import React, { useState, useCallback, useEffect } from 'react';
import axios from 'axios';
import {
  EyeIcon,
  WrenchScrewdriverIcon,
  StarIcon,
  ArrowPathIcon,
  PencilIcon,
  ClockIcon,
  CheckCircleIcon,
  XCircleIcon,
  QuestionMarkCircleIcon,
  CogIcon,
  LinkIcon,
  ShieldCheckIcon,
  ShieldExclamationIcon,
  TrashIcon,
  InformationCircleIcon,
} from '@heroicons/react/24/outline';
import ServerConfigModal from './ServerConfigModal';
import SecurityScanModal from './SecurityScanModal';
import StarRatingWidget from './StarRatingWidget';
import VersionBadge from './VersionBadge';
import VersionSelectorModal from './VersionSelectorModal';
import DeleteConfirmation from './DeleteConfirmation';
import ConfirmModal from './ConfirmModal';
import StatusBadge from './StatusBadge';
import { ANSBadge } from './ANSBadge';
import ServerDetailsModal from './ServerDetailsModal';
import useEscapeKey from '../hooks/useEscapeKey';
import { formatRelativeTime } from '../utils/dateUtils';
import { normalizeHealthStatus } from '../utils/healthStatus';
import { useAuth } from '../contexts/AuthContext';
import type { LocalRuntime } from '../types/server';

interface ServerVersion {
  version: string;
  proxy_pass_url: string;
  status: string;
  is_default: boolean;
  released?: string;
  sunset_date?: string;
  description?: string;
}

interface SyncMetadata {
  is_federated?: boolean;
  source_peer_id?: string;
  upstream_path?: string;
  last_synced_at?: string;
  is_read_only?: boolean;
  is_orphaned?: boolean;
  orphaned_at?: string;
}

export interface Server {
  name: string;
  path: string;
  description?: string;
  official?: boolean;
  enabled: boolean;
  tags?: string[];
  last_checked_time?: string;
  usersCount?: number;
  rating_details?: Array<{ user: string; rating: number }>;
  status?: 'healthy' | 'healthy-auth-expired' | 'unhealthy' | 'unknown' | 'local';
  num_tools?: number;
  proxy_pass_url?: string;
  mcp_endpoint?: string;
  // Local-server fields
  deployment?: 'remote' | 'local';
  local_runtime?: LocalRuntime;
  registered_by?: string | null;
  // Version routing fields
  version?: string;  // Current active version
  versions?: ServerVersion[];
  default_version?: string;
  // MCP server info from initialize response
  mcp_server_version?: string;
  mcp_server_version_previous?: string;
  mcp_server_version_updated_at?: string;
  // Federation sync metadata
  sync_metadata?: SyncMetadata;
  // Backend authentication
  auth_scheme?: string;
  auth_header_name?: string;
  custom_header_names?: string[];
  // Lifecycle status
  lifecycle_status?: 'active' | 'deprecated' | 'draft' | 'beta';
  source_created_at?: string;
  source_updated_at?: string;
  // ANS Integration
  ans_metadata?: {
    ans_agent_id: string;
    status: 'verified' | 'expired' | 'revoked' | 'not_found' | 'pending';
    domain?: string;
    organization?: string;
    certificate?: {
      not_after?: string;
      subject_dn?: string;
      issuer_dn?: string;
    };
    last_verified?: string;
  };
}

interface ServerCardProps {
  server: Server;
  onToggle: (path: string, enabled: boolean) => void;
  onEdit?: (server: Server) => void;
  canModify?: boolean;
  canHealthCheck?: boolean;
  canToggle?: boolean;
  canDelete?: boolean;
  onRefreshSuccess?: () => void;
  onShowToast?: (message: string, type: 'success' | 'error') => void;
  onServerUpdate?: (path: string, updates: Partial<Server>) => void;
  onDelete?: (path: string) => Promise<void>;
  authToken?: string | null;
}

interface Tool {
  name: string;
  description?: string;
  schema?: any;
}

// Helper function to format time since last checked
const formatTimeSince = (timestamp: string | null | undefined): string | null => {
  if (!timestamp) {
    return null;
  }
  
  try {
    const now = new Date();
    const lastChecked = new Date(timestamp);
    
    // Check if the date is valid
    if (isNaN(lastChecked.getTime())) {
      return null;
    }
    
    const diffMs = now.getTime() - lastChecked.getTime();
    
    const diffSeconds = Math.floor(diffMs / 1000);
    const diffMinutes = Math.floor(diffSeconds / 60);
    const diffHours = Math.floor(diffMinutes / 60);
    const diffDays = Math.floor(diffHours / 24);
    
    let result;
    if (diffSeconds < 0) {
      result = 'just now';
    } else if (diffDays > 0) {
      result = `${diffDays}d ago`;
    } else if (diffHours > 0) {
      result = `${diffHours}h ago`;
    } else if (diffMinutes > 0) {
      result = `${diffMinutes}m ago`;
    } else {
      result = `${diffSeconds}s ago`;
    }
    
    return result;
  } catch (error) {
    console.error('formatTimeSince error:', error, 'for timestamp:', timestamp);
    return null;
  }
};

