'use client';

import * as DialogPrimitive from '@radix-ui/react-dialog';
import { AnimatePresence, motion } from 'framer-motion';
import { Plus, Search, X } from 'lucide-react';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { Input } from '@/components/ui/input';
import { springs } from '@/lib/animations';
import { getTauriAPI } from '@/lib/tauri-api-interface';
import { cn } from '@/lib/utils';
import type { Workspace } from '@/shared';
import { hasAnyReadyProvider } from '@/shared';
import { useTaskStore } from '@/stores/taskStore';
import { useWorkspaceStore } from '@/stores/workspaceStore';
import TaskLauncherItem from './TaskLauncherItem';

export default function TaskLauncher() {
  const navigate = useNavigate();
  const [searchQuery, setSearchQuery] = useState('');
  const [selectedIndex, setSelectedIndex] = useState(0);

  const { isLauncherOpen, closeLauncher, allTasks, loadAllTasks, startTask } = useTaskStore();
  const { workspaces, activeWorkspace, switchWorkspace } = useWorkspaceStore();
  const api = getTauriAPI();

  // Build workspace lookup map
  const workspaceMap = useMemo(() => {
    const map = new Map<string, Workspace>();
    for (const ws of workspaces) {
      map.set(ws.id, ws);
    }
    return map;
  }, [workspaces]);

  // Load all tasks when launcher opens
  useEffect(() => {
    if (isLauncherOpen) {
      loadAllTasks();
    }
  }, [isLauncherOpen, loadAllTasks]);

  // Filter tasks by search query (title only)
  const filteredTasks = useMemo(() => {
    if (!searchQuery.trim()) {
      // Show last 7 days when no search
      const sevenDaysAgo = Date.now() - 7 * 24 * 60 * 60 * 1000;
      return allTasks.filter((t) => new Date(t.createdAt).getTime() > sevenDaysAgo);
    }
    const query = searchQuery.toLowerCase();
    return allTasks.filter((t) => t.prompt.toLowerCase().includes(query));
  }, [allTasks, searchQuery]);

  // Total items: "New task" + filtered tasks
  const totalItems = 1 + filteredTasks.length;

  // Clamp selected index when results change
  useEffect(() => {
    setSelectedIndex((i) => Math.min(i, Math.max(0, totalItems - 1)));
  }, [totalItems]);

  // Reset state when launcher opens
  useEffect(() => {
    if (isLauncherOpen) {
      setSearchQuery('');
      setSelectedIndex(0);
    }
  }, [isLauncherOpen]);

  const handleOpenChange = useCallback(
    (open: boolean) => {
      if (!open && isLauncherOpen) {
        closeLauncher();
        setSearchQuery('');
        setSelectedIndex(0);
      }
    },
    [isLauncherOpen, closeLauncher]
  );

  const handleSelect = useCallback(
    async (index: number) => {
      if (index === 0) {
        // "New task" selected
        if (searchQuery.trim()) {
          // Check if any provider is ready before starting task
          const settings = await api.getProviderSettings();
          if (!hasAnyReadyProvider(settings)) {
            // No ready provider - navigate to home which will show settings
            closeLauncher();
            navigate('/');
            return;
          }
          closeLauncher();
          const taskId = `task_${Date.now()}`;
          const task = await startTask({ prompt: searchQuery.trim(), taskId });
          if (task) {
            navigate(`/execution/${task.id}`);
          }
        } else {
          // Navigate to home for empty input
          closeLauncher();
          navigate('/');
        }
      } else {
        // Task selected - navigate to it, switching workspace if needed
        const task = filteredTasks[index - 1];
        if (task) {
          closeLauncher();
          if (task.workspaceId && task.workspaceId !== activeWorkspace?.id) {
            await switchWorkspace(task.workspaceId);
          }
          navigate(`/execution/${task.id}`);
        }
      }
    },
    [searchQuery, filteredTasks, closeLauncher, navigate, startTask, api, activeWorkspace?.id, switchWorkspace]
  );

  const handleKeyDown = useCallback(
    (e: React.KeyboardEvent) => {
      // Ignore Enter during IME composition (Chinese/Japanese input)
      if (e.nativeEvent.isComposing || e.keyCode === 229) return;
      switch (e.key) {
        case 'ArrowDown':
          e.preventDefault();
          setSelectedIndex((i) => Math.min(i + 1, totalItems - 1));
          break;
        case 'ArrowUp':
          e.preventDefault();
          setSelectedIndex((i) => Math.max(i - 1, 0));
          break;
        case 'Enter':
          e.preventDefault();
          handleSelect(selectedIndex);
          break;
        case 'Escape':
          e.preventDefault();
          closeLauncher();
          break;
      }
    },
    [totalItems, selectedIndex, handleSelect, closeLauncher]
  );

  return (
    <DialogPrimitive.Root onOpenChange={handleOpenChange} open={isLauncherOpen}>
      <AnimatePresence>
        {isLauncherOpen && (
          <DialogPrimitive.Portal forceMount>
            {/* Overlay */}
            <DialogPrimitive.Overlay asChild>
              <motion.div
                animate={{ opacity: 1 }}
                className="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
                exit={{ opacity: 0 }}
                initial={{ opacity: 0 }}
                transition={{ duration: 0.15 }}
              />
            </DialogPrimitive.Overlay>

            {/* Content */}
            <DialogPrimitive.Content className="fixed inset-0 z-50 flex items-start justify-center pt-[20vh]" onKeyDown={handleKeyDown}>
              <motion.div
                animate={{ opacity: 1, scale: 1, y: 0 }}
                className="w-full max-w-2xl overflow-hidden rounded-lg border border-border bg-card shadow-2xl"
                exit={{ opacity: 0, scale: 0.95, y: -10 }}
                initial={{ opacity: 0, scale: 0.95, y: -10 }}
                transition={springs.bouncy}
              >
                {/* Search Input */}
                <div className="flex items-center gap-3 border-border border-b px-4 py-3">
                  <Search className="h-4 w-4 shrink-0 text-muted-foreground" />
                  <Input
                    className="h-full border-0 px-0 py-1 focus:outline-none focus-visible:ring-0"
                    onChange={(e) => setSearchQuery(e.target.value)}
                    placeholder="Search tasks across all workspaces..."
                    type="text"
                    value={searchQuery}
                  />
                  <DialogPrimitive.Close asChild>
                    <button aria-label="Close" className="text-muted-foreground transition-colors hover:text-foreground">
                      <X className="h-4 w-4" />
                    </button>
                  </DialogPrimitive.Close>
                </div>

                {/* Results */}
                <div className="max-h-80 overflow-y-auto p-2">
                  {/* New Task Option */}
                  <button
                    className={cn(
                      'w-full rounded-md px-3 py-2 text-left text-sm transition-colors duration-100',
                      'flex items-center gap-2',
                      selectedIndex === 0 ? 'bg-primary text-primary-foreground' : 'text-foreground hover:bg-accent'
                    )}
                    onClick={() => handleSelect(0)}
                  >
                    <Plus className="h-4 w-4 shrink-0" />
                    <span>New task</span>
                    {searchQuery.trim() && (
                      <span
                        className={cn('truncate text-xs', selectedIndex === 0 ? 'text-primary-foreground/70' : 'text-muted-foreground')}
                      >
                        — "{searchQuery}"
                      </span>
                    )}
                  </button>

                  {/* Task List */}
                  {filteredTasks.length > 0 && (
                    <>
                      <div className="px-3 py-2 font-medium text-muted-foreground text-xs">
                        {searchQuery.trim() ? 'Results' : 'Last 7 days'}
                      </div>
                      {filteredTasks.slice(0, 10).map((task, i) => (
                        <TaskLauncherItem
                          activeWorkspaceId={activeWorkspace?.id}
                          isSelected={selectedIndex === i + 1}
                          key={task.id}
                          onClick={() => handleSelect(i + 1)}
                          task={task}
                          workspace={task.workspaceId ? workspaceMap.get(task.workspaceId) : undefined}
                        />
                      ))}
                    </>
                  )}

                  {/* Empty State */}
                  {searchQuery.trim() && filteredTasks.length === 0 && (
                    <div className="px-3 py-4 text-center text-muted-foreground text-sm">No tasks found</div>
                  )}
                </div>

                {/* Footer hint */}
                <div className="flex items-center gap-4 border-border border-t px-4 py-2 text-muted-foreground text-xs">
                  <span>
                    <kbd className="rounded bg-muted px-1.5 py-0.5 text-[10px]">↑↓</kbd> Navigate
                  </span>
                  <span>
                    <kbd className="rounded bg-muted px-1.5 py-0.5 text-[10px]">↵</kbd> Select
                  </span>
                  <span>
                    <kbd className="rounded bg-muted px-1.5 py-0.5 text-[10px]">Esc</kbd> Close
                  </span>
                </div>
              </motion.div>
            </DialogPrimitive.Content>
          </DialogPrimitive.Portal>
        )}
      </AnimatePresence>
    </DialogPrimitive.Root>
  );
}
