{
  description = "Michael Thomas's NixOS configuration";

  inputs = {
    nixpkgs.url = "nixpkgs/nixos-23.11";
    unstable.url = "nixpkgs/nixos-unstable";
    nur.url = "github:nix-community/NUR";

    utils.url = "github:numtide/flake-utils";
    rust-overlay.url = "github:oxalica/rust-overlay";
    nix-vscode-extensions.url = "github:nix-community/nix-vscode-extensions";

    agenix = {
      url = "github:ryantm/agenix";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    nixos-wsl = {
      url = "github:nix-community/NixOS-WSL";
      inputs = {
        nixpkgs.follows = "nixpkgs";
      };
    };
    vscode-server = {
      url = "github:nix-community/nixos-vscode-server";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    darwin = {
      url = "github:lnl7/nix-darwin/master";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    home-manager = {
      url = "github:rycee/home-manager/release-23.11";
      inputs = {
        nixpkgs.follows = "nixpkgs";
      };
    };
  };

  outputs = {
    self,
    nixpkgs,
    unstable,
    nur,
    agenix,
    utils,
    rust-overlay,
    nix-vscode-extensions,
    nixos-wsl,
    vscode-server,
    darwin,
    home-manager,
    ...
  } @ inputs: let
    forAllSystems = nixpkgs.lib.genAttrs utils.lib.defaultSystems;

    defaultModules = [
      self.overlaysModule
      home-manager.nixosModules.home-manager
      ./modules
    ];
  in {
    # Your custom packages
    # Accessible through 'nix build', 'nix shell', etc
    packages = forAllSystems (system: import ./pkgs nixpkgs.legacyPackages.${system});

    overlays = import ./overlays {inherit inputs;};

    overlaysModule = {
      nixpkgs.overlays = builtins.attrValues self.overlays;
    };

    nixosConfigurations = {
      loft = nixpkgs.lib.nixosSystem {
        system = utils.lib.system.x86_64-linux;
        modules =
          defaultModules
          ++ [
            ./modules/common.nix
            ./modules/containers.nix

            ./machines/loft/configuration.nix
          ];
        specialArgs = {inherit inputs;};
      };

      kitchen = nixpkgs.lib.nixosSystem {
        system = utils.lib.system.x86_64-linux;
        modules =
          defaultModules
          ++ [
            ./modules/common.nix
            ./modules/containers.nix
            {
              home-manager.useGlobalPkgs = true;
              home-manager.useUserPackages = true;
              home-manager.users.michael = import ./user/environments/nixos/home.nix;
            }

            ./machines/kitchen/configuration.nix
          ];
        specialArgs = {inherit inputs;};
      };

      thinkcentre = nixpkgs.lib.nixosSystem {
        system = utils.lib.system.x86_64-linux;
        modules =
          defaultModules
          ++ [
            ./modules/common.nix
            ./modules/hyprland.nix
            ./modules/containers.nix
            {
              home-manager.useGlobalPkgs = true;
              home-manager.useUserPackages = true;
              home-manager.users.michael = import ./user/environments/nixos/home.nix;
            }

            ./machines/thinkcentre/configuration.nix
            agenix.nixosModules.default
            {
              environment.systemPackages = [
                agenix.packages.x86_64-linux.default
              ];
            }
          ];
        specialArgs = {inherit inputs;};
      };

      oracle = nixpkgs.lib.nixosSystem {
        system = utils.lib.system.x86_64-linux;
        modules =
          defaultModules
          ++ [
            ./modules/nix.nix
            {
              home-manager.useGlobalPkgs = true;
              home-manager.useUserPackages = true;
              home-manager.users.michael = import ./user/environments/nixos-server/home.nix;
            }
            agenix.nixosModules.default
            {
              environment.systemPackages = [
                agenix.packages.x86_64-linux.default
              ];
            }

            ./machines/oracle/configuration.nix
          ];
        specialArgs = {inherit inputs;};
      };

      # WSL environment
      work = inputs.nixpkgs.lib.nixosSystem {
        system = utils.lib.system.x86_64-linux;
        modules =
          defaultModules
          ++ [
            vscode-server.nixosModules.default
            ./modules/containers.nix
            ./modules/nix.nix

            ./machines/work/configuration.nix
          ];
        specialArgs = {inherit inputs;};
      };
    };

    darwinConfigurations = {
      mac = darwin.lib.darwinSystem {
        system = "aarch64-darwin";
        specialArgs = {inherit inputs;};
        modules =
          defaultModules
          ++ [
            {
              home-manager.useGlobalPkgs = true;
              home-manager.useUserPackages = true;
              home-manager.users.michael = import ./user/environments/mac/home.nix;
            }

            ./modules/yabai.nix
            ./machines/mac/configuration.nix
          ];
      };
    };

    homeConfigurations = {
      nixos = inputs.home-manager.lib.homeManagerConfiguration {
        system = "x86_64-linux";
        homeDirectory = "/home/michael";
        username = "michael";
        stateVersion = "21.05";
        configuration = {
          config,
          pkgs,
          ...
        }: {
          programs.home-manager.enable = true;

          imports = [
            ./user/environments/nixos/home.nix
          ];
        };
      };

      wsl = inputs.home-manager.lib.homeManagerConfiguration {
        system = "x86_64-linux";
        homeDirectory = "/home/michael";
        username = "michael";
        stateVersion = "21.05";
        configuration = {
          config,
          pkgs,
          ...
        }: {
          programs.home-manager.enable = true;

          imports = [
            ./user/environments/wsl/home.nix
          ];
        };
      };

      mac = inputs.home-manager.lib.homeManagerConfiguration {
        system = "aarch64-darwin";
        homeDirectory = "/Users/michael";
        username = "michael";
        stateVersion = "22.05";
        configuration = {
          config,
          pkgs,
          ...
        }: {
          programs.home-manager.enable = true;

          imports = [
            ./user/environments/mac/home.nix
          ];
        };
      };
    };
  };
  # // utils.lib.eachSystem [ "aarch64-linux" "x86_64-darwin" "x86_64-linux" ] (system: {
  # 	nixpkgs = import nixpkgs {
  # 		inherit system;
  # 		overlays = [
  # 			self.overlays.default
  # 		];
  # 		config.allowUnfree = true;
  # 	};
  # });
}