// Cmd/Ctrl+K command palette — action catalog (t-paliad-044).
//
// Every action shown above the entity-search results is defined here. Adding /
// removing actions = editing this file. The dispatcher (`runAction`) reuses
// existing DOM handlers (lang toggle button, sidebar pin, invite modal) rather
// than duplicating their state, so the source of truth for each behavior stays
// where it already lives.
//
// Substring filter is intentionally simple — no fuzzy match, no token
// permutation. Matches against BOTH the current-language label and the other-
// language label so a German speaker who types "deadline" still finds Fristen.

import { getLang, tDyn } from "./i18n";

export type ActionGroup = "navigate" | "create" | "toggle";

export interface PaletteAction {
  id: string;
  i18nKey: string;
  fallbackDe: string;
  fallbackEn: string;
  iconKey: ActionIconKey;
  group: ActionGroup;
}

// Stroke-based icons matching the sidebar/search aesthetic (1.5 width,
// currentColor). Picked per action; reused where the meaning maps.
export type ActionIconKey =
  | "dashboard"
  | "folder"
  | "clock"
  | "calendar"
  | "agenda"
  | "users"
  | "book"
  | "building"
  | "link"
  | "check"
  | "download"
  | "gear"
  | "plus"
  | "globe"
  | "pin"
  | "mail"
  | "logout";

export const PALETTE_ACTIONS: PaletteAction[] = [
  // Navigate
  { id: "nav.dashboard",    i18nKey: "palette.action.nav.dashboard",    fallbackDe: "Gehe zu Dashboard",       fallbackEn: "Go to Dashboard",       iconKey: "dashboard", group: "navigate" },
  { id: "nav.projects",     i18nKey: "palette.action.nav.projects",     fallbackDe: "Gehe zu Projekte",        fallbackEn: "Go to Projects",        iconKey: "folder",    group: "navigate" },
  { id: "nav.deadlines",    i18nKey: "palette.action.nav.deadlines",    fallbackDe: "Gehe zu Fristen",         fallbackEn: "Go to Deadlines",       iconKey: "clock",     group: "navigate" },
  { id: "nav.appointments", i18nKey: "palette.action.nav.appointments", fallbackDe: "Gehe zu Termine",         fallbackEn: "Go to Appointments",    iconKey: "calendar",  group: "navigate" },
  { id: "nav.agenda",       i18nKey: "palette.action.nav.agenda",       fallbackDe: "Gehe zu Agenda",          fallbackEn: "Go to Agenda",          iconKey: "agenda",    group: "navigate" },
  { id: "nav.team",         i18nKey: "palette.action.nav.team",         fallbackDe: "Gehe zu Team",            fallbackEn: "Go to Team",            iconKey: "users",     group: "navigate" },
  { id: "nav.glossary",     i18nKey: "palette.action.nav.glossary",     fallbackDe: "Gehe zu Glossar",         fallbackEn: "Go to Glossary",        iconKey: "book",      group: "navigate" },
  { id: "nav.courts",       i18nKey: "palette.action.nav.courts",       fallbackDe: "Gehe zu Gerichte",        fallbackEn: "Go to Courts",          iconKey: "building",  group: "navigate" },
  { id: "nav.links",        i18nKey: "palette.action.nav.links",        fallbackDe: "Gehe zu Links",           fallbackEn: "Go to Links",           iconKey: "link",      group: "navigate" },
  { id: "nav.checklists",   i18nKey: "palette.action.nav.checklists",   fallbackDe: "Gehe zu Checklisten",     fallbackEn: "Go to Checklists",      iconKey: "check",     group: "navigate" },
  { id: "nav.downloads",    i18nKey: "palette.action.nav.downloads",    fallbackDe: "Gehe zu Downloads",       fallbackEn: "Go to Downloads",       iconKey: "download",  group: "navigate" },
  { id: "nav.settings",     i18nKey: "palette.action.nav.settings",     fallbackDe: "Gehe zu Einstellungen",   fallbackEn: "Go to Settings",        iconKey: "gear",      group: "navigate" },

  // Create
  { id: "create.deadline",    i18nKey: "palette.action.create.deadline",    fallbackDe: "Neue Frist anlegen",     fallbackEn: "New deadline",     iconKey: "plus", group: "create" },
  { id: "create.appointment", i18nKey: "palette.action.create.appointment", fallbackDe: "Neuer Termin anlegen",   fallbackEn: "New appointment",  iconKey: "plus", group: "create" },
  { id: "create.project",     i18nKey: "palette.action.create.project",     fallbackDe: "Neues Projekt anlegen",  fallbackEn: "New project",      iconKey: "plus", group: "create" },

  // Toggle / app actions
  { id: "toggle.lang", i18nKey: "palette.action.toggle.lang", fallbackDe: "Sprache umschalten",    fallbackEn: "Toggle language",    iconKey: "globe",  group: "toggle" },
  { id: "toggle.pin",  i18nKey: "palette.action.toggle.pin",  fallbackDe: "Sidebar an-/abheften",  fallbackEn: "Pin / unpin sidebar", iconKey: "pin",   group: "toggle" },
  { id: "app.invite",  i18nKey: "palette.action.app.invite",  fallbackDe: "Kolleg:in einladen",    fallbackEn: "Invite a colleague", iconKey: "mail",   group: "toggle" },
  { id: "app.logout",  i18nKey: "palette.action.app.logout",  fallbackDe: "Abmelden",              fallbackEn: "Logout",             iconKey: "logout", group: "toggle" },
];