const ServerCard: React.FC<ServerCardProps> = React.memo(({ server, onToggle, onEdit, canModify, canHealthCheck = true, canToggle = true, canDelete, onRefreshSuccess, onShowToast, onServerUpdate, onDelete, authToken }) => {
  const { user } = useAuth();
  const isAdmin = user?.is_admin === true;
  const [tools, setTools] = useState<Tool[]>([]);
  const [loadingTools, setLoadingTools] = useState(false);
  const [showTools, setShowTools] = useState(false);
  const [showConfig, setShowConfig] = useState(false);
  const [loadingRefresh, setLoadingRefresh] = useState(false);
  const [showSecurityScan, setShowSecurityScan] = useState(false);
  const [securityScanResult, setSecurityScanResult] = useState<any>(null);
  const [loadingSecurityScan, setLoadingSecurityScan] = useState(false);
  const [showVersionSelector, setShowVersionSelector] = useState(false);
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
  const [showDetails, setShowDetails] = useState(false);
  const [expandedDescriptions, setExpandedDescriptions] = useState<Set<number>>(new Set());
  const [showClearSecurityPendingConfirm, setShowClearSecurityPendingConfirm] = useState(false);
  const [clearingSecurityPending, setClearingSecurityPending] = useState(false);

  const closeToolsModal = useCallback(() => {
    setShowTools(false);
    setExpandedDescriptions(new Set());
  }, []);
  useEscapeKey(closeToolsModal, showTools);
  useEscapeKey(() => setShowDeleteConfirm(false), showDeleteConfirm);

  // Fetch security scan status on mount to show correct icon color.
  // Local (stdio) servers are never auto-scanned (no HTTP endpoint to probe);
  // skip the request — it would 404 anyway.
  useEffect(() => {
    if (server.deployment === 'local') return;
    const fetchSecurityScan = async () => {
      try {
        const headers = authToken ? { Authorization: `Bearer ${authToken}` } : undefined;
        const response = await axios.get(
          `/api/servers${server.path}/security-scan`,
          headers ? { headers } : undefined
        );
        setSecurityScanResult(response.data);
      } catch {
        // Silently ignore - no scan result available
      }
    };
    fetchSecurityScan();
  }, [server.path, server.deployment, authToken]);

  const getStatusIcon = () => {
    // Local servers: registry doesn't health-check, so show a neutral indicator.
    if (server.deployment === 'local' || server.status === 'local') {
      return <span className="text-emerald-500 text-xs font-mono">stdio</span>;
    }
    switch (server.status) {
      case 'healthy':
        return <CheckCircleIcon className="h-4 w-4 text-green-500" />;
      case 'healthy-auth-expired':
        return <CheckCircleIcon className="h-4 w-4 text-orange-500" />;
      case 'unhealthy':
        return <XCircleIcon className="h-4 w-4 text-red-500" />;
      default:
        return <QuestionMarkCircleIcon className="h-4 w-4 text-gray-400" />;
    }
  };

  const getStatusColor = () => {
    if (server.deployment === 'local' || server.status === 'local') {
      return 'bg-emerald-100 text-emerald-800 dark:bg-emerald-900/30 dark:text-emerald-400';
    }
    switch (server.status) {
      case 'healthy':
        return 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400';
      case 'healthy-auth-expired':
        return 'bg-orange-100 text-orange-800 dark:bg-orange-900/30 dark:text-orange-400';
      case 'unhealthy':
        return 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400';
      default:
        return 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200';
    }
  };

  const handleViewTools = useCallback(async () => {
    if (loadingTools) return;
    
    setLoadingTools(true);
    try {
      const response = await axios.get(`/api/tools${server.path}`);
      setTools(response.data.tools || []);
      setShowTools(true);
    } catch (error) {
      console.error('Failed to fetch tools:', error);
      if (onShowToast) {
        onShowToast('Failed to fetch tools', 'error');
      }
    } finally {
      setLoadingTools(false);
    }
  }, [server.path, loadingTools, onShowToast]);

  const handleRefreshHealth = useCallback(async () => {
    if (loadingRefresh) return;
    
    setLoadingRefresh(true);
    try {
      // Extract service name from path (remove leading slash)
      const serviceName = server.path.replace(/^\//, '');
      
      const response = await axios.post(`/api/refresh/${serviceName}`);
      
      // Update just this server instead of triggering global refresh
      if (onServerUpdate && response.data) {
        const updates: Partial<Server> = {
          status: normalizeHealthStatus(response.data.status),
          last_checked_time: response.data.last_checked_iso,
          num_tools: response.data.num_tools
        };
        
        onServerUpdate(server.path, updates);
      } else if (onRefreshSuccess) {
        // Fallback to global refresh if onServerUpdate is not provided
        onRefreshSuccess();
      }
      
      if (onShowToast) {
        onShowToast('Health status refreshed successfully', 'success');
      }
    } catch (error: any) {
      console.error('Failed to refresh health:', error);
      if (onShowToast) {
        onShowToast(error.response?.data?.detail || 'Failed to refresh health status', 'error');
      }
    } finally {
      setLoadingRefresh(false);
    }
  }, [server.path, loadingRefresh, onRefreshSuccess, onShowToast, onServerUpdate]);

  const handleViewSecurityScan = useCallback(async () => {
    if (loadingSecurityScan) return;

    setShowSecurityScan(true);
    setLoadingSecurityScan(true);
    try {
      const headers = authToken ? { Authorization: `Bearer ${authToken}` } : undefined;
      const response = await axios.get(
        `/api/servers${server.path}/security-scan`,
        headers ? { headers } : undefined
      );
      setSecurityScanResult(response.data);
    } catch (error: any) {
      if (error.response?.status !== 404) {
        console.error('Failed to fetch security scan:', error);
        if (onShowToast) {
          onShowToast('Failed to load security scan results', 'error');
        }
      }
      setSecurityScanResult(null);
    } finally {
      setLoadingSecurityScan(false);
    }
  }, [server.path, authToken, loadingSecurityScan, onShowToast]);

  const handleRescan = useCallback(async () => {
    const headers = authToken ? { Authorization: `Bearer ${authToken}` } : undefined;
    const response = await axios.post(
      `/api/servers${server.path}/rescan`,
      undefined,
      headers ? { headers } : undefined
    );
    setSecurityScanResult(response.data);
  }, [server.path, authToken]);

  const handleRefreshServerData = useCallback(async () => {
    try {
      const headers = authToken ? { Authorization: `Bearer ${authToken}` } : undefined;
      const response = await axios.get(
        `/api/server_details${server.path}`,
        headers ? { headers } : undefined
      );

      if (onServerUpdate && response.data) {
        const serverData = response.data;
        const updates: Partial<Server> = {
          name: serverData.server_name,
          description: serverData.description,
          enabled: serverData.is_enabled,
          tags: serverData.tags,
          status: normalizeHealthStatus(serverData.health_status),
          last_checked_time: serverData.last_checked_iso,
          num_tools: serverData.num_tools,
          proxy_pass_url: serverData.proxy_pass_url,
          mcp_endpoint: serverData.mcp_endpoint,
          version: serverData.version,
          versions: serverData.versions,
          default_version: serverData.default_version,
          mcp_server_version: serverData.mcp_server_version,
          mcp_server_version_previous: serverData.mcp_server_version_previous,
          mcp_server_version_updated_at: serverData.mcp_server_version_updated_at,
        };
        onServerUpdate(server.path, updates);
      }
    } catch (error) {
      console.error('Failed to refresh server data:', error);
    }
  }, [server.path, authToken, onServerUpdate]);

  const handleClearSecurityPending = useCallback(async () => {
    if (clearingSecurityPending) return;
    setClearingSecurityPending(true);
    try {
      const cleanPath = server.path.replace(/^\/+/, '');
      await axios.post(`/api/clear-security-pending-local/${cleanPath}`);
      onShowToast?.('Marked as security-reviewed', 'success');
      if (onServerUpdate) {
        onServerUpdate(server.path, {
          tags: (server.tags || []).filter(t => t !== 'security-pending-local'),
        });
      }
      setShowClearSecurityPendingConfirm(false);
    } catch (err: unknown) {
      const e = err as { response?: { data?: { detail?: string } } };
      onShowToast?.(e.response?.data?.detail || 'Failed to clear tag', 'error');
    } finally {
      setClearingSecurityPending(false);
    }
  }, [server.path, server.tags, clearingSecurityPending, onServerUpdate, onShowToast]);

  const getSecurityIconState = () => {
    // Local (stdio) servers can't be auto-scanned. Their security state is
    // signalled by the security-pending-local tag instead:
    //   tag present  → amber (admin manual review still owed)
    //   tag absent   → green (admin has reviewed and cleared)
    if (server.deployment === 'local') {
      if (server.tags?.includes('security-pending-local')) {
        return {
          Icon: ShieldExclamationIcon,
          color: 'text-amber-500 dark:text-amber-400',
          title: 'Pending manual security review (local server)',
        };
      }
      return {
        Icon: ShieldCheckIcon,
        color: 'text-green-500 dark:text-green-400',
        title: 'Local server marked as security-reviewed',
      };
    }

    // Gray: no scan result yet
    if (!securityScanResult) {
      return { Icon: ShieldCheckIcon, color: 'text-gray-400 dark:text-gray-500', title: 'View security scan results' };
    }
    // Red: scan failed or any vulnerabilities found
    if (securityScanResult.scan_failed) {
      return { Icon: ShieldExclamationIcon, color: 'text-red-500 dark:text-red-400', title: 'Security scan failed' };
    }
    const hasVulnerabilities = securityScanResult.critical_issues > 0 ||
      securityScanResult.high_severity > 0 ||
      securityScanResult.medium_severity > 0 ||
      securityScanResult.low_severity > 0;
    if (hasVulnerabilities) {
      return { Icon: ShieldExclamationIcon, color: 'text-red-500 dark:text-red-400', title: 'Security issues found' };
    }
    // Green: scan passed with no vulnerabilities
    return { Icon: ShieldCheckIcon, color: 'text-green-500 dark:text-green-400', title: 'Security scan passed' };
  };

  // Generate MCP configuration for the server
  // Check if this is an Anthropic registry server
  const isAnthropicServer = server.tags?.includes('anthropic-registry');

  // Check if this server has security pending
  const isSecurityPending = server.tags?.includes('security-pending');
  const isSecurityPendingLocal = server.tags?.includes('security-pending-local');

  // Local (stdio) deployment — no HTTP endpoint, so health/scan paths skip it.
  const isLocal = server.deployment === 'local';

  // Check if this is a federated server from a peer registry using sync_metadata
  const isFederatedServer = server.sync_metadata?.is_federated === true;
  const peerRegistryId = isFederatedServer && server.sync_metadata?.source_peer_id
    ? server.sync_metadata.source_peer_id
    : null;

  // Check if this server is orphaned (no longer exists on peer registry)
  const isOrphanedServer = server.sync_metadata?.is_orphaned === true;

  return (
    <>
      <div className={`group rounded-2xl shadow-sm hover:shadow-xl transition-all duration-300 h-full flex flex-col ${
        isAnthropicServer 
          ? 'bg-gradient-to-br from-purple-50 to-indigo-50 dark:from-purple-900/20 dark:to-indigo-900/20 border-2 border-purple-200 dark:border-purple-700 hover:border-purple-300 dark:hover:border-purple-600'
          : 'bg-white dark:bg-gray-800 border border-gray-100 dark:border-gray-700 hover:border-gray-200 dark:hover:border-gray-600'
      }`}>
        {/* Render DeleteConfirmation inline when showDeleteConfirm is true */}
        {showDeleteConfirm ? (
          <div className="p-5 h-full flex flex-col justify-center">
            <DeleteConfirmation
              entityType="server"
              entityName={server.name || server.path.replace(/^\//, '')}
              entityPath={server.path}
              onConfirm={onDelete!}
              onCancel={() => setShowDeleteConfirm(false)}
            />
          </div>
        ) : (
        <>
        {/* Header */}
        <div className="p-5 pb-4">
          <div className="flex items-start justify-between mb-4">
            <div className="flex-1 min-w-0">
              <div className="flex items-center gap-2 mb-3 flex-wrap">
                <h3 className="text-lg font-bold text-gray-900 dark:text-white truncate min-w-[120px]">
                  {server.name}
                </h3>
                {server.lifecycle_status && server.lifecycle_status !== 'active' && (
                  <StatusBadge status={server.lifecycle_status} />
                )}
                {server.deployment === 'local' && (
                  <span
                    className="px-2 py-0.5 text-xs font-semibold bg-gradient-to-r from-emerald-100 to-teal-100 text-emerald-700 dark:from-emerald-900/30 dark:to-teal-900/30 dark:text-emerald-300 rounded-full flex-shrink-0 border border-emerald-200 dark:border-emerald-600"
                    title="Local (stdio) — runs on your machine via launch recipe"
                  >
                    LOCAL
                  </span>
                )}
                {server.official && (
                  <span className="px-2 py-0.5 text-xs font-semibold bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-300 rounded-full flex-shrink-0">
                    OFFICIAL
                  </span>
                )}
                {isAnthropicServer && (
                  <span className="px-2 py-0.5 text-xs font-semibold bg-gradient-to-r from-purple-100 to-indigo-100 text-purple-700 dark:from-purple-900/30 dark:to-indigo-900/30 dark:text-purple-300 rounded-full flex-shrink-0 border border-purple-200 dark:border-purple-600">
                    ANTHROPIC
                  </span>
                )}
                {/* Check if this is an ASOR server */}
                {server.tags?.includes('asor') && (
                  <span className="px-2 py-0.5 text-xs font-semibold bg-gradient-to-r from-orange-100 to-red-100 text-orange-700 dark:from-orange-900/30 dark:to-red-900/30 dark:text-orange-300 rounded-full flex-shrink-0 border border-orange-200 dark:border-orange-600">
                    ASOR
                  </span>
                )}
                {isSecurityPending && (
                  <span className="px-2 py-0.5 text-xs font-semibold bg-gradient-to-r from-amber-100 to-orange-100 text-amber-700 dark:from-amber-900/30 dark:to-orange-900/30 dark:text-amber-300 rounded-full flex-shrink-0 border border-amber-200 dark:border-amber-600">
                    SECURITY PENDING
                  </span>
                )}
                {isSecurityPendingLocal && (
                  isAdmin ? (
                    <button
                      type="button"
                      onClick={() => setShowClearSecurityPendingConfirm(true)}
                      className="px-2 py-0.5 text-xs font-semibold bg-gradient-to-r from-amber-100 to-orange-100 text-amber-700 dark:from-amber-900/30 dark:to-orange-900/30 dark:text-amber-300 rounded-full flex-shrink-0 border border-amber-200 dark:border-amber-600 hover:from-amber-200 hover:to-orange-200 transition"
                      title="Click to mark as security-reviewed (admin only)"
                    >
                      SECURITY PENDING (LOCAL) ×
                    </button>
                  ) : (
                    <span
                      className="px-2 py-0.5 text-xs font-semibold bg-gradient-to-r from-amber-100 to-orange-100 text-amber-700 dark:from-amber-900/30 dark:to-orange-900/30 dark:text-amber-300 rounded-full flex-shrink-0 border border-amber-200 dark:border-amber-600"
                      title="Pending security review by an admin (local server)"
                    >
                      SECURITY PENDING (LOCAL)
                    </span>
                  )
                )}
                {/* ANS badge moved to trust bar below description */}
                {/* Registry source badge - only show for federated (peer registry) items */}
                {isFederatedServer && (
                  <span className="px-2 py-0.5 text-xs font-semibold bg-gradient-to-r from-cyan-100 to-blue-100 text-cyan-700 dark:from-cyan-900/30 dark:to-blue-900/30 dark:text-cyan-300 rounded-full flex-shrink-0 border border-cyan-200 dark:border-cyan-600" title={`Synced from ${peerRegistryId}`}>
                    {peerRegistryId?.toUpperCase().replace('PEER-REGISTRY-', '').replace('PEER-', '')}
                  </span>
                )}
                {/* Orphaned badge - server no longer exists on peer registry */}
                {isOrphanedServer && (
                  <span className="px-2 py-0.5 text-xs font-semibold bg-gradient-to-r from-red-100 to-rose-100 text-red-700 dark:from-red-900/30 dark:to-rose-900/30 dark:text-red-300 rounded-full flex-shrink-0 border border-red-200 dark:border-red-600" title="No longer exists on peer registry">
                    ORPHANED
                  </span>
                )}
                {/* Backend auth scheme badge */}
                {server.auth_scheme && server.auth_scheme !== 'none' && server.auth_scheme === 'bearer' && (
                  <span className="px-2 py-0.5 text-xs font-semibold bg-gradient-to-r from-blue-100 to-indigo-100 text-blue-700 dark:from-blue-900/30 dark:to-indigo-900/30 dark:text-blue-300 rounded-full flex-shrink-0 border border-blue-200 dark:border-blue-600" title="Backend uses Bearer token authentication">
                    BEARER AUTH
                  </span>
                )}
                {server.auth_scheme && server.auth_scheme === 'api_key' && (
                  <span className="px-2 py-0.5 text-xs font-semibold bg-gradient-to-r from-yellow-100 to-amber-100 text-yellow-700 dark:from-yellow-900/30 dark:to-amber-900/30 dark:text-yellow-300 rounded-full flex-shrink-0 border border-yellow-200 dark:border-yellow-600" title={`Backend uses API Key authentication (header: ${server.auth_header_name || 'X-API-Key'})`}>
                    API KEY AUTH
                  </span>
                )}
              </div>
              
              <code className="text-xs text-gray-600 dark:text-gray-300 bg-gray-50 dark:bg-gray-800/50 px-2 py-1 rounded font-mono">
                {server.path}
              </code>
            </div>

            {canModify && (
              <button
                className="p-2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700/50 rounded-lg transition-all duration-200 flex-shrink-0"
                onClick={() => onEdit?.(server)}
                title="Edit server"
                aria-label={`Edit ${server.name}`}
              >
                <PencilIcon className="h-4 w-4" />
              </button>
            )}

            {/* Connect Button */}
            <button
              onClick={() => setShowConfig(true)}
              className="flex items-center gap-1 px-2 py-1.5 text-xs font-medium text-green-600 dark:text-green-400 hover:bg-green-50 dark:hover:bg-green-700/50 rounded-lg transition-all duration-200 flex-shrink-0 border border-green-200 dark:border-green-700"
              title="Get connection details and mcp.json configuration"
              aria-label={`Connect to ${server.name}`}
            >
              <LinkIcon className="h-3.5 w-3.5" />
              Connect
            </button>

            {/* Security Scan Button */}
            <button
              onClick={handleViewSecurityScan}
              className={`p-2 hover:bg-gray-50 dark:hover:bg-gray-700/50 rounded-lg transition-all duration-200 flex-shrink-0 ${getSecurityIconState().color}`}
              title={getSecurityIconState().title}
              aria-label="View security scan results"
            >
              {React.createElement(getSecurityIconState().Icon, { className: "h-4 w-4" })}
            </button>

            {/* Delete Button */}
            {canDelete && (
              <button
                onClick={() => setShowDeleteConfirm(true)}
                className="p-2 text-gray-400 hover:text-red-600 dark:hover:text-red-400 hover:bg-red-50 dark:hover:bg-red-700/50 rounded-lg transition-all duration-200 flex-shrink-0"
                title="Delete server"
                aria-label={`Delete ${server.name}`}
              >
                <TrashIcon className="h-4 w-4" />
              </button>
            )}
          </div>

          {/* Description */}
          <p className="text-gray-600 dark:text-gray-300 text-sm leading-relaxed line-clamp-2 mb-4">
            {server.description || 'No description available'}
          </p>

          {/* ANS Trust Bar */}
          {server.ans_metadata && (
            <div className="mb-4 p-2.5 rounded-lg bg-gray-50/80 dark:bg-gray-800/50 border border-gray-200/60 dark:border-gray-700/60 flex items-center gap-3">
              <ANSBadge ansMetadata={server.ans_metadata} compact />
              <span className="text-xs text-gray-500 dark:text-gray-400 truncate">
                {server.ans_metadata.domain || server.ans_metadata.ans_agent_id}
              </span>
            </div>
          )}

          {/* Tags */}
          {server.tags && server.tags.length > 0 && (
            <div className="flex flex-wrap gap-1.5 mb-4">
              {server.tags.slice(0, 3).map((tag) => (
                <span
                  key={tag}
                  className="px-2 py-1 text-xs font-medium bg-blue-50 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 rounded"
                >
                  #{tag}
                </span>
              ))}
              {server.tags.length > 3 && (
                <span className="px-2 py-1 text-xs font-medium bg-gray-50 dark:bg-gray-800 text-gray-600 dark:text-gray-300 rounded">
                  +{server.tags.length - 3}
                </span>
              )}
            </div>
          )}
        </div>

        {/* Stats */}
        <div className="px-5 pb-4">
          <div className="grid grid-cols-3 gap-4">
            <StarRatingWidget
              resourceType="servers"
              path={server.path}
              initialRating={0}
              initialCount={server.rating_details?.length || 0}
              authToken={authToken}
              onShowToast={onShowToast}
            />
            <div className="flex items-center gap-2">
              {(server.num_tools || 0) > 0 ? (
                <button
                  onClick={handleViewTools}
                  disabled={loadingTools}
                  className="flex items-center gap-2 text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300 disabled:opacity-50 hover:bg-blue-50 dark:hover:bg-blue-900/20 px-2 py-1 -mx-2 -my-1 rounded transition-all"
                  title="View tools"
                >
                  <div className="p-1.5 bg-blue-50 dark:bg-blue-900/30 rounded">
                    <WrenchScrewdriverIcon className="h-4 w-4" />
                  </div>
                  <div>
                    <div className="text-sm font-semibold">{server.num_tools}</div>
                    <div className="text-xs">Tools</div>
                  </div>
                </button>
              ) : (
                <div className="flex items-center gap-2 text-gray-400 dark:text-gray-500">
                  <div className="p-1.5 bg-gray-50 dark:bg-gray-800 rounded">
                    <WrenchScrewdriverIcon className="h-4 w-4" />
                  </div>
                  <div>
                    <div className="text-sm font-semibold">{server.num_tools || 0}</div>
                    <div className="text-xs">Tools</div>
                  </div>
                </div>
              )}
            </div>
            {/* Version display - user routing version and/or MCP server version */}
            <div className="flex flex-col items-end gap-1">
              {server.versions && server.versions.length > 1 && (
                <VersionBadge
                  versions={server.versions}
                  defaultVersion={server.default_version || server.version}
                  onClick={() => setShowVersionSelector(true)}
                />
              )}
              {server.mcp_server_version && (
                <span
                  className="inline-flex items-center px-2 py-0.5 text-xs font-medium bg-gray-50 text-gray-600 dark:bg-gray-800 dark:text-gray-400 rounded"
                  title={
                    server.mcp_server_version_previous
                      ? `MCP Server Version: ${server.mcp_server_version} (previously ${server.mcp_server_version_previous})`
                      : `MCP Server Version: ${server.mcp_server_version}`
                  }
                >
                  <span className="text-gray-400 dark:text-gray-500 mr-1">srv</span>
                  {server.mcp_server_version}
                  {server.mcp_server_version_updated_at &&
                    (Date.now() - new Date(server.mcp_server_version_updated_at).getTime()) < 24 * 60 * 60 * 1000 && (
                    <span className="ml-1 h-1.5 w-1.5 rounded-full bg-green-500 inline-block" title="Recently updated" />
                  )}
                </span>
              )}
            </div>
          </div>
        </div>

        {/* Footer */}
        <div className="mt-auto px-5 py-4 border-t border-gray-100 dark:border-gray-700 bg-gray-50/50 dark:bg-gray-900/30 rounded-b-2xl">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-4">
              {/* Status Indicators */}
              <div className="flex items-center gap-2">
                <div className={`w-3 h-3 rounded-full ${
                  server.enabled 
                    ? 'bg-green-400 shadow-lg shadow-green-400/30' 
                    : 'bg-gray-300 dark:bg-gray-600'
                }`} />
                <span className="text-sm font-medium text-gray-700 dark:text-gray-300">
                  {server.enabled ? 'Enabled' : 'Disabled'}
                </span>
              </div>
              
              <div className="w-px h-4 bg-gray-200 dark:bg-gray-600" />
              
              <div className="flex items-center gap-2">
                <div className={`w-3 h-3 rounded-full ${
                  isLocal
                    ? 'bg-emerald-400 shadow-lg shadow-emerald-400/30'
                    : server.status === 'healthy'
                    ? 'bg-emerald-400 shadow-lg shadow-emerald-400/30'
                    : server.status === 'healthy-auth-expired'
                    ? 'bg-orange-400 shadow-lg shadow-orange-400/30'
                    : server.status === 'unhealthy'
                    ? 'bg-red-400 shadow-lg shadow-red-400/30'
                    : 'bg-amber-400 shadow-lg shadow-amber-400/30'
                }`} />
                <span
                  className="text-sm font-medium text-gray-700 dark:text-gray-300"
                  title={
                    isLocal
                      ? 'Runs on the developer’s machine via stdio launch recipe — registry does not health-check'
                      : undefined
                  }
                >
                  {isLocal ? 'Local' :
                   server.status === 'healthy' ? 'Healthy' :
                   server.status === 'healthy-auth-expired' ? 'Healthy (Auth Expired)' :
                   server.status === 'unhealthy' ? 'Unhealthy' : 'Unknown'}
                </span>
              </div>
            </div>

            {/* Controls */}
            <div className="flex items-center gap-3">
              {/* Last Updated (source timestamp) */}
              {server.source_updated_at && (
                <div className="text-xs text-gray-500 dark:text-gray-300 flex items-center gap-1.5">
                  <ClockIcon className="h-3.5 w-3.5" />
                  <span title={new Date(server.source_updated_at).toLocaleString()}>
                    {formatRelativeTime(server.source_updated_at)}
                  </span>
                </div>
              )}

              {/* Last Checked */}
              {(() => {
                const timeText = formatTimeSince(server.last_checked_time);
                return server.last_checked_time && timeText && !server.source_updated_at ? (
                  <div className="text-xs text-gray-500 dark:text-gray-300 flex items-center gap-1.5">
                    <ClockIcon className="h-3.5 w-3.5" />
                    <span>{timeText}</span>
                  </div>
                ) : null;
              })()}

              {/* Refresh Button — only show if the user has health_check_service
                  permission AND the server has something to refresh. Local
                  (stdio) servers have no HTTP endpoint to probe, so refresh
                  is a no-op for them — hide the button entirely. */}
              {canHealthCheck && !isLocal && (
                <button
                  onClick={handleRefreshHealth}
                  disabled={loadingRefresh}
                  className="p-2.5 text-gray-500 hover:text-blue-600 dark:hover:text-blue-400 hover:bg-blue-50 dark:hover:bg-blue-900/20 rounded-lg transition-all duration-200 disabled:opacity-50"
                  title="Refresh health status"
                  aria-label={`Refresh health status for ${server.name}`}
                >
                  <ArrowPathIcon className={`h-4 w-4 ${loadingRefresh ? 'animate-spin' : ''}`} />
                </button>
              )}

              {/* Toggle Switch - only show if user has toggle_service permission */}
              {canToggle && (
                <label className="relative inline-flex items-center cursor-pointer">
                  <input
                    type="checkbox"
                    checked={server.enabled}
                    onChange={(e) => onToggle(server.path, e.target.checked)}
                    className="sr-only peer"
                    aria-label={`Enable ${server.name}`}
                  />
                  <div className={`relative w-12 h-6 rounded-full transition-colors duration-200 ease-in-out ${
                    server.enabled
                      ? 'bg-blue-600'
                      : 'bg-gray-300 dark:bg-gray-600'
                  }`}>
                    <div className={`absolute top-0.5 left-0.5 w-5 h-5 bg-white rounded-full transition-transform duration-200 ease-in-out ${
                      server.enabled ? 'translate-x-6' : 'translate-x-0'
                    }`} />
                  </div>
                </label>
              )}
            </div>
          </div>
        </div>
        </>
        )}
      </div>

      {/* Tools Modal */}
      {showTools && (
        <div
          className="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50"
          onClick={() => {
            setShowTools(false);
            setExpandedDescriptions(new Set());
          }}
        >
          <div
            className="bg-white dark:bg-gray-800 rounded-xl p-6 max-w-2xl w-full mx-4 max-h-[80vh] overflow-auto"
            onClick={(e) => e.stopPropagation()}
          >
            <div className="flex items-center justify-between mb-4">
              <h3 className="text-lg font-semibold text-gray-900 dark:text-white">
                Tools for {server.name}
              </h3>
              <button
                onClick={() => {
                  setShowTools(false);
                  setExpandedDescriptions(new Set());
                }}
                className="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
              >
                ✕
              </button>
            </div>
            
            <div className="space-y-4">
              {tools.length > 0 ? (
                tools.map((tool, index) => {
                  const isExpanded = expandedDescriptions.has(index);
                  const toggleExpand = () => {
                    const newExpanded = new Set(expandedDescriptions);
                    if (isExpanded) {
                      newExpanded.delete(index);
                    } else {
                      newExpanded.add(index);
                    }
                    setExpandedDescriptions(newExpanded);
                  };

                  return (
                    <div key={index} className="border border-gray-200 dark:border-gray-700 rounded-lg p-4">
                      <h4 className="font-medium text-gray-900 dark:text-white mb-2">
                        {tool.name}
                      </h4>
                      {tool.description && (
                        <div className="mb-2">
                          <p className={`text-sm text-gray-600 dark:text-gray-300 ${!isExpanded ? 'line-clamp-2' : ''}`}>
                            {tool.description}
                          </p>
                          {tool.description.length > 150 && (
                            <button
                              onClick={toggleExpand}
                              className="text-xs text-blue-600 dark:text-blue-400 hover:underline mt-1"
                            >
                              {isExpanded ? 'Show less' : 'Show more'}
                            </button>
                          )}
                        </div>
                      )}
                      {tool.schema && (
                        <details className="text-xs">
                          <summary className="cursor-pointer text-gray-500 dark:text-gray-300">
                            View Schema
                          </summary>
                          <pre className="mt-2 p-3 bg-gray-50 dark:bg-gray-900 border dark:border-gray-700 rounded overflow-x-auto text-gray-900 dark:text-gray-100">
                            {JSON.stringify(tool.schema, null, 2)}
                          </pre>
                        </details>
                      )}
                    </div>
                  );
                })
              ) : server.enabled && (server.status === 'healthy' || server.status === 'healthy-auth-expired') ? (
                <p className="text-gray-500 dark:text-gray-300">
                  No tools available to you on this server. Ask your administrator if you need access.
                </p>
              ) : (
                <p className="text-gray-500 dark:text-gray-300">No tools available for this server.</p>
              )}
            </div>
          </div>
        </div>
      )}

      <ServerConfigModal
        server={server}
        isOpen={showConfig}
        onClose={() => setShowConfig(false)}
        onShowToast={onShowToast}
      />

      <SecurityScanModal
        resourceName={server.name}
        resourceType="server"
        isOpen={showSecurityScan}
        onClose={() => setShowSecurityScan(false)}
        loading={loadingSecurityScan}
        scanResult={securityScanResult}
        // Local (stdio) servers can't be scanned — registry has no HTTP
        // endpoint to probe. They carry the security-pending-local tag for
        // manual review instead.
        onRescan={canModify && !isLocal ? handleRescan : undefined}
        canRescan={canModify && !isLocal}
        unscannableReason={
          isLocal
            ? 'Local (stdio) servers cannot be scanned automatically — the registry has no HTTP endpoint to probe. These servers carry the “security-pending-local” tag and require manual review of the launch recipe (package, args, env) before being marked as reviewed.'
            : undefined
        }
        onShowToast={onShowToast}
      />

      <ConfirmModal
        isOpen={showClearSecurityPendingConfirm}
        onClose={() => setShowClearSecurityPendingConfirm(false)}
        onConfirm={handleClearSecurityPending}
        title={`Mark "${server.name}" as security-reviewed?`}
        message={
          'Local servers are not auto-scanned because the registry has no HTTP ' +
          'endpoint to probe. Clearing this tag asserts that you have manually ' +
          'reviewed the launch recipe (package, args, env) and consider it safe ' +
          'for distribution to developers.'
        }
        confirmLabel="Mark as reviewed"
        cancelLabel="Cancel"
        loadingLabel="Marking..."
        isLoading={clearingSecurityPending}
      />

      <VersionSelectorModal
        isOpen={showVersionSelector}
        onClose={() => setShowVersionSelector(false)}
        serverName={server.name}
        serverPath={server.path}
        versions={server.versions || []}
        defaultVersion={server.default_version || null}
        onVersionChange={(newDefaultVersion) => {
          if (onServerUpdate) {
            // Update both default_version and versions array to reflect the change
            const updatedVersions = server.versions?.map(v => ({
              ...v,
              is_default: v.version === newDefaultVersion
            }));
            onServerUpdate(server.path, {
              default_version: newDefaultVersion,
              versions: updatedVersions
            });
          }
        }}
        onRefreshServer={handleRefreshServerData}
        onShowToast={onShowToast}
        authToken={authToken}
        canModify={canModify}
      />

      <ServerDetailsModal
        server={server}
        isOpen={showDetails}
        onClose={() => setShowDetails(false)}
        fullDetails={server}
      />

    </>
  );
});

ServerCard.displayName = 'ServerCard';

export default ServerCard;
