{
  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";

    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,
    utils,
    rust-overlay,
    nix-vscode-extensions,
    nixos-wsl,
    vscode-server,
    darwin,
    home-manager,
    ...
  } @ inputs: {
    # This repo's overlay plus any other overlays you use
    # If you want to use packages from flakes that are not nixpkgs (such as NUR), add their overlays here.\
    overlays = {
      default = import ./overlays inputs;
      pkg-sets = (
        final: prev: {
          unstable = import inputs.unstable {system = final.system;};
          trunk = import inputs.trunk {system = final.system;};
        }
      );
      rust-overlay = rust-overlay.overlays.default;
      vscode-extensions = nix-vscode-extensions.overlays.default;
    };

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

    nixosConfigurations = {
      loft = nixpkgs.lib.nixosSystem {
        system = utils.lib.system.x86_64-linux;
        modules = [
          self.overlaysModule
          home-manager.nixosModules.home-manager
          ./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 = [
          self.overlaysModule
          home-manager.nixosModules.home-manager
          ./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 = [
          self.overlaysModule
          home-manager.nixosModules.home-manager
          ./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
        ];
        specialArgs = {inherit inputs;};
      };

      oracle = nixpkgs.lib.nixosSystem {
        system = utils.lib.system.x86_64-linux;
        modules = [
          home-manager.nixosModules.home-manager
          ./modules/nix.nix
          {
            home-manager.useGlobalPkgs = true;
            home-manager.useUserPackages = true;
            home-manager.users.michael = import ./user/environments/nixos-server/home.nix;
          }

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

      # WSL environment
      work = inputs.nixpkgs.lib.nixosSystem {
        system = utils.lib.system.x86_64-linux;
        modules = [
          self.overlaysModule
          home-manager.nixosModules.home-manager
          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 = [
          self.overlaysModule
          home-manager.darwinModules.home-manager
          {
            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;
  # 	};
  # });
}