// labelFor returns the active-language label for an action, falling back to
// the hard-coded fallbacks if i18n.ts hasn't loaded the key yet. The
// `lookup` callback takes a runtime string because action.i18nKey is read
// off a config object — callers should pass `tDyn` (not `t`) since the
// i18n key is composed at runtime.
export function labelFor(action: PaletteAction, lookup: (k: string) => string): string {
  const lang = getLang();
  const translated = lookup(action.i18nKey);
  if (translated && translated !== action.i18nKey) return translated;
  return lang === "en" ? action.fallbackEn : action.fallbackDe;
}

// filterActions runs a substring match against BOTH language fallbacks plus the
// translated label. Sorted: prefix-match > substring-match, ties broken by
// catalog order. Empty query returns the full catalog. See labelFor for the
// lookup contract — callers should pass `tDyn`.
export function filterActions(query: string, lookup: (k: string) => string): PaletteAction[] {
  const q = query.trim().toLowerCase();
  if (!q) return PALETTE_ACTIONS.slice();

  type Scored = { action: PaletteAction; score: number; idx: number };
  const scored: Scored[] = [];

  PALETTE_ACTIONS.forEach((action, idx) => {
    const haystacks = [
      labelFor(action, tDyn).toLowerCase(),
      action.fallbackDe.toLowerCase(),
      action.fallbackEn.toLowerCase(),
    ];
    let bestScore = -1;
    for (const h of haystacks) {
      if (h.startsWith(q)) {
        bestScore = Math.max(bestScore, 2);
        break;
      }
      if (h.includes(q)) {
        bestScore = Math.max(bestScore, 1);
      }
    }
    if (bestScore >= 0) scored.push({ action, score: bestScore, idx });
  });

  scored.sort((a, b) => (b.score - a.score) || (a.idx - b.idx));
  return scored.map((s) => s.action);
}

