import { useEffect, useMemo, useState } from 'react';
import { Command } from 'cmdk';
import { useNavigate } from 'react-router-dom';
import { useQuery } from '@tanstack/react-query';
import toast from 'react-hot-toast';
import {
  Rss,
  Package,
  LayoutTemplate,
  FolderKanban,
  Mail,
  Users,
  Clock,
  Shield,
  Activity,
  ListChecks,
  RefreshCw,
  Heart,
  Calendar,
  Tag,
  Megaphone,
  LayoutDashboard,
  Sparkles,
} from 'lucide-react';
import { api } from '../lib/api-client';

interface Props {
  open: boolean;
  onOpenChange: (open: boolean) => void;
}

interface NavCommand {
  id: string;
  label: string;
  hint?: string;
  icon: React.ComponentType<{ className?: string }>;
  run: () => void;
}

const ICONS = {
  dashboard: LayoutDashboard,
  feeds: Rss,
  products: Package,
  homepage: LayoutTemplate,
  collections: FolderKanban,
  categories: Tag,
  brands: Heart,
  calendar: Calendar,
  emails: Mail,
  subscribers: Users,
  push: Megaphone,
  crons: Clock,
  audit: Shield,
  health: Activity,
  jobs: ListChecks,
  sync: RefreshCw,
  regen: Sparkles,
};

