/**
 * MCPPanel Component
 *
 * MCP 服务器管理面板：列出服务器状态、连接/断开、启用/禁用
 */

import { useState, useEffect, useCallback } from 'react';
import {
  X,
  RefreshCw,
  Plug,
  PlugZap,
  Power,
  PowerOff,
  ChevronDown,
  ChevronRight,
  Server,
  Globe,
  Wrench,
  AlertCircle,
} 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 { Skeleton } from './Skeleton';
import {
  listMCPServers,
  connectMCPServer,
  disconnectMCPServer,
  enableMCPServer,
  disableMCPServer,
  type MCPServerStatus,
} from '../api/client.js';

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

// 状态颜色映射
function getStatusColor(status: MCPServerStatus['status']) {
  switch (status) {
    case 'connected':
      return 'bg-green-500';
    case 'connecting':
      return 'bg-yellow-500 animate-pulse';
    case 'disconnected':
      return 'bg-surface-muted';
    case 'disabled':
      return 'bg-surface-emphasis';
    case 'error':
      return 'bg-red-500';
    default:
      return 'bg-surface-muted';
  }
}

// 状态文字
function getStatusText(status: MCPServerStatus['status']) {
  switch (status) {
    case 'connected':
      return 'Connected';
    case 'connecting':
      return 'Connecting...';
    case 'disconnected':
      return 'Disconnected';
    case 'disabled':
      return 'Disabled';
    case 'error':
      return 'Error';
    default:
      return status;
  }
}

// 类型图标
function getTypeIcon(type: 'local' | 'remote') {
  return type === 'local' ? (
    <Server size={14} className="text-blue-400" />
  ) : (
    <Globe size={14} className="text-purple-400" />
  );
}