// runAction dispatches to the underlying behavior. Reuses existing DOM
// handlers wherever possible — sidebar pin, lang toggle, invite modal — so the
// source of truth stays where the feature lives.
export function runAction(id: string): void {
  switch (id) {
    case "nav.dashboard":    window.location.href = "/dashboard"; return;
    case "nav.projects":     window.location.href = "/projects"; return;
    case "nav.deadlines":    window.location.href = "/events?type=deadline"; return;
    case "nav.appointments": window.location.href = "/events?type=appointment"; return;
    case "nav.agenda":       window.location.href = "/agenda"; return;
    case "nav.team":         window.location.href = "/team"; return;
    case "nav.glossary":     window.location.href = "/glossary"; return;
    case "nav.courts":       window.location.href = "/courts"; return;
    case "nav.links":        window.location.href = "/links"; return;
    case "nav.checklists":   window.location.href = "/checklists"; return;
    case "nav.downloads":    window.location.href = "/downloads"; return;
    case "nav.settings":     window.location.href = "/settings"; return;

    case "create.deadline":    window.location.href = "/deadlines/new"; return;
    case "create.appointment": window.location.href = "/appointments/new"; return;
    case "create.project":     window.location.href = "/projects/new"; return;

    case "toggle.lang": {
      const cur = getLang();
      const next = cur === "de" ? "en" : "de";
      const btn = document.querySelector<HTMLButtonElement>(`[data-lang-toggle="${next}"]`);
      btn?.click();
      return;
    }
    case "toggle.pin": {
      const btn = document.querySelector<HTMLButtonElement>(".sidebar-pin");
      btn?.click();
      return;
    }
    case "app.invite": {
      const btn = document.getElementById("sidebar-invite-btn") as HTMLButtonElement | null;
      btn?.click();
      return;
    }
    case "app.logout":
      window.location.href = "/logout";
      return;
  }
}

// iconFor returns a tiny inline SVG. Stroke-based, 1.5 width, currentColor.
// Mirrors the sidebar/search icon language so the palette feels native.
export function iconForAction(key: ActionIconKey): string {
  const a = 'viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"';
  switch (key) {
    case "dashboard":
      return `<svg ${a}><path d="M12 14l3.5-3.5"/><path d="M3 12a9 9 0 0 1 18 0"/><path d="M12 3v2"/><path d="M3 12H5"/><path d="M19 12h2"/><path d="M5.6 5.6l1.4 1.4"/><path d="M17 7l1.4-1.4"/></svg>`;
    case "folder":
      return `<svg ${a}><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>`;
    case "clock":
      return `<svg ${a}><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>`;
    case "calendar":
      return `<svg ${a}><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>`;
    case "agenda":
      return `<svg ${a}><rect x="3" y="4" width="18" height="17" rx="2"/><line x1="3" y1="9" x2="21" y2="9"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="7" y1="13" x2="13" y2="13"/><line x1="7" y1="17" x2="17" y2="17"/></svg>`;
    case "users":
      return `<svg ${a}><circle cx="9" cy="8" r="4"/><path d="M2 21v-1a6 6 0 0 1 6-6h2a6 6 0 0 1 6 6v1"/><path d="M16 3a4 4 0 0 1 0 8"/><path d="M22 21v-1a6 6 0 0 0-4-5.66"/></svg>`;
    case "book":
      return `<svg ${a}><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>`;
    case "building":
      return `<svg ${a}><path d="M3 21h18"/><path d="M5 21V5a2 2 0 0 1 2-2h7a2 2 0 0 1 2 2v16"/><path d="M16 9h3a2 2 0 0 1 2 2v10"/></svg>`;
    case "link":
      return `<svg ${a}><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>`;
    case "check":
      return `<svg ${a}><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>`;
    case "download":
      return `<svg ${a}><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>`;
    case "gear":
      return `<svg ${a}><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>`;
    case "plus":
      return `<svg ${a}><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>`;
    case "globe":
      return `<svg ${a}><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>`;
    case "pin":
      return `<svg ${a}><line x1="12" y1="17" x2="12" y2="22"/><path d="M5 17h14v-1.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V6h1a1 1 0 0 0 0-2H8a1 1 0 0 0 0 2h1v4.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24Z"/></svg>`;
    case "mail":
      return `<svg ${a}><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>`;
    case "logout":
      return `<svg ${a}><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>`;
  }
  return "";
}
