# yazi — the flagship file manager: a fast, keyboard-driven TUI that
# fits the distro's identity (Ghostty's Kitty-graphics previews, rofi
# menus, everything from one JSON). Themed from theme-state.json and
# shipped with a curated plugin set. The GUI half (Thunar, "open folder"
# handler) is nomarchy.system.fileManager on the system side.
#
# `y` (the shell wrapper) cd's the shell to yazi's last directory on
# exit; SUPER+E opens it in a fresh terminal.
{ config, lib, pkgs, ... }:

let
  cfg = config.nomarchy;
  t = cfg.theme;
  c = t.colors;
in
{
  config = lib.mkIf cfg.yazi.enable {
    # Preview + tooling deps yazi shells out to (thumbnails, search,
    # archives, the plugins below). All small CLIs.
    home.packages = with pkgs; [
      ffmpegthumbnailer # video thumbnails
      poppler-utils     # PDF previews (pdftoppm)
      p7zip             # archive preview + the compress plugin
      jq                # JSON preview
      fd ripgrep fzf    # navigation / search integrations
      chafa             # image fallback when the terminal lacks graphics
      mediainfo         # mediainfo plugin (audio/subtitle metadata)
      glow              # glow plugin (markdown rendering)
    ];

    programs.yazi = {
      enable = true;
      shellWrapperName = "y"; # `y` cd's on exit; `yazi` stays a no-cd launcher
      enableBashIntegration = true;

      settings = {
        mgr = {
          show_hidden = false;
          sort_by = "natural";
          sort_dir_first = true;
          linemode = "size";
        };
        preview = {
          max_width = 1000;
          max_height = 1000;
        };
        plugin = {
          # git status in the linemode (fetcher registered before setup).
          # yazi 26.x made `group` required on fetchers (without it the
          # config fails to parse and yazi falls back to presets); "*"
          # matches files, "*/" dirs, so they share the "git" group.
          prepend_fetchers = [
            { id = "git"; url = "*"; run = "git"; group = "git"; }
            { id = "git"; url = "*/"; run = "git"; group = "git"; }
          ];
          # Route only audio + subtitles to mediainfo's text metadata;
          # images/videos keep yazi's native visual thumbnails. Markdown
          # renders through glow.
          # Match field is `url` (a path glob) or `mime` — yazi 26.x renamed
          # the old `name` to `url`, same as the fetchers above. Using `name`
          # fails the parse ("at least one of 'url' or 'mime'") and yazi falls
          # back to its presets.
          prepend_previewers = [
            { url = "*.md"; run = "glow"; }
            { mime = "audio/*"; run = "mediainfo"; }
            { mime = "application/subrip"; run = "mediainfo"; }
          ];
        };
      };

      keymap.mgr.prepend_keymap = [
        { on = "l"; run = "plugin smart-enter"; desc = "Enter dir or open file"; }
        { on = "<Enter>"; run = "plugin smart-enter"; desc = "Enter dir or open file"; }
        { on = [ "c" "m" ]; run = "plugin chmod"; desc = "Chmod on selected files"; }
        { on = "M"; run = "plugin mount"; desc = "Mount/unmount manager"; }
        { on = [ "c" "a" "a" ]; run = "plugin compress"; desc = "Archive selected files"; }
      ];

      # Curated plugins (nixpkgs yaziPlugins). setup = true emits the
      # require(...):setup() call in init.lua; the rest are invoked via
      # the keymap/previewer/fetcher wiring above.
      plugins = {
        full-border = { package = pkgs.yaziPlugins.full-border; setup = true; };
        git = { package = pkgs.yaziPlugins.git; setup = true; };
        smart-enter = { package = pkgs.yaziPlugins.smart-enter; };
        chmod = { package = pkgs.yaziPlugins.chmod; };
        mount = { package = pkgs.yaziPlugins.mount; };
        compress = { package = pkgs.yaziPlugins.compress; };
        mediainfo = { package = pkgs.yaziPlugins.mediainfo; };
        glow = { package = pkgs.yaziPlugins.glow; };
      };

      # Theme from the palette. yazi merges this over its built-in theme,
      # so only the accent-bearing UI is specified; everything else keeps
      # yazi's defaults (which already follow Ghostty's ANSI colors).
      theme = {
        mgr = {
          cwd = { fg = c.accent; };
          hovered = { fg = c.base; bg = c.accent; };
          preview_hovered = { underline = true; };
          find_keyword = { fg = c.warn; italic = true; };
          find_position = { fg = c.accentAlt; bg = "reset"; italic = true; };
          marker_copied = { fg = c.good; bg = c.good; };
          marker_cut = { fg = c.bad; bg = c.bad; };
          marker_marked = { fg = c.accent; bg = c.accent; };
          marker_selected = { fg = c.warn; bg = c.warn; };
          count_copied = { fg = c.base; bg = c.good; };
          count_cut = { fg = c.base; bg = c.bad; };
          count_selected = { fg = c.base; bg = c.warn; };
          border_symbol = "│";
          border_style = { fg = c.muted; };
        };
        mode = {
          normal_main = { fg = c.base; bg = c.accent; bold = true; };
          normal_alt = { fg = c.accent; bg = c.surface; };
          select_main = { fg = c.base; bg = c.good; bold = true; };
          select_alt = { fg = c.good; bg = c.surface; };
          unset_main = { fg = c.base; bg = c.accentAlt; bold = true; };
          unset_alt = { fg = c.accentAlt; bg = c.surface; };
        };
        status = {
          perm_type = { fg = c.accent; };
          perm_read = { fg = c.good; };
          perm_write = { fg = c.bad; };
          perm_exec = { fg = c.warn; };
          progress_label = { fg = c.text; bold = true; };
          progress_normal = { fg = c.accent; bg = c.surface; };
          progress_error = { fg = c.bad; bg = c.surface; };
        };
      };
    };
  };
}
