# See https://github.com/sunmeplz/xray-3x-ui

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

with lib;

let
  cfg = config.machine.xray-3x-ui;

  # Minimum Go version required for building
  minGoVersion = "1.26.0";

  xray-3x-ui =
    assert assertMsg (versionAtLeast pkgs.go.version minGoVersion)
      "3x-ui requires Go >= ${minGoVersion}, but ${pkgs.go.version} is available";

    pkgs.buildGoModule rec {
      pname = "3x-ui";
      version = "2.8.11";

      src = pkgs.fetchFromGitHub {
        owner = "MHSanaei";
        repo = "3x-ui";
        rev = "v${version}";
        hash = "sha256-2I6t3caf2t7nKSFwxI/dVIobpBzuptrgauuXfFw8ltg=";
      };

      vendorHash = "sha256-M8YQTMfF/xZut4hxUcAfF2xGK625vwJNp4JS/zoXUCQ=";

      ldflags = [
        "-s"
        "-w"
      ];

      meta = with lib; {
        description = "Xray panel supporting multi-protocol multi-user";
        homepage = "https://github.com/MHSanaei/3x-ui";
        license = licenses.gpl3Only;
        platforms = platforms.linux;
        maintainers = [ ];
      };
    };

in
{
  # Service implementation
  config = mkIf cfg.enable {
    # User and group configuration
    users.users.xray-3x-ui = {
      isSystemUser = true;
      group = "xray-3x-ui";
      description = "3x-ui service user";
    };

    users.groups.xray-3x-ui = { };

    # Directory structure
    systemd.tmpfiles.rules = [
      "d ${cfg.dataDir} 0755 xray-3x-ui xray-3x-ui -"
      "d ${cfg.dataDir}/bin 0755 xray-3x-ui xray-3x-ui -"
      "d ${cfg.dataDir}/logs 0755 xray-3x-ui xray-3x-ui -"
    ];

    # Systemd service
    systemd.services.xray-3x-ui = {
      description = "3x-ui Xray Panel";
      after = [ "network.target" ];
      wantedBy = [ "multi-user.target" ];

      environment = {
        XUI_DB_FOLDER = cfg.dataDir;
        XUI_BIN_FOLDER = "${cfg.dataDir}/bin";
        XUI_LOG_FOLDER = "${cfg.dataDir}/logs";
      };

      preStart = ''
        # Symlink xray-core binary to expected location
        ln -sf ${pkgs.xray}/bin/xray ${cfg.dataDir}/bin/xray-linux-amd64
      '';

      serviceConfig = {
        Type = "simple";
        ExecStart = "${xray-3x-ui}/bin/3x-ui";
        WorkingDirectory = cfg.dataDir;
        Restart = "on-failure";
        RestartSec = "10s";
        User = "xray-3x-ui";
        Group = "xray-3x-ui";
        StateDirectory = "3x-ui 3x-ui/bin 3x-ui/logs";
        StateDirectoryMode = "0755";
        AmbientCapabilities = [
          "CAP_NET_BIND_SERVICE"
          "CAP_NET_ADMIN"
        ];
        CapabilityBoundingSet = [
          "CAP_NET_BIND_SERVICE"
          "CAP_NET_ADMIN"
        ];
      };
    };

    # Add to system packages for CLI access
    environment.systemPackages = [ xray-3x-ui ];
  };
}
