{
  lib,
  pkgs,
  config,
  namespace,
  ...
}:
with lib;
let
  inherit (lib.${namespace}) mkOpt mkBoolOpt;
  cfg = config.${namespace}.hardware.amd;
in
{
  options.${namespace}.hardware.amd = {
    enable = mkEnableOption "amd hardware config";

    corectrl.enable = mkBoolOpt false "Enable Corectl";

    corectrl.enablePolkit = mkBoolOpt false "Enable Corectl Polkit";

    corectrl.polkitGroup = mkOpt types.str "wheel" "Corectl Polkit Group";

    lact.enable = mkBoolOpt false "Enable Lact daemon";
  };

  config = lib.mkIf cfg.enable {
    boot = {
      kernelModules = [
        "nct6775"
        "k10temp"
      ];
      kernelParams = [ (if cfg.enable then "amdgpu.ppfeaturemask=0xffffffff" else null) ];
    };

    # Configure programs
    programs.corectrl = {
      enable = cfg.corectrl.enable;
      package = pkgs.corectrl;
    };

    # Configure environment
    environment = {
      # Force radv
      variables = {
        AMD_VULKAN_ICD = "RADV";
        STEAM_FORCE_DESKTOPUI_SCALING = "1.0";
        GDK_SCALE = "1";
      };
    };

    # Configure polkit
    security.polkit = lib.mkIf cfg.corectrl.enablePolkit {
      extraConfig = ''
        polkit.addRule(function(action, subject) {
          if ((action.id == "org.corectrl.helper.init" ||
              action.id == "org.corectrl.helperkiller.init") &&
              subject.local == true &&
              subject.active == true &&
              subject.isInGroup("${cfg.corectrl.polkitGroup}")) {
                  return polkit.Result.YES;
          }
        });
      '';
    };

    # nixpkg is broken so need to manually define
    systemd.services = {
      load-k10temp = {
        description = "Load k10temp manually cause it wont otherwise";
        script = ''
          ${pkgs.kmod}/bin/modprobe k10temp
        '';
        wantedBy = [ "multi-user.target" ];
      };
      lactd = lib.mkIf cfg.lact.enable {
        description = "AMDGPU Control Daemon";
        path = with pkgs; [
          bash
          lact
        ];
        script = ''
          lact daemon
        '';
        wantedBy = [ "multi-user.target" ];
        after = [ "multi-user.target" ];
      };
    };

    # Configure environment
    environment = {
      systemPackages = with pkgs; lib.mkIf cfg.lact.enable [ lact ];
    };
  };
}
