"use client";

import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { usePathname, useRouter } from 'next/navigation';
import { SETTING_ACTIONS, HELP_ARTICLE_META } from '@/lib/help/registry.js';
import SmartSearchValueModal from './smart-search-value-modal.jsx';

const NAV_ITEMS = [
  { title: 'Overview', href: '/', section: 'Navigate', keys: ['dashboard', 'home', 'canvas', 'main'] },
  { title: 'Agents', href: '/agents', section: 'Navigate', keys: ['agent', 'worker', 'roster', 'team'] },
  { title: 'Tasks', href: '/tasks', section: 'Navigate', keys: ['task', 'work', 'todo', 'kanban'] },
  { title: 'Approvals', href: '/approvals', section: 'Navigate', keys: ['approve', 'permission', 'review'] },
  { title: 'Tools', href: '/tools', section: 'Navigate', keys: ['tool', 'connector', 'capability'] },
  { title: 'Schedules', href: '/schedules', section: 'Navigate', keys: ['cron', 'schedule', 'calendar'] },
  { title: 'Reports', href: '/reports', section: 'Navigate', keys: ['report', 'artifact', 'brief'] },
  { title: 'Activity', href: '/activity', section: 'Navigate', keys: ['activity', 'runs', 'history'] },
  { title: 'Runtime', href: '/runtime', section: 'Navigate', keys: ['runtime', 'diagnostics', 'heartbeat', 'process'] },
  { title: 'Brand', href: '/brand', section: 'Navigate', keys: ['brand', 'identity', 'design'] },
  { title: 'Settings', href: '/settings', section: 'Navigate', keys: ['settings', 'config', 'preferences'] },
  { title: 'Help', href: '/help', section: 'Navigate', keys: ['help', 'guide', 'docs', 'documentation', 'shortcuts'] },
];

const QUICK_ACTIONS = [
  {
    id: 'focus-main-agent',
    title: 'Focus main agent composer',
    detail: 'Jump to the prompt box without leaving the keyboard.',
    section: 'Action',
    shortcut: '⌘J',
    keys: ['chat', 'composer', 'prompt', 'ask', 'agent'],
    run: ({ router, pathname }) => {
      if (pathname !== '/') {
        router.push('/');
        window.setTimeout(() => window.dispatchEvent(new Event('madarx:focus-composer')), 180);
      } else {
        window.dispatchEvent(new Event('madarx:focus-composer'));
      }
    },
  },
  {
    id: 'new-chat',
    title: 'New main-agent chat',
    detail: 'Fresh conversation without using ⌘N, which belongs to the browser.',
    section: 'Action',
    shortcut: '⌘⇧J',
    keys: ['new', 'session', 'chat', 'fresh'],
    run: ({ router, pathname }) => {
      if (pathname !== '/') router.push('/');
      window.setTimeout(() => window.dispatchEvent(new Event('madarx:new-chat')), pathname === '/' ? 0 : 180);
    },
  },
  {
    id: 'settings-modal',
    title: 'Open agent configuration',
    detail: 'Close to the right thumb, but avoids browser-level ⌘, preferences.',
    section: 'Action',
    shortcut: '⌘;',
    keys: ['settings', 'preferences', 'config', 'model'],
    run: ({ router, pathname }) => {
      if (pathname !== '/') {
        router.push('/');
        window.setTimeout(() => window.dispatchEvent(new Event('madarx:open-config')), 180);
      } else {
        window.dispatchEvent(new Event('madarx:open-config'));
      }
    },
  },
  {
    id: 'shortcut-help',
    title: 'Show keyboard shortcuts',
    detail: 'Open this palette and filter to shortcut help.',
    section: 'Action',
    shortcut: '⌘/',
    keys: ['keyboard', 'shortcut', 'help', 'command'],
    run: ({ openWithQuery }) => openWithQuery('shortcuts'),
  },
];

const SHORTCUT_NOTES = [
  { title: 'Open smart search', detail: '⌘Space or ⌘K. Thumb + home-row fallback; Ctrl Space also works when macOS owns Spotlight.', section: 'Shortcuts', keys: ['shortcut', 'search', 'spotlight', 'command space'] },
  { title: 'Focus main agent', detail: '⌘J. Right thumb + index on home row; avoids browser shortcuts.', section: 'Shortcuts', keys: ['shortcut', 'composer', 'prompt'] },
  { title: 'New chat', detail: '⌘⇧J. Same hand position as focus, with Shift; avoids ⌘N.', section: 'Shortcuts', keys: ['shortcut', 'new chat', 'session'] },
  { title: 'Agents / Tasks / Runtime', detail: '⌘⇧A, ⌘⇧T, ⌘⇧D. Left-hand clusters for common operating surfaces.', section: 'Shortcuts', keys: ['shortcut', 'navigation', 'agents', 'tasks', 'runtime'] },
  { title: 'Agent settings', detail: '⌘; sits under the right hand and avoids browser Preferences on ⌘,.', section: 'Shortcuts', keys: ['shortcut', 'settings', 'preferences'] },
];

