/**
 * ConnectionStatus Component
 *
 * Displays the current Gateway connection status with visual indicators.
 * Supports automatic reconnect and manual reconnect button.
 * Includes health status indicator for ZCLAW backend.
 */

import { useState, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { Wifi, WifiOff, Loader2, RefreshCw, Heart, HeartPulse } from 'lucide-react';
import { useConnectionStore, getClient } from '../store/connectionStore';
import {
  createHealthCheckScheduler,
  getHealthStatusLabel,
  formatHealthCheckTime,
  type HealthCheckResult,
  type HealthStatus,
} from '../lib/health-check';

interface ConnectionStatusProps {
  /** Show compact version (just icon and status text) */
  compact?: boolean;
  /** Show reconnect button when disconnected */
  showReconnectButton?: boolean;
  /** Additional CSS classes */
  className?: string;
}

interface ReconnectInfo {
  attempt: number;
  delay: number;
  maxAttempts: number;
}

type StatusType = 'disconnected' | 'connecting' | 'handshaking' | 'connected' | 'reconnecting';

const statusConfig: Record<StatusType, {
  color: string;
  bgColor: string;
  label: string;
  icon: typeof Wifi;
  animate?: boolean;
}> = {
  disconnected: {
    color: 'text-red-500',
    bgColor: 'bg-red-50 dark:bg-red-900/20',
    label: '已断开',
    icon: WifiOff,
  },
  connecting: {
    color: 'text-yellow-500',
    bgColor: 'bg-yellow-50 dark:bg-yellow-900/20',
    label: '连接中...',
    icon: Loader2,
    animate: true,
  },
  handshaking: {
    color: 'text-yellow-500',
    bgColor: 'bg-yellow-50 dark:bg-yellow-900/20',
    label: '认证中...',
    icon: Loader2,
    animate: true,
  },
  connected: {
    color: 'text-green-500',
    bgColor: 'bg-green-50 dark:bg-green-900/20',
    label: '已连接',
    icon: Wifi,
  },
  reconnecting: {
    color: 'text-orange-500',
    bgColor: 'bg-orange-50 dark:bg-orange-900/20',
    label: '重连中...',
    icon: RefreshCw,
    animate: true,
  },
};

export function ConnectionStatus({
  compact = false,
  showReconnectButton = true,
  className = '',
}: ConnectionStatusProps) {
  const connectionState = useConnectionStore((s) => s.connectionState);
  const connect = useConnectionStore((s) => s.connect);
  const [showPrompt, setShowPrompt] = useState(false);
  const [reconnectInfo, setReconnectInfo] = useState<ReconnectInfo | null>(null);

  // Listen for reconnect events
  useEffect(() => {
    const client = getClient();

    const unsubReconnecting = client.on('reconnecting', (info) => {
      setReconnectInfo(info as ReconnectInfo);
    });

    const unsubFailed = client.on('reconnect_failed', () => {
      setShowPrompt(true);
      setReconnectInfo(null);
    });

    const unsubConnected = client.on('connected', () => {
      setShowPrompt(false);
      setReconnectInfo(null);
    });

    return () => {
      unsubReconnecting();
      unsubFailed();
      unsubConnected();
    };
  }, []);

  const config = statusConfig[connectionState];
  const Icon = config.icon;
  const isDisconnected = connectionState === 'disconnected';
  const isReconnecting = connectionState === 'reconnecting';

  const handleReconnect = async () => {
    setShowPrompt(false);
    try {
      await connect();
    } catch (error) {
      console.error('Manual reconnect failed:', error);
    }
  };

  // Compact version
  if (compact) {
    return (
      <div className={`flex items-center gap-1.5 ${className}`}>
        <Icon
          className={`w-3.5 h-3.5 ${config.color} ${config.animate ? 'animate-spin' : ''}`}
        />
        <span className={`text-xs ${config.color}`}>
          {isReconnecting && reconnectInfo
            ? `${config.label} (${reconnectInfo.attempt}/${reconnectInfo.maxAttempts})`
            : config.label}
        </span>
        {showPrompt && showReconnectButton && (
          <button
            onClick={handleReconnect}
            className="text-xs text-blue-500 hover:text-blue-600 ml-1"
          >
            重连
          </button>
        )}
      </div>
    );
  }

  // Full version
  return (
    <div className={`flex items-center gap-3 ${config.bgColor} rounded-lg px-3 py-2 ${className}`}>
      <motion.div
        initial={false}
        animate={{ rotate: config.animate ? 360 : 0 }}
        transition={config.animate ? { duration: 1, repeat: Infinity, ease: 'linear' } : {}}
      >
        <Icon className={`w-5 h-5 ${config.color}`} />
      </motion.div>

      <div className="flex-1">
        <div className={`text-sm font-medium ${config.color}`}>
          {isReconnecting && reconnectInfo
            ? `${config.label} (${reconnectInfo.attempt}/${reconnectInfo.maxAttempts})`
            : config.label}
        </div>
        {reconnectInfo && (
          <div className="text-xs text-gray-500 dark:text-gray-400">
            {Math.round(reconnectInfo.delay / 1000)}秒后重试
          </div>
        )}
      </div>

      <AnimatePresence>
        {showPrompt && isDisconnected && showReconnectButton && (
          <motion.button
            initial={{ opacity: 0, scale: 0.9 }}
            animate={{ opacity: 1, scale: 1 }}
            exit={{ opacity: 0, scale: 0.9 }}
            onClick={handleReconnect}
            className="flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium text-white bg-blue-500 hover:bg-blue-600 rounded-md transition-colors"
          >
            <RefreshCw className="w-4 h-4" />
            重新连接
          </motion.button>
        )}
      </AnimatePresence>
    </div>
  );
}

/**
 * ConnectionIndicator - Minimal connection indicator for headers
 */
export function ConnectionIndicator({ className = '' }: { className?: string }) {
  const connectionState = useConnectionStore((s) => s.connectionState);

  const isConnected = connectionState === 'connected';
  const isReconnecting = connectionState === 'reconnecting';

  return (
    <span className={`text-xs flex items-center gap-1 ${className}`}>
      <span
        className={`w-1.5 h-1.5 rounded-full ${
          isConnected
            ? 'bg-green-400'
            : isReconnecting
            ? 'bg-orange-400 animate-pulse'
            : 'bg-red-400'
        }`}
      />
      <span className={
        isConnected
          ? 'text-green-500'
          : isReconnecting
          ? 'text-orange-500'
          : 'text-red-500'
      }>
        {isConnected
          ? 'Gateway 已连接'
          : isReconnecting
          ? '重连中...'
          : 'Gateway 未连接'}
      </span>
    </span>
  );
}

/**
 * HealthStatusIndicator - Displays ZCLAW backend health status
 */
export function HealthStatusIndicator({
  className = '',
  showDetails = false,
}: {
  className?: string;
  showDetails?: boolean;
}) {
  const [healthResult, setHealthResult] = useState<HealthCheckResult | null>(null);

  useEffect(() => {
    // Start periodic health checks
    const cleanup = createHealthCheckScheduler((result) => {
      setHealthResult(result);
    }, 30000); // Check every 30 seconds

    return cleanup;
  }, []);

  if (!healthResult) {
    return (
      <span className={`text-xs flex items-center gap-1 ${className}`}>
        <Heart className="w-3.5 h-3.5 text-gray-400" />
        <span className="text-gray-400">检查中...</span>
      </span>
    );
  }

  const statusColors: Record<HealthStatus, { dot: string; text: string; icon: typeof Heart }> = {
    healthy: { dot: 'bg-green-400', text: 'text-green-500', icon: Heart },
    unhealthy: { dot: 'bg-red-400', text: 'text-red-500', icon: HeartPulse },
    unknown: { dot: 'bg-gray-400', text: 'text-gray-500', icon: Heart },
  };

  const config = statusColors[healthResult.status];
  const Icon = config.icon;

  return (
    <span className={`text-xs flex items-center gap-1 ${className}`}>
      <Icon className={`w-3.5 h-3.5 ${config.text}`} />
      <span className={config.text}>
        {getHealthStatusLabel(healthResult.status)}
      </span>
      {showDetails && healthResult.message && (
        <span className="text-gray-400 ml-1" title={healthResult.message}>
          ({formatHealthCheckTime(healthResult.timestamp)})
        </span>
      )}
    </span>
  );
}

export default ConnectionStatus;
