import { useMemo, useState } from 'react';
import { Spotlight, type SpotlightActionData } from '@mantine/spotlight';
import { useDebouncedValue } from '@mantine/hooks';
import { IconFileText, IconSearch } from '@tabler/icons-react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
import { flattenNav, type NavSection } from '@ema-platform/ui';
import { useGetAllApplicationsQuery } from '@ema-platform/api';

/** Long enough that typing a company name does not fire a request per keystroke. */
const SEARCH_DEBOUNCE_MS = 250;

/** Below this, a server search matches too much to be useful. */
const MIN_SEARCH_LENGTH = 2;

interface CommandPaletteProps {
  /** Already permission-filtered, so the palette cannot reach a hidden route. */
  sections: NavSection[];
}

/**
 * ⌘K search over every destination and recent application.
 *
 * With twenty-plus destinations plus five licence types, hunting through
 * nested menus is the slow path. This makes nesting cheap: anything reachable
 * by clicking is reachable by typing, including applications by number,
 * company or TIN.
 */
export function CommandPalette({ sections }: CommandPaletteProps) {
  const { t } = useTranslation();
  const navigate = useNavigate();
  const [query, setQuery] = useState('');
  const [debounced] = useDebouncedValue(query, SEARCH_DEBOUNCE_MS);

  const term = debounced.trim();
  // Only hits the API once the palette is open and the query is meaningful.
  const { data: applications } = useGetAllApplicationsQuery(
    { search: term, take: 8 },
    { skip: term.length < MIN_SEARCH_LENGTH },
  );

  const destinationActions = useMemo<SpotlightActionData[]>(
    () =>
      flattenNav(sections)
        .filter((item) => item.to && !item.soon)
        .map((item) => ({
          id: item.to as string,
          label: t(item.label),
          description: item.to,
          leftSection: <item.icon size={18} stroke={1.6} />,
          onClick: () => navigate(item.to as string),
        })),
    [sections, navigate, t],
  );

  const applicationActions = useMemo<SpotlightActionData[]>(
    () =>
      (applications?.items ?? []).map((app) => ({
        id: `application-${app.id}`,
        label: app.companyName ?? app.applicationNumber,
        description: [app.applicationNumber, app.tinNumber]
          .filter(Boolean)
          .join(' · '),
        leftSection: <IconFileText size={18} stroke={1.6} />,
        onClick: () => navigate(`/licence-review/${app.id}`),
      })),
    [applications, navigate],
  );

  return (
    <Spotlight
      query={query}
      onQueryChange={setQuery}
      actions={[
        {
          group: t('nav.destinations', 'Go to'),
          actions: destinationActions,
        },
        {
          group: t('nav.applications', 'Applications'),
          actions: applicationActions,
        },
      ]}
      shortcut={['mod + K']}
      nothingFound={t('nav.noResults', 'Nothing found')}
      highlightQuery
      searchProps={{
        leftSection: <IconSearch size={18} stroke={1.6} />,
        placeholder: t(
          'nav.commandPlaceholder',
          'Search screens, applications, companies, TIN…',
        ),
      }}
    />
  );
}
