{ config, lib, pkgs, ... }:
let
  cfg = config.services.pvv-nettsiden;
  inherit (lib) mkDefault mkEnableOption mkPackageOption mkIf mkOption types mdDoc;
  format = pkgs.formats.php { };
in
{
  options.services.pvv-nettsiden = {
    enable = mkEnableOption (lib.mdDoc "Enable pvv-nettsiden");

    package = mkPackageOption pkgs "pvv-nettsiden" { };

    user = mkOption {
      type = types.str;
      default = "pvv-nettsiden";
      description = mdDoc "User to run php-fpm and own the image directories";
    };

    group = mkOption {
      type = types.str;
      default = "pvv-nettsiden";
      description = mdDoc "Group to run php-fpm and own the image directories";
    };

    domainName = mkOption {
      type = types.str;
      default = "www.pvv.no";
      description = mdDoc "Domain name for the website";
    };

    enableNginx = mkEnableOption "nginx" // { default = true; };
    useSSL = mkEnableOption "secure cookies" // { default = true; };

    settings = mkOption {
      description = "Settings for the website";
      default = { };
      type = types.submodule {
        freeformType = format.type;
        options = lib.mapAttrsRecursiveCond
          (attrs: !(attrs ? "type"))
          (_: option: option // { type = types.either option.type format.lib.types.raw; })
        {
          GALLERY = {
            DIR = mkOption {
              type = types.path;
              default = "/var/lib/pvv-nettsiden/gallery";
              description = mdDoc "Directory where the gallery is located. See documentation at TODO";
            };

            SERVER_PATH = mkOption {
              type = types.str;
              default = "/static/gallery";
              description = mdDoc "Path to the gallery on the server";
            };
          };

          SLIDESHOW = {
            DIR = mkOption {
              type = types.path;
              default = "/var/lib/pvv-nettsiden/slideshow";
              description = mdDoc "Directory where the slideshow is located. See documentation at TODO";
            };

            SERVER_PATH = mkOption {
              type = types.str;
              default = "/static/slideshow";
              description = mdDoc "Path to the slideshow on the server";
            };
          };

          DB = {
            DSN = mkOption {
              type = types.str;
              default = "sqlite:/var/lib/pvv-nettsiden/pvv-nettsiden.db";
              example = "pgsql:host=localhost;port=5432;dbname=testdb;user=bruce;password=mypass";
              description = mdDoc "Database connection string, see https://www.php.net/manual/en/pdo.construct.php";
            };

            USER = mkOption {
              type = with types; nullOr str;
              default = null;
              example = "pvv-nettsiden";
              description = mdDoc "Database user";
            };

            PASS = mkOption {
              type = with types; nullOr str;
              default = null;
              description = mdDoc "Database password. Recommends: null, set in extraConfig";
            };
          };
        };
      };
    };
  };


  config = mkIf cfg.enable {
    users.users = mkIf (cfg.user == "pvv-nettsiden") {
      "pvv-nettsiden" = {
        description = "PVV Website Service User";
        group = cfg.group;
        createHome = false;
        isSystemUser = true;
      };
    };

    users.groups = mkIf (cfg.group == "pvv-nettsiden") {
      "pvv-nettsiden" = { };
    };

    services.nginx = mkIf cfg.enableNginx {
      enable = true;

      recommendedGzipSettings = mkDefault true;
      recommendedProxySettings = mkDefault true;

      virtualHosts."${cfg.domainName}" = {
        forceSSL = mkDefault cfg.useSSL;
        enableACME = mkDefault true;
        locations = {
          "/" = {
            root = "${cfg.package}/share/php/pvv-nettsiden/www/";
            index = "index.php";
          };

          "~ \\.php$".extraConfig = ''
            include ${pkgs.nginx}/conf/fastcgi_params;
            fastcgi_param SCRIPT_FILENAME ${cfg.package}/share/php/pvv-nettsiden/www$fastcgi_script_name;
            fastcgi_pass unix:${config.services.phpfpm.pools."pvv-nettsiden".socket};
          '';

          ${cfg.settings.GALLERY.SERVER_PATH} = {
            root = cfg.settings.GALLERY.DIR;
          };

          ${cfg.settings.SLIDESHOW.SERVER_PATH} = {
            root = cfg.settings.SLIDESHOW.DIR;
          };
        };
      };

    };

    services.phpfpm.pools.pvv-nettsiden = {
      user = cfg.user;
      group = cfg.group;

      phpEnv.PVV_CONFIG_FILE = toString (format.generate "pvv-nettsiden-conf.php" cfg.settings);

      settings = {
        "listen.owner" = config.services.nginx.user;
        "listen.group" = config.services.nginx.group;
        "pm" = mkDefault "ondemand";
        "pm.max_children" = mkDefault 32;
        "pm.process_idle_timeout" = mkDefault "10s";
        "pm.max_requests" = mkDefault 500;
      };
    };
  };
}