/**
 * CommandPanel Component
 *
 * 命令管理面板：列出、搜索、创建、编辑、删除命令
 */

import { useState, useEffect, useCallback } from 'react';
import {
  X,
  Plus,
  Search,
  Pencil,
  Trash2,
  RefreshCw,
  Terminal,
  User,
  FolderOpen,
  Cog,
} from 'lucide-react';
import { motion, AnimatePresence } from 'framer-motion';
import { toast } from 'sonner';
import { cn } from '../utils/cn';
import { modalOverlay, modalContent, smoothTransition } from '../utils/animations';
import { Button } from '../primitives/Button';
import { Input } from '../primitives/Input';
import { Skeleton } from './Skeleton';
import { CommandEditor } from './CommandEditor';
import {
  listCommands,
  deleteCommand,
  reloadCommands,
  type CommandListResponse,
} from '../api/client.js';

interface CommandPanelProps {
  onClose: () => void;
  /** 是否启用响应式布局 */
  responsive?: boolean;
}

type CommandItem = CommandListResponse['commands'][number];

// Source 图标映射
function getSourceIcon(source: string) {
  switch (source) {
    case 'builtin':
      return <Cog size={14} className="text-fg-muted" />;
    case 'user':
      return <User size={14} className="text-blue-400" />;
    case 'project':
      return <FolderOpen size={14} className="text-green-400" />;
    default:
      return <Terminal size={14} className="text-fg-muted" />;
  }
}

// Source 标签样式
function getSourceBadgeClass(source: string) {
  switch (source) {
    case 'builtin':
      return 'bg-surface-muted text-fg-secondary';
    case 'user':
      return 'bg-blue-500/20 text-blue-400';
    case 'project':
      return 'bg-green-500/20 text-green-400';
    default:
      return 'bg-surface-muted text-fg-secondary';
  }
}