function normalize(value) {
  return String(value || '').toLowerCase().trim();
}

function searchableText(item) {
  return [item.title, item.detail, item.section, item.href, ...(item.keys || [])].filter(Boolean).join(' ').toLowerCase();
}

function isTypingTarget(target) {
  const tag = target?.tagName?.toLowerCase();
  return target?.isContentEditable || tag === 'input' || tag === 'textarea' || tag === 'select';
}

export default function SmartSearch() {
  const router = useRouter();
  const pathname = usePathname();
  const inputRef = useRef(null);
  const [open, setOpen] = useState(false);
  const [query, setQuery] = useState('');
  const [active, setActive] = useState(0);
  // Current state for setting actions, keyed by action id. Fetched once.
  const [currentById, setCurrentById] = useState({});
  const [indexLoaded, setIndexLoaded] = useState(false);
  // The setting action whose value modal is open (independent of the palette).
  const [activeSetting, setActiveSetting] = useState(null);

  const loadIndex = useCallback(async () => {
    try {
      const res = await fetch('/api/help', { cache: 'no-store' });
      if (!res.ok) return;
      const data = await res.json();
      const map = {};
      for (const a of data.actions || []) map[a.id] = a.current;
      setCurrentById(map);
      setIndexLoaded(true);
    } catch {
      // Non-fatal: setting rows still work, they just won't show current status.
    }
  }, []);

  const items = useMemo(() => {
    const nav = NAV_ITEMS.map(item => ({
      ...item,
      id: `nav:${item.href}`,
      kind: 'nav',
      detail: item.href === '/' ? 'Return to the main command center.' : `Open ${item.href}`,
      run: ({ router }) => router.push(item.href),
    }));
    const settings = SETTING_ACTIONS.map(action => ({
      id: `set:${action.id}`,
      kind: 'setting',
      action,
      title: action.title,
      detail: action.field?.help || 'Set this value.',
      section: 'Set',
      keys: action.keywords,
    }));
    const docs = HELP_ARTICLE_META.map(article => ({
      id: `doc:${article.slug}`,
      kind: 'doc',
      title: article.title,
      detail: article.summary,
      section: 'Doc',
      href: `/help/${article.slug}`,
      keys: article.keywords,
    }));
    return [...QUICK_ACTIONS, ...settings, ...docs, ...nav, ...SHORTCUT_NOTES];
  }, []);

  const results = useMemo(() => {
    const q = normalize(query);
    if (!q) return items.slice(0, 10);
    const terms = q.split(/\s+/).filter(Boolean);
    return items
      .map(item => {
        const hay = searchableText(item);
        const score = terms.reduce((sum, term) => sum + (hay.includes(term) ? 1 : 0), 0);
        const starts = normalize(item.title).startsWith(q) ? 3 : 0;
        return { item, score: score + starts };
      })
      .filter(({ score }) => score > 0)
      .sort((a, b) => b.score - a.score || a.item.title.localeCompare(b.item.title))
      .map(({ item }) => item)
      .slice(0, 12);
  }, [items, query]);

  const openWithQuery = nextQuery => {
    setQuery(nextQuery || '');
    setOpen(true);
    setActive(0);
  };

  const close = () => {
    setOpen(false);
    setQuery('');
    setActive(0);
  };

  const openSetting = useCallback(actionId => {
    const action = SETTING_ACTIONS.find(a => a.id === actionId);
    if (action) setActiveSetting(action);
  }, []);

  const closeModal = useCallback(() => setActiveSetting(null), []);

  const runItem = item => {
    if (!item) return;
    if (item.kind === 'setting') {
      setActiveSetting(item.action);
      close();
      return;
    }
    if (item.kind === 'doc') {
      router.push(item.href);
      close();
      return;
    }
    if (!item.run) return;
    item.run({ router, pathname, openWithQuery });
    if (item.section !== 'Shortcuts') close();
  };

  // Load the help index when the palette first opens, or when a setting modal is
  // requested from elsewhere (e.g. a doc page "Set this now" button).
  useEffect(() => {
    if ((open || activeSetting) && !indexLoaded) loadIndex();
  }, [open, activeSetting, indexLoaded, loadIndex]);

  useEffect(() => {
    if (!open) return;
    const t = window.setTimeout(() => inputRef.current?.focus(), 0);
    return () => window.clearTimeout(t);
  }, [open]);

  useEffect(() => {
    setActive(0);
  }, [query, open]);

  // Allow other surfaces (doc pages) to open a value modal directly.
  useEffect(() => {
    function onOpenSetting(event) {
      const id = event?.detail?.id;
      if (id) openSetting(id);
    }
    window.addEventListener('madarx:open-setting', onOpenSetting);
    return () => window.removeEventListener('madarx:open-setting', onOpenSetting);
  }, [openSetting]);

  useEffect(() => {
    function onKeyDown(event) {
      const key = (event.key || '').toLowerCase();
      const mod = event.metaKey || event.ctrlKey;
      const typing = isTypingTarget(event.target);

      if (open) {
        if (event.key === 'Escape') { event.preventDefault(); close(); return; }
        if (event.key === 'ArrowDown') { event.preventDefault(); setActive(i => Math.min(i + 1, Math.max(0, results.length - 1))); return; }
        if (event.key === 'ArrowUp') { event.preventDefault(); setActive(i => Math.max(0, i - 1)); return; }
        if (event.key === 'Enter') { event.preventDefault(); runItem(results[active]); return; }
      }

      if ((event.metaKey && event.code === 'Space') || (event.metaKey && key === 'k') || (event.ctrlKey && event.code === 'Space')) {
        event.preventDefault();
        setOpen(value => {
          // Opening the palette dismisses any value modal so the two never stack.
          if (!value) setActiveSetting(null);
          return !value;
        });
        return;
      }

      if (!mod || typing) return;

      if (event.metaKey && key === 'j' && !event.shiftKey) {
        event.preventDefault();
        QUICK_ACTIONS[0].run({ router, pathname });
        return;
      }
      if (event.metaKey && key === 'j' && event.shiftKey) {
        event.preventDefault();
        QUICK_ACTIONS[1].run({ router, pathname });
        return;
      }
      if (event.metaKey && key === ';') {
        event.preventDefault();
        QUICK_ACTIONS[2].run({ router, pathname });
        return;
      }
      if (event.metaKey && key === '/') {
        event.preventDefault();
        openWithQuery('shortcuts');
        return;
      }
      if (event.metaKey && event.shiftKey && ['a', 't', 'd'].includes(key)) {
        event.preventDefault();
        const href = key === 'a' ? '/agents' : key === 't' ? '/tasks' : '/runtime';
        router.push(href);
      }
    }

    window.addEventListener('keydown', onKeyDown);
    return () => window.removeEventListener('keydown', onKeyDown);
  }, [active, open, pathname, results, router]);

  const modal = activeSetting ? (
    <SmartSearchValueModal
      action={activeSetting}
      current={currentById[activeSetting.id]}
      onClose={closeModal}
      onSaved={loadIndex}
    />
  ) : null;

  if (!open) return modal;

  return (
    <>
      <div className="smart-search-overlay" role="presentation" onMouseDown={event => { if (event.target === event.currentTarget) close(); }}>
        <section className="smart-search-panel" role="dialog" aria-modal="true" aria-label="Smart search">
          <div className="smart-search-head">
            <span className="smart-search-orb" aria-hidden="true" />
            <input
              ref={inputRef}
              value={query}
              onChange={event => setQuery(event.target.value)}
              placeholder="Search docs, settings, pages…"
              aria-label="Search madarX OS"
            />
            <kbd>esc</kbd>
          </div>
          <div className="smart-search-results" role="listbox" aria-label="Smart search results">
            {results.length ? results.map((item, index) => {
              const current = item.kind === 'setting' ? currentById[item.action.id] : null;
              const status = current ? (item.action.kind === 'secret' ? (current.status === 'set' ? 'Set' : null) : null) : null;
              return (
                <button
                  key={item.id || item.title}
                  type="button"
                  className={'smart-search-row' + (index === active ? ' is-active' : '')}
                  onMouseEnter={() => setActive(index)}
                  onClick={() => runItem(item)}
                  role="option"
                  aria-selected={index === active}
                >
                  <span className="smart-search-row-main">
                    <small>
                      <span className={`smart-search-kind kind-${item.kind || 'nav'}`}>{item.section}</span>
                      {status ? <span className="smart-search-pill">{status}</span> : null}
                    </small>
                    <b>{item.title}</b>
                    <em>{item.detail}</em>
                  </span>
                  {item.shortcut ? <kbd>{item.shortcut}</kbd> : item.href ? <kbd>{item.href}</kbd> : null}
                </button>
              );
            }) : (
              <div className="smart-search-empty">No matches. Try “api key”, “whatsapp”, “agent”, or “shortcut”.</div>
            )}
          </div>
          <footer className="smart-search-foot">
            <span><kbd>↑</kbd><kbd>↓</kbd> select</span>
            <span><kbd>return</kbd> open</span>
            <span><kbd>⌘J</kbd> composer</span>
          </footer>
        </section>
      </div>
      {modal}
    </>
  );
}
