{ flake, self, inputs }: 
{ pkgs, modulesPath, lib, config, ... }: let
    # Build marzban package directly to avoid circular dependency
    system = pkgs.system;
    #vmIp      = "5.180.46.39";
    vmIp      = "147.45.116.17";
    vmGateway = "147.45.116.1";
    #vmIp         = "5.180.46.57";
    #vmGateway    = "5.180.46.1";
    legacyDomain = "vproxy.store";
  in {
    imports = [
      (modulesPath + "/profiles/qemu-guest.nix")
      #(modulesPath + "/installer/cd-dvd/iso-image.nix")
      inputs.util.nixosModules.hectic
      inputs.util.nixosModules.postgresql
      inputs.sops-nix.nixosModules.sops
      self.nixosModules.dreamproxy-bot
      self.nixosModules.vproxy-bot
      self.nixosModules.vproxy-rest
      self.nixosModules.marzban
      self.nixosModules.photoedit-bot
      self.nixosModules.legacy-web
      self.nixosModules.vproxy-web
      inputs.disko.nixosModules.disko
    ];

    boot.loader.systemd-boot.enable = false;
    boot.loader.efi.canTouchEfiVariables = false;
    
    boot.loader.grub = {
      enable = true;
      device = "/dev/vda";
      efiSupport = false;
      forceInstall = true;
    };

    disko.devices.disk.vda = {
      device = "/dev/vda";
      type = "disk";
      content = {
        type = "gpt";
        partitions = {
          ESP = {
            size = "512M";
            type = "EF00";
            content = {
              type = "filesystem";
              format = "vfat";
              mountpoint = "/boot";
              mountOptions = [ "umask=0077" ];
            };
          };
          root = {
            size = "100%";
            content = {
              type = "filesystem";
              format = "ext4";
              mountpoint = "/";
            };
          };
        };
      };
    };


    networking.useDHCP = false;
    networking.interfaces.ens3 = {
      ipv4.addresses = [
        { address = vmIp; prefixLength = 24; }
      ];
    };
    networking.defaultGateway = vmGateway;
    networking.nameservers = [ "1.1.1.1" "8.8.8.8" ];

    hectic = {
      archetype.dev.enable = true;
      services.support-bot = {
        "vproxy" = {
          environmentPath = config.sops.secrets."vproxy.support-bot.env".path;
          redisPort       = 6379;
        };
        "vpn" = {
          environmentPath = config.sops.secrets."vpn.support-bot.env".path;
          redisPort       = 6380;
        };
        "domain" = {
          environmentPath = config.sops.secrets."domain.support-bot.env".path;
          redisPort       = 6381;
        };
      };
    };

    boot.initrd.availableKernelModules = [
      "ata_piix"
      "uhci_hcd"
      "xen_blkfront"
    ] ++ (if pkgs.system != "aarch64-linux" then [ "vmw_pvscsi" ] else []);

    sops = {
      gnupg.sshKeyPaths = [ ];
      age.sshKeyPaths   = [ "/etc/ssh/ssh_host_ed25519_key" ];
      defaultSopsFile   = ../../../sus/services.env.yaml;

      secrets."vproxy.support-bot.env"      = {};
      secrets."vpn.support-bot.env"         = {};
      secrets."domain.support-bot.env"      = {};
      secrets."dreamproxy-bot.env"          = {};
      secrets."vproxy-bot.env"              = {};
      secrets."photoedit-bot.env"           = {};
      secrets."vproxy-web.env"              = {};
    };

    #hectic.marzban = {
    #  enable = true;
    #  settings = xraySettings;
    #  marzbanPackage = marzban-package;
    #  environment = inputs.util.lib.readEnvironment {
    #    prefix = "";
    #    envVarsToRead = [
    #      "POSTGRES_USER"
    #      "POSTGRES_PASSWORD"
    #      "DB_NAME"
    #      "DB_HOST"
    #      "DB_PORT"
    #    ];
    #  };
    #};

    environment.sessionVariables.SYSTEMD_PAGER = "${pkgs.hectic.nvim-pager}/bin/pager";

    # TODO(yukkop): make vproxy.store be on owr server
    #services.mailserver = {
    #  enable = true;
    #  domain = domain;
    #  loginAccounts = {
    #    "security" = {
    #      hashedPassword = "";
    #    };
    #    "info" = {
    #      hashedPassword = "";
    #    };
    #  };
    #};

    banned.services = {
      dreamproxy-bot = {
        enable          = true;
	environmentPath = config.sops.secrets."dreamproxy-bot.env".path;
      };
      legacy-web = {
        enable = true;
        domain = legacyDomain;
      };
      vproxy-bot = {
        enable          = true;
        websiteDomain   = "vproxy.cc";
        redisPort       = 7021;
        redisGetProxyDb = 1;
        redisPurchaseDb = 2;
        redisMasterDb   = 3;
        environmentPath = config.sops.secrets."vproxy-bot.env".path;
      };
      vproxy-web = {
        enable = true;
        environmentPath = config.sops.secrets."vproxy-web.env".path;
      };
      photoedit-bot = {
        enable    = true;
        adminList = [380055934 6885853129 1046347923 1342847359 7048701446];
        environmentPath = config.sops.secrets."photoedit-bot.env".path;
      };
    };

    services = {
      vproxy-rest.enable = true;
    };

    programs.git = { enable = true; };

    environment.systemPackages = (with pkgs; [ 
      # for system instalation in case when neccesary
      parted

      # tools
      ncdu
      curl
      rsync
      sqlite
      neovim
      postgresql_15 
      lsof
      openssl # maybe necessary for pg_smtp_client for postgresql
      pkg-config
    ]) ++ [
        (self.lib.rustToolchain system)
    ];

    # Autologin root in the VM
    services.getty.autologinUser = "root";

    virtualisation.vmVariant = {
      #virtualisation.qemu.options = [
      #  "-nographic" 
      #  "-display" "curses"
      #  "-append" "console=ttyS0"
      #  "-serial" "mon:stdio"
      #  "-vga" "qxl"
      #];
      virtualisation.forwardPorts = [
        { from = "host"; host.port = 40500; guest.port = 22; }
        { from = "host"; host.port = 8000; guest.port = 8000; }
        { from = "host"; host.port = 8888; guest.port = 80; }
      ];
    };

    services.openssh.hostKeys = [
      { path = "/etc/ssh/ssh_host_ed25519_key"; type = "ed25519"; }
      { path = "/etc/ssh/ssh_host_rsa_key"; type = "rsa"; bits = 4096; }
    ];
    services.openssh.settings.PasswordAuthentication = lib.mkForce true;

    users.users.root.openssh.authorizedKeys.keys = [
      ''ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICW5YVDdm/sN/Die9kGdGOpiGHnJUX4Aq5yCXALyWAwk devbox-user@devbox-vproxy''
      ''ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC5PxmNeqqxSREUcJy0qZi49ZROaefa5pwwnwGoe1UY8j/2hGRUlysVfp4ToleVR0eJnWuZ88aM31pyyhvZWUJpZpHW25m3QSxXyhFj15/Kk844ckJfeuB+0Di0LeN0LJynzHdz9Y/fNBXskRuhSrJ5MuzwEspM+Mc42wy++bAWWb3fFw+6N2Mj59RU82Cun9FZmecAd2oqk3OoYhtX4zfgxGhwsq+murxuLfFzQeBpIP/IsbTenuQc6sitEae+Lq6vrPV/TVazdV6o4tE7isa3TJoSdTF39n+gZffSZrSqSyMwBtbOvN42gB344JliJ1//wgDJWSJ1Oy4wz7F2Am+UwOWvPuvm75hXl7V9jXMECVRhZ+ROa6Q6//z7kdt6lfIrlh6zlPenFnv5ji/yyramYSxfbEEEBqPEjekh/OUSDdyuJ69Ektr8+pAAsX0hPhnXkmX7y8cY0dkmFZVUKPV2YDlKjL6d+Gq3LwdElPyR3a9j28Dkon/Ahv77VnKkqy1GawqfDdIyhmOW5dpNvHIYr0XhrBth8zyPvqpDfehtKevLLTTtl86aZ9nJFKavjfuo+By6OrwQPpsz4jFqoBdK7MNUZKw+d58a7Z+TlJpJwB5hjWpOuiPM5FQ0XP4WsLnKbEMYkw1KqtJMRt4rsOmcRcEwk3Oud1qMpG4a6FTLDQ== qq@archlinux''
      ''ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMezFt0OjCXCEjuOch03oTGXxgON+O9YShrU0hC0dJfb''
      ''ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICrbBG+U07f7OKvOxYIGYCaNvyozzxQF+I9Fb5TYZErK''
      ''ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGUqLmQXXcgpdv89UkDmctj5XmCBKMByQsFrEqBCfB1O''
      ''ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBsYIQVwnVi/zoqHvuXNXb9qcGsv9q3rY7z7gHmLPfI4''
    ];

    networking.firewall = {
      enable = true;
      allowedTCPPorts = [
        # for server
        443    # default ssl
        80
        4000
        #465    # SMTP over SSL
        #587    # SMTP over TLS (optional)
        #25     # Default SMTP (optional)
        53     # DNS
      ];
    };
    programs.zsh.shellAliases = let
    # quick log for postgres service
    generatePgScript = n: ''
      journalctl -u postgresql --since "${n} hour ago" |
      ${pkgs.hectic.prettify-log}/bin/prettify-log --color-output |
      ${pkgs.hectic.nvim-pager}/bin/pager
    '';
    pgNh = builtins.listToAttrs (builtins.genList (i: let
        n = toString (i + 1);
    in {
        name = "pg${n}h";
        value = (generatePgScript n);
    }) 72);

           # quick log for bot service
    generateBtScript = n: ''
      journalctl -u vproxy-bot --since "${n} hour ago" |
      ${pkgs.hectic.prettify-log}/bin/prettify-log --color-output |
      ${pkgs.hectic.nvim-pager}/bin/pager
    '';
    btNh = builtins.listToAttrs (builtins.genList (i: let
        n = toString (i + 1);
    in {
      name = "bt${n}h";
      value = (generateBtScript n);
    }) 72);

     # quick log for nginx service
    generateNgScript = n: ''
      journalctl -u nginx --since "${n} hour ago" |
      ${pkgs.hectic.prettify-log}/bin/prettify-log --color-output |
      ${pkgs.hectic.nvim-pager}/bin/pager
    '';
    ngNh = builtins.listToAttrs (builtins.genList (i: let
      n = toString (i + 1);
    in {
      name = "ng${n}h";
      value = (generateNgScript n);
    }) 72);
  in { 
    hectic = /* bash */ ''
     echo "hectic project util help"
     echo "pg<N>h"
     echo "ng<N>h"
     echo "bt<N>h"
  '';

  } // pgNh // btNh // ngNh;

  system.stateVersion = lib.mkForce "24.05";
}
