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

let
  inherit (lib)
    mkIf
    mkEnableOption
    mkOption
    ;

  cfg = config.commonSettings.proxyServer;

  singTls = {
    enabled = true;
    server_name = config.deployment.targetHost;
    key_path = config.security.acme.certs.${config.deployment.targetHost}.directory + "/key.pem";
    certificate_path =
      config.security.acme.certs.${config.deployment.targetHost}.directory + "/cert.pem";
  };

  mkSingConfig = users: {
    log = {
      level = "warn";
    };
    inbounds =
      [
        {
          tag = "sg0";
          type = "trojan";
          listen = "::";
          listen_port = cfg.trojan.port;
          tcp_multi_path = true;
          tcp_fast_open = true;
          users = map (user: {
            name = user.name;
            password = {
              _secret = user.passwordFile;
            };
          }) users;
          tls = singTls;
        }
      ]
      ++ lib.forEach (lib.range 6311 6314) (port: {
        tag = "sg" + toString (port - 6310);
        type = "tuic";
        listen = "::";
        listen_port = port;
        congestion_control = "bbr";
        users = map (user: {
          name = user.name;
          uuid = {
            _secret = user.uuidFile;
          };
          password = {
            _secret = user.passwordFile;
          };
        }) users;
        tls = singTls;
      });
    outbounds =
      # warp outbound goes first to make it default outbound
      (lib.optionals (cfg.warp.onTuic or cfg.warp.onTrojan) [
        {
          type = "wireguard";
          tag = "wg-out";
          private_key = {
            _secret = config.sops.secrets.wg_private_key.path;
          };
          local_address = [
            "172.16.0.2/32"
            { _secret = config.sops.secrets.wg_ipv6_local_addr.path; }
          ];
          peers = [
            {
              public_key = "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=";
              allowed_ips = [
                "0.0.0.0/0"
                "::/0"
              ];
              server = "162.159.192.1";
              server_port = 500;
            }
          ];
        }
      ])
      ++ [

        {
          type = "direct";
          tag = "direct";
        }
      ];
    route = {
      rules =
        [
          {
            inbound = "sg4";
            outbound = "direct";
          }
        ]
        ++ (lib.optionals (!cfg.warp.onTuic) (
          lib.forEach (lib.range 1 3) (i: {
            inbound = "sg${toString i}";
            outbound = "direct";
          })
        ))
        ++ (lib.optionals (!cfg.warp.onTrojan) [
          {
            inbound = "sg0";
            outbound = "direct";
          }
        ]);
    };
    experimental = {
      v2ray_api = {
        listen = "127.0.0.1:15175";
        stats = {
          users = map (u: u.name) users;
          enabled = true;
          inbounds = map (p: "sg" + toString p) (lib.range 0 4);
        };
      };
    };
  };
  sing-box = pkgs.sing-box.overrideAttrs (
    finalAttrs: previousAttrs: {
      tags = previousAttrs.tags ++ [
        "with_v2ray_api"
      ];
    }
  );
in
{
  options.commonSettings.proxyServer = {
    enable = mkEnableOption "sing-box as a server";

    trojan = {
      port = mkOption {
        type = lib.types.port;
        default = 8080;
      };
    };

    warp = {
      onTrojan = mkEnableOption "forward to warp in trojan";
      onTuic = mkEnableOption "forward to warp in first two port of tuic";
    };

    users = mkOption {
      type = lib.types.listOf lib.types.str;
    };
  };

  config = mkIf cfg.enable (
    {
      boot.kernel.sysctl = {
        "net.core.default_qdisc" = "fq";
        "net.ipv4.tcp_congestion_control" = "bbr";
      };

      networking.firewall.trustedInterfaces = [ "tun0" ];

      security.acme = {
        acceptTerms = true;
        certs.${config.deployment.targetHost} = {
          email = "me@namely.icu";
          # Avoid port conflict
          listenHTTP = if config.services.caddy.enable then ":30310" else ":80";
        };
      };
      services.caddy.virtualHosts."http://${config.deployment.targetHost}:80".extraConfig = ''
        reverse_proxy 127.0.0.1:30310
      '';

      networking.firewall.allowedTCPPorts = [
        80
        cfg.trojan.port
      ];
      networking.firewall.allowedUDPPorts = [ ] ++ (lib.range 6311 6314);

      services.sing-box = {
        enable = true;
        package = sing-box;
        settings = (
          mkSingConfig (
            map (n: {
              name = n;
              uuidFile = config.sops.secrets."sing-box/users/${n}/uuid".path;
              passwordFile = config.sops.secrets."sing-box/users/${n}/password".path;
            }) cfg.users
          )
        );
      };
    }
    // {
      sops.secrets = (
        builtins.foldl' (a: b: a // b) { } (
          map (u: {
            "sing-box/users/${u}/uuid" = { };
            "sing-box/users/${u}/password" = { };
          }) cfg.users
        )
      );
    }
  );
}