export function CommandPanel({ onClose, responsive = false }: CommandPanelProps) {
  // 数据状态
  const [commands, setCommands] = useState<CommandItem[]>([]);
  const [filteredCommands, setFilteredCommands] = useState<CommandItem[]>([]);
  const [stats, setStats] = useState<{ total: number; bySource: Record<string, number> } | null>(
    null
  );

  // UI 状态
  const [loading, setLoading] = useState(true);
  const [searchQuery, setSearchQuery] = useState('');
  const [deletingCommand, setDeletingCommand] = useState<string | null>(null);
  const [reloading, setReloading] = useState(false);

  // 编辑器状态
  const [editorOpen, setEditorOpen] = useState(false);
  const [editingCommand, setEditingCommand] = useState<string | undefined>(undefined);

  // 加载命令列表
  const loadCommands = useCallback(async () => {
    setLoading(true);
    try {
      const result = await listCommands();
      if (result.success) {
        setCommands(result.data.commands);
        setFilteredCommands(result.data.commands);
        setStats(result.data.stats);
      } else {
        toast.error('Failed to load commands');
      }
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to load commands');
    } finally {
      setLoading(false);
    }
  }, []);

  // 初始加载
  useEffect(() => {
    loadCommands();
  }, [loadCommands]);

  // 搜索过滤
  useEffect(() => {
    if (!searchQuery.trim()) {
      setFilteredCommands(commands);
      return;
    }

    const query = searchQuery.toLowerCase();
    const filtered = commands.filter(
      (cmd) =>
        cmd.name.toLowerCase().includes(query) || cmd.description?.toLowerCase().includes(query)
    );
    setFilteredCommands(filtered);
  }, [searchQuery, commands]);

  // 删除命令
  const handleDelete = async (name: string) => {
    if (!confirm(`Are you sure you want to delete command "/${name}"?`)) {
      return;
    }

    setDeletingCommand(name);
    try {
      const result = await deleteCommand(name);
      if (result.success) {
        toast.success(`Command "/${name}" deleted`);
        loadCommands();
      } else {
        toast.error(result.error || 'Failed to delete command');
      }
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to delete command');
    } finally {
      setDeletingCommand(null);
    }
  };

  // 重新加载命令
  const handleReload = async () => {
    setReloading(true);
    try {
      const result = await reloadCommands();
      if (result.success) {
        toast.success('Commands reloaded');
        loadCommands();
      } else {
        toast.error('Failed to reload commands');
      }
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to reload commands');
    } finally {
      setReloading(false);
    }
  };

  // 打开编辑器（创建）
  const openCreateEditor = () => {
    setEditingCommand(undefined);
    setEditorOpen(true);
  };

  // 打开编辑器（编辑）
  const openEditEditor = (name: string) => {
    setEditingCommand(name);
    setEditorOpen(true);
  };

  // 编辑器保存回调
  const handleEditorSaved = () => {
    loadCommands();
  };

  // Loading 骨架屏
  const LoadingSkeleton = () => (
    <div className="space-y-3 p-4">
      {[1, 2, 3, 4, 5].map((i) => (
        <div key={i} className="flex items-center gap-3 p-3 bg-surface-base/50 rounded-lg">
          <Skeleton className="h-5 w-5 rounded" />
          <div className="flex-1 space-y-2">
            <Skeleton className="h-4 w-32" />
            <Skeleton className="h-3 w-48" />
          </div>
          <Skeleton className="h-8 w-16" />
        </div>
      ))}
    </div>
  );

  return (
    <>
      <AnimatePresence>
        <motion.div
          variants={modalOverlay}
          initial="initial"
          animate="animate"
          exit="exit"
          transition={{ duration: 0.2 }}
          className={cn(
            'fixed inset-0 bg-black/50 flex z-50',
            responsive
              ? 'items-end md:items-center justify-center'
              : 'items-center justify-center'
          )}
          onClick={onClose}
        >
          <motion.div
            variants={modalContent}
            initial="initial"
            animate="animate"
            exit="exit"
            transition={smoothTransition}
            onClick={(e) => e.stopPropagation()}
            className={cn(
              'bg-surface-subtle max-h-[90vh] overflow-hidden flex flex-col',
              responsive
                ? 'w-full md:w-full md:max-w-2xl md:mx-4 rounded-t-2xl md:rounded-lg'
                : 'rounded-lg w-full max-w-2xl mx-4'
            )}
          >
            {/* Header */}
            <div
              className={cn(
                'flex items-center justify-between border-b border-line',
                responsive ? 'px-4 md:px-6 py-4' : 'px-6 py-4'
              )}
            >
              {responsive && (
                <div className="absolute top-2 left-1/2 -translate-x-1/2 w-10 h-1 bg-surface-muted rounded-full md:hidden" />
              )}
              <div className={cn(responsive && 'mt-2 md:mt-0')}>
                <h2 className="text-lg font-semibold">Commands</h2>
                {stats && (
                  <p className="text-xs text-fg-subtle">
                    {stats.total} commands ({stats.bySource.builtin || 0} builtin,{' '}
                    {stats.bySource.user || 0} user, {stats.bySource.project || 0} project)
                  </p>
                )}
              </div>
              <Button
                variant="ghost"
                size="icon"
                onClick={onClose}
                className={cn(responsive && 'min-w-[44px] min-h-[44px]')}
              >
                <X size={20} />
              </Button>
            </div>

            {/* Toolbar */}
            <div
              className={cn(
                'flex items-center gap-3 border-b border-line',
                responsive ? 'px-4 md:px-6 py-3' : 'px-6 py-3'
              )}
            >
              <div className="flex-1 relative">
                <Search
                  size={16}
                  className="absolute left-3 top-1/2 -translate-y-1/2 text-fg-subtle"
                />
                <Input
                  value={searchQuery}
                  onChange={(e) => setSearchQuery(e.target.value)}
                  placeholder="Search commands..."
                  className="pl-9"
                />
              </div>
              <Button
                variant="ghost"
                size="icon"
                onClick={handleReload}
                disabled={reloading}
                title="Reload commands"
              >
                <RefreshCw size={18} className={cn(reloading && 'animate-spin')} />
              </Button>
              <Button onClick={openCreateEditor}>
                <Plus size={16} className="mr-1" />
                New
              </Button>
            </div>

            {/* Command List */}
            <div className="flex-1 overflow-y-auto">
              {loading ? (
                <LoadingSkeleton />
              ) : filteredCommands.length === 0 ? (
                <div className="flex flex-col items-center justify-center py-12 text-fg-subtle">
                  <Terminal size={48} className="mb-4 opacity-50" />
                  <p>
                    {searchQuery
                      ? `No commands matching "${searchQuery}"`
                      : 'No commands found'}
                  </p>
                  {!searchQuery && (
                    <Button variant="ghost" className="mt-4" onClick={openCreateEditor}>
                      <Plus size={16} className="mr-2" />
                      Create your first command
                    </Button>
                  )}
                </div>
              ) : (
                <motion.div
                  initial={{ opacity: 0 }}
                  animate={{ opacity: 1 }}
                  className={cn('space-y-2', responsive ? 'p-4' : 'p-4')}
                >
                  {filteredCommands.map((command) => (
                    <motion.div
                      key={command.name}
                      layout
                      initial={{ opacity: 0, y: 10 }}
                      animate={{ opacity: 1, y: 0 }}
                      exit={{ opacity: 0, y: -10 }}
                      className={cn(
                        'flex items-center gap-3 p-3 bg-surface-base/50 rounded-lg',
                        'hover:bg-surface-base/80 transition-colors group'
                      )}
                    >
                      {/* Icon */}
                      {getSourceIcon(command.source)}

                      {/* Info */}
                      <div className="flex-1 min-w-0">
                        <div className="flex items-center gap-2">
                          <span className="font-mono text-sm text-fg-secondary">/{command.name}</span>
                          <span
                            className={cn(
                              'px-1.5 py-0.5 text-xs rounded',
                              getSourceBadgeClass(command.source)
                            )}
                          >
                            {command.source}
                          </span>
                        </div>
                        {command.description && (
                          <p className="text-xs text-fg-subtle truncate mt-0.5">
                            {command.description}
                          </p>
                        )}
                      </div>

                      {/* Actions */}
                      <div className="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
                        <Button
                          variant="ghost"
                          size="icon"
                          className="h-8 w-8"
                          onClick={() => openEditEditor(command.name)}
                          title="Edit"
                        >
                          <Pencil size={14} />
                        </Button>
                        {command.source !== 'builtin' && (
                          <Button
                            variant="ghost"
                            size="icon"
                            className="h-8 w-8 text-red-400 hover:text-red-300 hover:bg-red-500/10"
                            onClick={() => handleDelete(command.name)}
                            disabled={deletingCommand === command.name}
                            title="Delete"
                          >
                            {deletingCommand === command.name ? (
                              <div className="animate-spin rounded-full h-3.5 w-3.5 border-t border-b border-red-400" />
                            ) : (
                              <Trash2 size={14} />
                            )}
                          </Button>
                        )}
                      </div>
                    </motion.div>
                  ))}
                </motion.div>
              )}
            </div>
          </motion.div>
        </motion.div>
      </AnimatePresence>

      {/* Command Editor */}
      {editorOpen && (
        <CommandEditor
          commandName={editingCommand}
          onClose={() => setEditorOpen(false)}
          onSaved={handleEditorSaved}
          responsive={responsive}
        />
      )}
    </>
  );
}
