{ 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;
    };

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

    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);
  };
}