{
  lib,
  config,
  pkgs,
  ...
}: let
  inherit (lib) types mkOption mkEnableOption mkIf;
  cfg = config.horseman.containers.forgejo;
  username = config.horseman.username;

  BACKUP_DIR = config.horseman.containers.backupDir;
  DATA_DIR = "/home/${username}/backups/volumes/forgejo";
in {
  options = {
    horseman.containers.forgejo = {
      enable = mkEnableOption "forgejo containers";

      port = mkOption {
        default = 3000;
        type = types.int;
      };

      sshPort = mkOption {
        default = 16718;
        type = types.int;
      };

      url = mkOption {
        default = "https://git.koendev.nl";
        type = types.str;
      };
    };
  };

  config = mkIf cfg.enable {
    systemd.timers."backup-forgejo" = {
      wantedBy = ["timers.target"];
      timerConfig = {
        OnCalendar = "daily";
        Persistent = true;
      };
    };

    environment.systemPackages = [pkgs.gnutar];
    systemd.services."backup-forgejo" = {
      script = ''
        cd ${BACKUP_DIR}
        ${pkgs.gnutar}/bin/tar -cf forgejo-$(date +'%Y-%m-%d').tar ${DATA_DIR}
      '';
      serviceConfig = {
        User = "root";
      };
    };

    containers.forgejoRunner = {
      autoStart = true;
      privateNetwork = true;
      hostAddress = "192.168.100.2";
      localAddress = "192.168.100.102";

      bindMounts = {
        "/var/lib/secrets" = {
          hostPath = "/run/forgejo-secrets";
          isReadOnly = true;
        };
      };

      config = {
        config,
        pkgs,
        ...
      }: let
        configFile = pkgs.writeText "runner.yml" ''
          runner:
            labels:
              - "nixos:host"
        '';
      in {
        environment.systemPackages = with pkgs; [
          forgejo-runner
          nodejs_24 # Needed for actions/checkout@v4 action
        ];

        users.groups.runner = {};
        users.users.runner = {
          isNormalUser = true;
          group = "runner";
        };

        systemd.services.startup = {
          script = ''
            cd ${config.users.users.runner.home}
            ${pkgs.forgejo-runner}/bin/forgejo-runner create-runner-file --instance ${cfg.url} --secret $(cat /var/lib/secrets/secret) --name runner
            sleep 10
            ${pkgs.forgejo-runner}/bin/forgejo-runner daemon --config ${configFile}
          '';
          serviceConfig = {
            User = "runner";
            Environment = "PATH=$PATH:/run/current-system/sw/bin";
          };
          wantedBy = ["multi-user.target"];
        };

        system.stateVersion = "23.11";
      };
    };

    containers.forgejo = {
      autoStart = true;
      privateNetwork = true;
      hostAddress = "192.168.100.3";
      localAddress = "192.168.100.103";

      bindMounts = {
        "/var/lib/forgejo" = {
          hostPath = DATA_DIR;
          isReadOnly = false;
        };

        "/var/lib/secrets" = {
          hostPath = "/run/forgejo-secrets";
          isReadOnly = true;
        };
      };

      config = {
        config,
        pkgs,
        ...
      }: {
        environment.systemPackages = [pkgs.forgejo];

        services.openssh = {
          enable = true;
          ports = [cfg.sshPort];
          settings = {
            PermitRootLogin = "no";
            PasswordAuthentication = false;
            KbdInteractiveAuthentication = false;
            # AllowUsers = ["git"];
          };
        };

        services.forgejo = {
          enable = true;

          stateDir = "/var/lib/forgejo";

          settings = {
            server = {
              HTTP_PORT = cfg.port;
              SSH_PORT = cfg.sshPort;
              ROOT_URL = cfg.url;
            };
            session = {
              COOKIE_SECURE = true;
            };
            service = {
              DISABLE_REGISTRATION = true;
            };

            # Prevent users from creating repositories and orginizations
            repository = {
              MAX_CREATION_LIMIT = 0;
              DISABLE_MIGRATION = true;
            };
            admin = {
              DISABLE_REGULAR_ORG_CREATION = true;
            };
          };
        };

        systemd.services.startup = {
          script = ''
            cd ${config.users.users.forgejo.home}
            ${pkgs.forgejo}/bin/forgejo forgejo-cli actions register --name runner --secret $(cat /var/lib/secrets/secret) --config ${config.services.forgejo.stateDir}/custom/conf/app.ini
          '';
          serviceConfig.User = "forgejo";
          wantedBy = ["multi-user.target"];
        };

        networking = {
          firewall = {
            enable = true;
            allowedTCPPorts = [cfg.port cfg.sshPort];
          };
          # Use systemd-resolved inside the container
          # Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686
          useHostResolvConf = lib.mkForce false;
        };

        system.stateVersion = "23.11";
      };
    };
  };
}
