{ nixpkgs, nix-darwin, self, ... }@inputs:

let
  makePkgs = system: (import nixpkgs {
    inherit system;

    config.allowUnfree = true;
    overlays = [
      self.overlays.default
      inputs.niri.overlays.niri
      # inputs.lix-module.overlays.default

      inputs.zdwl.overlays.default

      (final: prev: ({
        star-citizen = inputs.nix-gaming.packages.${prev.system}.star-citizen;
      }))

      (final: prev: {
        tmux = prev.tmux.overrideAttrs (old: rec {
          version = "3.5";
          src = prev.fetchFromGitHub {
            owner = "tmux";
            repo = "tmux";
            rev = version;
            hash = "sha256-8CRZj7UyBhuB5QO27Y+tHG62S/eGxPOHWrwvh1aBqq0=";
          };
        });
      })

      (final: prev: {
        lutris-unwrapped = prev.lutris-unwrapped.overrideAttrs (old: rec {
          version = "0.5.18";
          src = prev.fetchFromGitHub {
            owner = "lutris";
            repo = "lutris";
            rev = "v${version}";
            hash = "sha256-dI5hqWBWrOGYUEM9Mfm7bTh7BEc4e+T9gJeiZ3BiqmE=";
          };
        });
      })

      (final: prev: {
        uhk-agent = prev.uhk-agent.overrideAttrs (old: rec {
          pname = "uhk-agent";
          version = "5.0.2";

          src = prev.fetchurl {
            url = "https://github.com/UltimateHackingKeyboard/agent/releases/download/v${version}/UHK.Agent-${version}-linux-x86_64.AppImage";
            name = "${pname}-${version}.AppImage";
            sha256 = "sha256-A0ALw5noXeeCGvWEFJMyYeNb9mMHyr3DC3T0yK1MQoM=";
          };
        });
      })
    ];
  });

  lib = nixpkgs.lib.extend (import ./lib);

  inherit (inputs.home-manager.lib) homeManagerConfiguration;
  inherit (lib) nixosSystem;
  inherit (lib.strings) optionalString;
  inherit (lib.attrsets) nameValuePair;
in
rec {
  toPartialNixosConfig =
    { hostname, system ? "x86_64-linux" }:
    nameValuePair
      hostname
      (nixosSystem rec {
        pkgs = makePkgs system;
        specialArgs = { inherit inputs self; };

        modules = [
          ./hosts/${hostname}/hardware-configuration.nix
          ./hosts/${hostname}/configuration.nix
          inputs.home-manager.nixosModules.default
          inputs.chaotic.nixosModules.default
          inputs.niri.nixosModules.niri
          {
            home-manager.extraSpecialArgs = {
              inherit inputs self pkgs;
              lib = pkgs.lib.extend (_: _: inputs.home-manager.lib);
            };
          }
        ];
      });

  toPartialHomeManagerConfig =
    { user, system ? "x86_64-linux", hostname ? "", configHostname ? "" }:
    let
      configHost = if builtins.stringLength configHostname > 0 then configHostname else hostname;
      hostStr = optionalString (builtins.stringLength hostname > 0) "@${hostname}";
    in
    assert lib.assertMsg (builtins.stringLength configHost > 0) "either configHostname or hostname need to exist";
    nameValuePair
      "${user}${hostStr}"
      (homeManagerConfiguration {
        pkgs = makePkgs system;
        extraSpecialArgs = { inherit inputs self; };

        modules = [
          inputs.chaotic.homeManagerModules.default
          ./hosts/${configHost}/home.nix
        ];
      });

  toPartialDarwinConfig =
    { hostname, system ? "aarch64-darwin", }:
    nameValuePair
      hostname
      (nix-darwin.lib.darwinSystem rec {
        pkgs = makePkgs system;
        specialArgs = { inherit inputs self; };

        modules = [
          inputs.home-manager.darwinModules.home-manager
          ./hosts/${hostname}/configuration.nix
          {
            home-manager.extraSpecialArgs = {
              inherit inputs self pkgs;
              lib = pkgs.lib.extend (_: _: inputs.home-manager.lib);
            };
          }
        ];
      });

  compileSystems =
    toPartialConfiguration:
    systems:
    lib.right
      builtins.listToAttrs
      (map toPartialConfiguration)
      systems;
  compileNixosSystems = compileSystems toPartialNixosConfig;
  compileDarwinSystems = compileSystems toPartialDarwinConfig;
  compileHomes = compileSystems toPartialHomeManagerConfig;
}