export function MCPPanel({ onClose, responsive = false }: MCPPanelProps) {
  // 数据状态
  const [servers, setServers] = useState<MCPServerStatus[]>([]);
  const [expandedServers, setExpandedServers] = useState<Set<string>>(new Set());

  // UI 状态
  const [loading, setLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);
  const [actionLoading, setActionLoading] = useState<string | null>(null);

  // 加载服务器列表
  const loadServers = useCallback(async (showToast = false) => {
    try {
      const result = await listMCPServers();
      if (result.success) {
        setServers(result.data);
        if (showToast) {
          toast.success('Servers refreshed');
        }
      } else {
        toast.error(result.error || 'Failed to load servers');
      }
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to load servers');
    }
  }, []);

  // 初始加载
  useEffect(() => {
    setLoading(true);
    loadServers().finally(() => setLoading(false));
  }, [loadServers]);

  // 刷新
  const handleRefresh = async () => {
    setRefreshing(true);
    await loadServers(true);
    setRefreshing(false);
  };

  // 连接服务器
  const handleConnect = async (name: string) => {
    setActionLoading(name);
    try {
      const result = await connectMCPServer(name);
      if (result.success) {
        toast.success(`Server "${name}" connected`);
        await loadServers();
      } else {
        toast.error(result.error || 'Connection failed');
      }
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Connection failed');
    } finally {
      setActionLoading(null);
    }
  };

  // 断开服务器
  const handleDisconnect = async (name: string) => {
    setActionLoading(name);
    try {
      const result = await disconnectMCPServer(name);
      if (result.success) {
        toast.success(`Server "${name}" disconnected`);
        await loadServers();
      } else {
        toast.error(result.error || 'Disconnect failed');
      }
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Disconnect failed');
    } finally {
      setActionLoading(null);
    }
  };

  // 启用服务器
  const handleEnable = async (name: string) => {
    setActionLoading(name);
    try {
      const result = await enableMCPServer(name);
      if (result.success) {
        toast.success(`Server "${name}" enabled`);
        await loadServers();
      } else {
        toast.error(result.error || 'Enable failed');
      }
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Enable failed');
    } finally {
      setActionLoading(null);
    }
  };

  // 禁用服务器
  const handleDisable = async (name: string) => {
    setActionLoading(name);
    try {
      const result = await disableMCPServer(name);
      if (result.success) {
        toast.success(`Server "${name}" disabled`);
        await loadServers();
      } else {
        toast.error(result.error || 'Disable failed');
      }
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Disable failed');
    } finally {
      setActionLoading(null);
    }
  };

  // 切换展开
  const toggleExpanded = (name: string) => {
    const newExpanded = new Set(expandedServers);
    if (newExpanded.has(name)) {
      newExpanded.delete(name);
    } else {
      newExpanded.add(name);
    }
    setExpandedServers(newExpanded);
  };

  // 统计
  const connectedCount = servers.filter((s) => s.status === 'connected').length;
  const totalToolCount = servers.reduce((sum, s) => sum + s.toolCount, 0);

  // Loading 骨架屏
  const LoadingSkeleton = () => (
    <div className="space-y-3 p-4">
      {[1, 2, 3].map((i) => (
        <div key={i} className="flex items-center gap-3 p-3 bg-surface-base/50 rounded-lg">
          <Skeleton className="h-3 w-3 rounded-full" />
          <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-20" />
        </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-emphasis rounded-full md:hidden" />
            )}
            <div className={cn(responsive && 'mt-2 md:mt-0')}>
              <h2 className="text-lg font-semibold flex items-center gap-2">
                <Plug size={20} className="text-primary-400" />
                MCP Servers
              </h2>
              <p className="text-xs text-fg-subtle">
                {servers.length} servers ({connectedCount} connected, {totalToolCount} tools)
              </p>
            </div>
            <div className="flex items-center gap-2">
              <Button
                variant="ghost"
                size="icon"
                onClick={handleRefresh}
                disabled={refreshing}
                title="Refresh"
                className={cn(responsive && 'min-w-[44px] min-h-[44px]')}
              >
                <RefreshCw size={18} className={cn(refreshing && 'animate-spin')} />
              </Button>
              <Button
                variant="ghost"
                size="icon"
                onClick={onClose}
                className={cn(responsive && 'min-w-[44px] min-h-[44px]')}
              >
                <X size={20} />
              </Button>
            </div>
          </div>

          {/* Server List */}
          <div className="flex-1 overflow-y-auto">
            {loading ? (
              <LoadingSkeleton />
            ) : servers.length === 0 ? (
              <div className="flex flex-col items-center justify-center py-12 text-fg-subtle">
                <Plug size={48} className="mb-4 opacity-50" />
                <p className="text-center">No MCP servers configured</p>
                <p className="text-xs text-fg-subtle mt-2 text-center max-w-xs">
                  Configure MCP servers in your .ai-assist/config.json file
                </p>
              </div>
            ) : (
              <motion.div
                initial={{ opacity: 0 }}
                animate={{ opacity: 1 }}
                className={cn('space-y-2', responsive ? 'p-4' : 'p-4')}
              >
                {servers.map((server) => {
                  const isExpanded = expandedServers.has(server.name);
                  const isLoading = actionLoading === server.name;

                  return (
                    <motion.div
                      key={server.name}
                      layout
                      initial={{ opacity: 0, y: 10 }}
                      animate={{ opacity: 1, y: 0 }}
                      className="bg-surface-base/50 rounded-lg overflow-hidden"
                    >
                      {/* Server Header */}
                      <div
                        className={cn(
                          'flex items-center gap-3 p-3',
                          'hover:bg-surface-base/80 transition-colors cursor-pointer'
                        )}
                        onClick={() => toggleExpanded(server.name)}
                      >
                        {/* Expand Icon */}
                        <button className="text-fg-subtle hover:text-fg-secondary">
                          {isExpanded ? <ChevronDown size={16} /> : <ChevronRight size={16} />}
                        </button>

                        {/* Status Indicator */}
                        <div className={cn('w-2.5 h-2.5 rounded-full', getStatusColor(server.status))} />

                        {/* Type Icon */}
                        {getTypeIcon(server.type)}

                        {/* Info */}
                        <div className="flex-1 min-w-0">
                          <div className="flex items-center gap-2">
                            <span className="font-medium text-fg-secondary">{server.name}</span>
                            <span className="text-xs text-fg-subtle">{server.type}</span>
                          </div>
                          <div className="flex items-center gap-2 text-xs text-fg-subtle">
                            <span>{getStatusText(server.status)}</span>
                            {server.toolCount > 0 && (
                              <>
                                <span>·</span>
                                <span className="flex items-center gap-1">
                                  <Wrench size={10} />
                                  {server.toolCount} tools
                                </span>
                              </>
                            )}
                          </div>
                        </div>

                        {/* Actions */}
                        <div
                          className="flex items-center gap-1"
                          onClick={(e) => e.stopPropagation()}
                        >
                          {isLoading ? (
                            <div className="animate-spin rounded-full h-5 w-5 border-t-2 border-b-2 border-primary-500" />
                          ) : server.status === 'disabled' ? (
                            <Button
                              variant="ghost"
                              size="sm"
                              onClick={() => handleEnable(server.name)}
                              className="text-green-400 hover:text-green-300"
                            >
                              <Power size={14} className="mr-1" />
                              Enable
                            </Button>
                          ) : server.status === 'connected' ? (
                            <>
                              <Button
                                variant="ghost"
                                size="sm"
                                onClick={() => handleDisconnect(server.name)}
                                className="text-yellow-400 hover:text-yellow-300"
                              >
                                <PlugZap size={14} className="mr-1" />
                                Disconnect
                              </Button>
                              <Button
                                variant="ghost"
                                size="sm"
                                onClick={() => handleDisable(server.name)}
                                className="text-red-400 hover:text-red-300"
                              >
                                <PowerOff size={14} className="mr-1" />
                                Disable
                              </Button>
                            </>
                          ) : server.status === 'disconnected' || server.status === 'error' ? (
                            <Button
                              variant="ghost"
                              size="sm"
                              onClick={() => handleConnect(server.name)}
                              className="text-blue-400 hover:text-blue-300"
                            >
                              <PlugZap size={14} className="mr-1" />
                              Connect
                            </Button>
                          ) : null}
                        </div>
                      </div>

                      {/* Expanded Content */}
                      <AnimatePresence>
                        {isExpanded && (
                          <motion.div
                            initial={{ height: 0, opacity: 0 }}
                            animate={{ height: 'auto', opacity: 1 }}
                            exit={{ height: 0, opacity: 0 }}
                            transition={{ duration: 0.2 }}
                            className="overflow-hidden"
                          >
                            <div className="px-4 pb-3 pt-1 border-t border-line/50">
                              {/* Error Message */}
                              {server.error && (
                                <div className="flex items-start gap-2 p-2 bg-red-500/10 rounded text-red-400 text-xs mb-2">
                                  <AlertCircle size={14} className="mt-0.5 flex-shrink-0" />
                                  <span>{server.error}</span>
                                </div>
                              )}

                              {/* Config Info */}
                              {server.config && (
                                <div className="space-y-1 text-xs text-fg-subtle">
                                  {server.config.command && (
                                    <div>
                                      <span className="text-fg-muted">Command:</span>{' '}
                                      <code className="font-mono bg-surface-subtle px-1 rounded">
                                        {server.config.command.join(' ')}
                                      </code>
                                    </div>
                                  )}
                                  {server.config.url && (
                                    <div>
                                      <span className="text-fg-muted">URL:</span>{' '}
                                      <code className="font-mono bg-surface-subtle px-1 rounded">
                                        {server.config.url}
                                      </code>
                                    </div>
                                  )}
                                  {server.config.timeout && (
                                    <div>
                                      <span className="text-fg-muted">Timeout:</span>{' '}
                                      {server.config.timeout}ms
                                    </div>
                                  )}
                                </div>
                              )}

                              {/* Tools List */}
                              {server.tools && server.tools.length > 0 && (
                                <div className="mt-3">
                                  <div className="text-xs text-fg-muted mb-1">Tools:</div>
                                  <div className="flex flex-wrap gap-1">
                                    {server.tools.map((tool) => (
                                      <span
                                        key={tool.name}
                                        className="px-2 py-0.5 bg-surface-subtle rounded text-xs text-fg-secondary"
                                        title={tool.description}
                                      >
                                        {tool.originalName}
                                      </span>
                                    ))}
                                  </div>
                                </div>
                              )}
                            </div>
                          </motion.div>
                        )}
                      </AnimatePresence>
                    </motion.div>
                  );
                })}
              </motion.div>
            )}
          </div>

          {/* Footer Info */}
          <div
            className={cn(
              'border-t border-line text-xs text-fg-subtle text-center',
              responsive ? 'px-4 py-3 safe-area-pb' : 'px-6 py-3'
            )}
          >
            Configure servers in <code className="font-mono bg-surface-base px-1 rounded">.ai-assist/config.json</code>
          </div>
        </motion.div>
      </motion.div>
    </AnimatePresence>
  );
}
