{
  config,
  lib,
  ...
}: let
  cfg = config.hive.gitea-instance;
in {
  options.hive.gitea-instance = {
    enable = lib.mkEnableOption "Enable the Gitea instance";

    instanceFQDN = lib.mkOption {
      type = lib.types.singleLineStr;
      example = "git.example.com";
      description = "Fully qualified domain name of the Gitea instance";
    };

    databasePasswordFile = lib.mkOption {
      type = lib.types.path;
      example = "/etc/gitea-db-pass.txt";
      description = "Path to the file containing the Gitea database password";
    };
  };

  config = lib.mkIf cfg.enable {
    # Gitea instance
    services.gitea = {
      enable = true;
      lfs.enable = true;
      appName = "Git yourself some Tea!";
      database = {
        name = "gitea";
        type = "postgres";
        passwordFile = cfg.databasePasswordFile;
      };
      settings = {
        server.PROTOCOL = "http+unix";
        server.ROOT_URL = "https://${cfg.instanceFQDN}/";
        server.DOMAIN = cfg.instanceFQDN;
        service.DISABLE_REGISTRATION = true;
      };
    };

    # Fallback server with only 403
    services.nginx.virtualHosts.${config.networking.domain} = lib.mkDefault {
      default = true;
      locations."/".return = 403;
      forceSSL = true;
      enableACME = true;
    };

    # Virtual host for gitea
    services.nginx.virtualHosts."${cfg.instanceFQDN}" = {
      forceSSL = true;
      enableACME = true;
      locations."/" = {
        proxyPass = "http://unix:/run/gitea/gitea.sock";
      };
    };

    # Database setup
    services.postgresql = {
      enable = true;
      ensureDatabases = [config.services.gitea.user];
      ensureUsers = [
        {
          name = config.services.gitea.database.user;
          ensureDBOwnership = true;
        }
      ];
    };
  };
}
