{
  config,
  lib,
  pkgs,
  ...
}:

let
  inherit (lib) mkEnableOption mkIf mkOption;
  inherit (lib.types) anything attrsOf port;

  inherit (config.security.acme) certs;

  cfg = config.services.wp-containers;

  mkName = builtins.replaceStrings [ "." ] [ "-" ];
  mkIp = ip: i: "${ip}.${builtins.toString i}";
  mkHost = mkIp "10.31.41";
  mkLocal = mkIp "10.0.0";

  mkConfig =
    {
      name,
      value,
      i,
    }:
    {
      services = {
        wordpress = {
          webserver = "nginx";
          sites.${name} = value;
        };

        nginx.virtualHosts.${name} = {
          onlySSL = true;
          sslCertificate = "${certs.${name}.directory}/fullchain.pem";
          sslCertificateKey = "${certs.${name}.directory}/key.pem";
          sslTrustedCertificate = "${certs.${name}.directory}/chain.pem";
        };

        # Increase the max post size
        phpfpm.pools."wordpress-${name}".phpOptions = ''
          post_max_size = 64M;
          upload_max_filesize = 64M;
          memory_limit = 128M;
        '';
      };

      networking = {
        hostName = mkName name;
        hosts.${mkLocal i} = [ name ];

        firewall.allowedTCPPorts = [ 443 ];
      };

      environment.systemPackages = [
        pkgs.wp-cli
        pkgs.neovim
      ];

      system.stateVersion = "23.11";
    };

  mkContainer = i: site: {
    name = mkName site.name;

    value = {
      privateNetwork = true;

      forwardPorts = [
        {
          containerPort = 443;
          hostPort = cfg.basePort + i;
        }
      ];

      bindMounts.certs = {
        hostPath = certs.${site.name}.directory;
        mountPoint = certs.${site.name}.directory;
      };

      hostAddress = mkHost i;
      localAddress = mkLocal i;

      autoStart = true;

      config = mkConfig (site // { inherit i; });
    };
  };

  mkVhost = i: site: {
    inherit (site) name;
    value = {
      enableACME = true;
      forceSSL = true;

      locations."/".proxyPass = "https://${mkHost i}:${builtins.toString (cfg.basePort + i)}";
    };
  };

  siteList = lib.attrsToList cfg.sites;
in
{
  options.services.wp-containers = {
    enable = mkEnableOption "wordpress sites in containers";

    basePort = mkOption {
      type = port;
      default = 9090;
    };

    sites = mkOption {
      type = attrsOf anything;
      default = { };
    };
  };

  config = mkIf cfg.enable {
    containers = builtins.listToAttrs (lib.imap1 mkContainer siteList);

    services.nginx.virtualHosts = builtins.listToAttrs (lib.imap1 mkVhost siteList);
  };
}