{ config, lib, ... }:
with lib;
let
  cfg = config.mjallen.theme;

  mkPalettePath = name: lib.snowfall.fs.get-file "modules/home/desktop/theme/palettes/${name}.nix";

  cap =
    s:
    let
      len = builtins.stringLength s;
    in
    (lib.toUpper (builtins.substring 0 1 s)) + (builtins.substring 1 (len - 1) s);
in
{
  options.mjallen.theme = {
    name = mkOption {
      type = types.enum [
        "nord"
        "dracula"
        "everforest"
      ];
      default = "nord";
      description = "Global theme palette name.";
    };

    # This is the palette file other modules should import.
    # It exports a normalized schema with colors, tokens, and compat maps.
    paletteFile = mkOption {
      type = types.path;
      default = mkPalettePath "nord";
      description = "Path to a palette nix file exporting a normalized schema (and compat maps).";
    };

    # Exposed tokens (derived from paletteFile)
    tokens = mkOption {
      type = types.attrs;
      default = { };
      description = "Derived tokens from the selected palette (set automatically).";
    };

    # Expose the imported palette (actual colors + compat groups)
    palette = mkOption {
      type = types.attrs;
      default = { };
      description = "Imported palette attrset from the selected paletteFile (set automatically).";
    };

    gtk = {
      enable = mkOption {
        type = types.bool;
        default = true;
        description = "Manage GTK theme using global theme settings.";
      };

      # e.g. Colloid-Dark-Compact-*
      color = mkOption {
        type = types.enum [
          "dark"
          "light"
        ];
        default = "dark";
        description = "GTK color variant.";
      };

      size = mkOption {
        type = types.enum [
          "standard"
          "compact"
        ];
        default = "compact";
        description = "GTK size variant.";
      };

      accent = mkOption {
        type = types.enum [
          "default"
          "purple"
          "pink"
          "red"
          "orange"
          "yellow"
          "green"
          "teal"
          "grey"
          "all"
        ];
        default = "all";
        description = "GTK accent (Colloid themeVariants).";
      };

      tweak = mkOption {
        type = types.enum [
          "normal"
          "rimless"
          "float"
          "black"
        ];
        default = "normal";
        description = "GTK tweak (Colloid tweaks).";
      };

      themeName = mkOption {
        type = types.nullOr types.str;
        default = null;
        description = "Explicit GTK theme name override. If null, computed from color/size/accent.";
      };
    };

    icons = {
      # Colloid icon scheme usually supports several named schemes. Default follows palette name.
      scheme = mkOption {
        type = types.enum [
          "default"
          "nord"
          "dracula"
          "gruvbox"
          "everforest"
          "catppuccin"
        ];
        default = cfg.name;
        description = "Icon scheme to use (Colloid schemeVariants).";
      };

      variant = mkOption {
        type = types.enum [
          "default"
          "purple"
          "pink"
          "red"
          "orange"
          "yellow"
          "green"
          "teal"
          "grey"
          "all"
        ];
        default = "all";
        description = "Icon variant (Colloid colorVariants).";
      };

      themeName = mkOption {
        type = types.nullOr types.str;
        default = null;
        description = "Explicit icon theme name override. If null, computed from scheme/variant.";
      };
    };
  };

  # Wire derived defaults that depend on other options.
  config = {
    # Keep paletteFile following the chosen name unless user overrides it explicitly.
    mjallen.theme.paletteFile = mkDefault (mkPalettePath cfg.name);

    # Pull tokens directly from the palette file for convenience
    mjallen.theme.tokens = mkDefault (
      let
        pal = import cfg.paletteFile;
      in
      pal.tokens or { }
    );

    # Expose the imported palette for convenience
    mjallen.theme.palette = mkDefault (import cfg.paletteFile);

    # Default per-program palette path (can still be overridden per program)
    mjallen.programs.waybar.theme.file = mkDefault cfg.paletteFile;
    mjallen.programs.kitty.theme.file = mkDefault cfg.paletteFile;
    mjallen.programs.mako.theme.file = mkDefault cfg.paletteFile;
    mjallen.programs.wofi.theme.file = mkDefault cfg.paletteFile;
    mjallen.programs.btop.theme.file = mkDefault cfg.paletteFile;
    mjallen.programs.nwg-dock.theme.file = mkDefault cfg.paletteFile;
    mjallen.programs.nwg-drawer.theme.file = mkDefault cfg.paletteFile;
    mjallen.programs.wlogout.theme.file = mkDefault cfg.paletteFile;

    # Computed GTK/Icon theme names if not overridden
    _module.args.mjallenThemeComputed = {
      gtkTheme =
        if cfg.gtk.themeName != null then
          cfg.gtk.themeName
        else
          "Colloid-${cap cfg.gtk.color}-${cap cfg.gtk.size}";

      iconTheme =
        if cfg.icons.themeName != null then
          cfg.icons.themeName
        else
          "Colloid-${cap cfg.icons.scheme}-${cap cfg.gtk.color}";
    };
  };
}