export function CommandPalette({ open, onOpenChange }: Props) {
  const navigate = useNavigate();
  const [search, setSearch] = useState('');

  const searchQuery = search.trim();
  const dynamicActive = open && searchQuery.length >= 2;

  const { data: feedHits } = useQuery({
    queryKey: ['cmdk-feeds', searchQuery],
    queryFn: () => api.get<{ feeds: Array<{ id: number; name: string; slug: string }> }>('/feeds'),
    enabled: dynamicActive,
    staleTime: 30_000,
  });

  const { data: productHits } = useQuery({
    queryKey: ['cmdk-products', searchQuery],
    queryFn: () =>
      api.get<{ products: Array<{ id: number; title: string; brand: string | null; slug: string }> }>(
        '/products',
        { q: searchQuery, limit: 5 },
      ),
    enabled: dynamicActive,
    staleTime: 10_000,
  });

  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'k') {
        e.preventDefault();
        onOpenChange(!open);
      }
      if (e.key === 'Escape' && open) onOpenChange(false);
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open, onOpenChange]);

  const navCommands: NavCommand[] = useMemo(
    () => [
      { id: 'dash', label: 'Dashboard', icon: ICONS.dashboard, run: () => navigate('/cms') },
      { id: 'feeds', label: 'Feeds', hint: 'Beheer feeds', icon: ICONS.feeds, run: () => navigate('/cms/feeds') },
      { id: 'products', label: 'Producten', icon: ICONS.products, run: () => navigate('/cms/products') },
      { id: 'collections', label: 'Collecties', icon: ICONS.collections, run: () => navigate('/cms/collections') },
      { id: 'categories', label: 'Categorieën', icon: ICONS.categories, run: () => navigate('/cms/categories') },
      { id: 'homepage', label: 'Homepage bewerken', icon: ICONS.homepage, run: () => navigate('/cms/homepage') },
      { id: 'brands', label: 'Merken', icon: ICONS.brands, run: () => navigate('/cms/brands') },
      { id: 'calendar', label: 'Releasekalender', icon: ICONS.calendar, run: () => navigate('/cms/calendar') },
      { id: 'emails', label: 'Emails', icon: ICONS.emails, run: () => navigate('/cms/emails') },
      { id: 'subscribers', label: 'Subscribers', icon: ICONS.subscribers, run: () => navigate('/cms/subscribers') },
      { id: 'push', label: 'Push notificaties', icon: ICONS.push, run: () => navigate('/cms/push') },
      { id: 'jobs', label: 'Job queue', icon: ICONS.jobs, run: () => navigate('/cms/jobs') },
      { id: 'audit', label: 'Audit log', icon: ICONS.audit, run: () => navigate('/cms/audit') },
      { id: 'crons', label: 'Crons', icon: ICONS.crons, run: () => navigate('/cms/crons') },
      { id: 'health', label: 'System health', icon: ICONS.health, run: () => navigate('/cms/health') },
      { id: 'errors', label: 'Error log', icon: ICONS.audit, run: () => navigate('/cms/errors') },
    ],
    [navigate],
  );

  const actions: NavCommand[] = useMemo(
    () => [
      {
        id: 'sync-all',
        label: 'Sync alle feeds',
        hint: 'Trigger handmatig',
        icon: ICONS.sync,
        run: async () => {
          await api.post('/feeds/sync-all').catch(() => {});
          navigate('/cms/jobs');
        },
      },
      {
        id: 'cache-clear',
        label: 'Leeg cache',
        icon: RefreshCw,
        run: async () => {
          await api.post('/system/cache-clear').catch(() => {});
        },
      },
    ],
    [navigate],
  );

  const close = (run: () => void | Promise<void>) => {
    onOpenChange(false);
    setTimeout(() => void run(), 50);
  };

  if (!open) return null;

  return (
    <div
      className="fixed inset-0 z-[100] bg-black/60 backdrop-blur-sm flex items-start justify-center pt-[15vh]"
      onClick={() => onOpenChange(false)}
    >
      <Command
        className="w-full max-w-xl mx-4 bg-[#141414] border border-[#333] rounded-xl shadow-2xl overflow-hidden"
        onClick={(e) => e.stopPropagation()}
      >
        <Command.Input
          value={search}
          onValueChange={setSearch}
          placeholder="Typ een commando of pagina…"
          className="w-full bg-[#0A0A0A] border-b border-[#333] px-4 py-3 text-sm text-[#F5F5F5] placeholder:text-[#666] focus:outline-none"
          autoFocus
        />
        <Command.List className="max-h-[60vh] overflow-auto p-2">
          <Command.Empty className="p-6 text-center text-sm text-[#666]">Geen resultaten.</Command.Empty>

          <Command.Group heading="Navigatie" className="text-[10px] uppercase tracking-wider text-[#666] px-2 pt-2 pb-1">
            {navCommands.map((cmd) => (
              <Command.Item
                key={cmd.id}
                value={`nav ${cmd.label}`}
                onSelect={() => close(cmd.run)}
                className="flex items-center gap-3 px-3 py-2 text-sm text-[#F5F5F5] rounded cursor-pointer data-[selected=true]:bg-[#1A1A1A]"
              >
                <cmd.icon className="h-4 w-4 text-[#999]" />
                <span>{cmd.label}</span>
                {cmd.hint && <span className="ml-auto text-[10px] text-[#666]">{cmd.hint}</span>}
              </Command.Item>
            ))}
          </Command.Group>

          <Command.Group heading="Acties" className="text-[10px] uppercase tracking-wider text-[#666] px-2 pt-2 pb-1">
            {actions.map((cmd) => (
              <Command.Item
                key={cmd.id}
                value={`action ${cmd.label}`}
                onSelect={() => close(cmd.run)}
                className="flex items-center gap-3 px-3 py-2 text-sm text-[#F5F5F5] rounded cursor-pointer data-[selected=true]:bg-[#1A1A1A]"
              >
                <cmd.icon className="h-4 w-4 text-[#00FF6A]" />
                <span>{cmd.label}</span>
                {cmd.hint && <span className="ml-auto text-[10px] text-[#666]">{cmd.hint}</span>}
              </Command.Item>
            ))}
          </Command.Group>

          {dynamicActive && (feedHits?.feeds?.length ?? 0) > 0 && (
            <Command.Group
              heading="Feeds"
              className="text-[10px] uppercase tracking-wider text-[#666] px-2 pt-2 pb-1"
            >
              {feedHits!.feeds
                .filter((f) => f.name.toLowerCase().includes(searchQuery.toLowerCase()))
                .slice(0, 5)
                .map((f) => (
                  <Command.Item
                    key={`feed-${f.id}`}
                    value={`feed sync ${f.name}`}
                    onSelect={() =>
                      close(async () => {
                        await api.post(`/feeds/${f.id}/sync`).catch((e: Error) => toast.error(e.message));
                        toast.success(`Feed "${f.name}" in wachtrij`);
                        navigate('/cms/jobs');
                      })
                    }
                    className="flex items-center gap-3 px-3 py-2 text-sm text-[#F5F5F5] rounded cursor-pointer data-[selected=true]:bg-[#1A1A1A]"
                  >
                    <ICONS.sync className="h-4 w-4 text-[#00FF6A]" />
                    <span>Sync feed: {f.name}</span>
                  </Command.Item>
                ))}
            </Command.Group>
          )}

          {dynamicActive && (productHits?.products?.length ?? 0) > 0 && (
            <Command.Group
              heading="Producten"
              className="text-[10px] uppercase tracking-wider text-[#666] px-2 pt-2 pb-1"
            >
              {productHits!.products.slice(0, 5).map((p) => (
                <Command.Item
                  key={`prod-${p.id}`}
                  value={`product ${p.title}`}
                  onSelect={() => close(() => navigate(`/cms/products?q=${encodeURIComponent(p.title)}`))}
                  className="flex items-center gap-3 px-3 py-2 text-sm text-[#F5F5F5] rounded cursor-pointer data-[selected=true]:bg-[#1A1A1A]"
                >
                  <ICONS.products className="h-4 w-4 text-[#999]" />
                  <span className="truncate">{p.title}</span>
                  <span className="ml-auto text-[10px] text-[#666]">{p.brand ?? '—'}</span>
                </Command.Item>
              ))}
            </Command.Group>
          )}
        </Command.List>
        <div className="border-t border-[#333] px-3 py-2 text-[10px] text-[#666] flex items-center gap-3">
          <span><kbd className="bg-[#0A0A0A] border border-[#333] rounded px-1.5 py-0.5">↑↓</kbd> navigeer</span>
          <span><kbd className="bg-[#0A0A0A] border border-[#333] rounded px-1.5 py-0.5">↵</kbd> kies</span>
          <span><kbd className="bg-[#0A0A0A] border border-[#333] rounded px-1.5 py-0.5">Esc</kbd> sluit</span>
        </div>
      </Command>
    </div>
  );
}
