/**
 * HealthPanel — Read-only dashboard for all subsystem health status
 *
 * Displays:
 * - Agent Heartbeat engine status (running, config, alerts)
 * - Connection status (mode, SaaS reachability)
 * - SaaS device heartbeat status
 * - Memory pipeline status
 * - Recent alerts history
 *
 * No config editing (that's HeartbeatConfig tab).
 * Uses useState (not Zustand) — component-scoped state.
 */

import { useState, useEffect, useCallback, useRef } from 'react';
import {
  Activity,
  RefreshCw,
  Wifi,
  WifiOff,
  Cloud,
  CloudOff,
  Database,
  AlertTriangle,
  CheckCircle,
  XCircle,
  Clock,
} from 'lucide-react';
import { intelligenceClient, type HeartbeatResult } from '../lib/intelligence-client';
import { useConnectionStore } from '../store/connectionStore';
import { useSaaSStore } from '../store/saasStore';
import { isTauriRuntime } from '../lib/tauri-gateway';
import { safeListen } from '../lib/safe-tauri';
import { createLogger } from '../lib/logger';

const log = createLogger('HealthPanel');

// === Types ===

interface HealthSnapshotData {
  timestamp: string;
  intelligence: {
    engineRunning: boolean;
    config: {
      enabled: boolean;
      interval_minutes: number;
      proactivity_level: string;
    };
    lastTick: string | null;
    alertCount24h: number;
    totalChecks: number;
  };
  memory: {
    totalEntries: number;
    storageSizeBytes: number;
    lastExtraction: string | null;
  };
}

interface HealthCardProps {
  title: string;
  icon: React.ReactNode;
  status: 'green' | 'yellow' | 'gray' | 'red';
  children: React.ReactNode;
}

const STATUS_COLORS = {
  green: 'text-green-500',
  yellow: 'text-yellow-500',
  gray: 'text-gray-400',
  red: 'text-red-500',
};

const STATUS_BG = {
  green: 'bg-green-50 dark:bg-green-900/20',
  yellow: 'bg-yellow-50 dark:bg-yellow-900/20',
  gray: 'bg-gray-50 dark:bg-gray-800/50',
  red: 'bg-red-50 dark:bg-red-900/20',
};

function HealthCard({ title, icon, status, children }: HealthCardProps) {
  return (
    <div className={`rounded-lg border border-gray-200 dark:border-gray-700 p-4 ${STATUS_BG[status]}`}>
      <div className="flex items-center gap-2 mb-3">
        <span className={STATUS_COLORS[status]}>{icon}</span>
        <h3 className="text-sm font-medium text-gray-900 dark:text-gray-100">{title}</h3>
        <span className={`ml-auto text-xs ${STATUS_COLORS[status]}`}>
          {status === 'green' ? '正常' : status === 'yellow' ? '降级' : status === 'red' ? '异常' : '未启用'}
        </span>
      </div>
      <div className="space-y-1.5 text-xs text-gray-600 dark:text-gray-400">
        {children}
      </div>
    </div>
  );
}

function formatBytes(bytes: number): string {
  if (bytes === 0) return '0 B';
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
}

function formatTime(isoString: string | null): string {
  if (!isoString) return '从未';
  try {
    const date = new Date(isoString);
    return date.toLocaleString('zh-CN', {
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
    });
  } catch {
    return isoString;
  }
}

function formatUrgency(urgency: string): { label: string; color: string } {
  switch (urgency) {
    case 'high': return { label: '高', color: 'text-red-500' };
    case 'medium': return { label: '中', color: 'text-yellow-500' };
    case 'low': return { label: '低', color: 'text-blue-500' };
    default: return { label: urgency, color: 'text-gray-500' };
  }
}

// === Main Component ===

export function HealthPanel() {
  const [snapshot, setSnapshot] = useState<HealthSnapshotData | null>(null);
  const [alerts, setAlerts] = useState<HeartbeatResult[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const alertsEndRef = useRef<HTMLDivElement>(null);

  // Get live connection and SaaS state
  const connectionState = useConnectionStore((s) => s.connectionState);
  const gatewayVersion = useConnectionStore((s) => s.gatewayVersion);
  const connectionMode = useSaaSStore((s) => s.connectionMode);
  const saasReachable = useSaaSStore((s) => s.saasReachable);
  const consecutiveFailures = useSaaSStore((s) => s._consecutiveFailures);
  const isLoggedIn = useSaaSStore((s) => s.isLoggedIn);

  // Fetch health snapshot
  const fetchSnapshot = useCallback(async () => {
    if (!isTauriRuntime()) return;
    setLoading(true);
    setError(null);
    try {
      const { invoke } = await import('@tauri-apps/api/core');
      const data = await invoke<HealthSnapshotData>('health_snapshot', {
        agentId: 'zclaw-main',
      });
      setSnapshot(data);
    } catch (err) {
      log.warn('Failed to fetch health snapshot:', err);
      setError(String(err));
    } finally {
      setLoading(false);
    }
  }, []);

  // Fetch alert history
  const fetchAlerts = useCallback(async () => {
    if (!isTauriRuntime()) return;
    try {
      const history = await intelligenceClient.heartbeat.getHistory('zclaw-main', 100);
      setAlerts(history);
    } catch (err) {
      log.warn('Failed to fetch alert history:', err);
    }
  }, []);

  // Initial load
  useEffect(() => {
    fetchSnapshot();
    fetchAlerts();
  }, [fetchSnapshot, fetchAlerts]);

  // Subscribe to real-time alerts
  useEffect(() => {
    if (!isTauriRuntime()) return;

    let unlisten: (() => void) | null = null;
    const subscribe = async () => {
      unlisten = await safeListen<Array<{ title: string; content: string; urgency: string; source: string; timestamp: string }>>(
        'heartbeat:alert',
        (newAlerts) => {
          // Prepend new alerts to history
          setAlerts((prev) => {
            const result: HeartbeatResult[] = [
              {
                status: 'alert',
                alerts: newAlerts.map((a) => ({
                  title: a.title,
                  content: a.content,
                  urgency: a.urgency as 'low' | 'medium' | 'high',
                  source: a.source,
                  timestamp: a.timestamp,
                })),
                checked_items: 0,
                timestamp: new Date().toISOString(),
              },
              ...prev,
            ];
            // Keep max 100
            return result.slice(0, 100);
          });
        },
      );
    };
    subscribe();

    return () => {
      if (unlisten) unlisten();
    };
  }, []);

  // Auto-scroll alerts to show latest
  useEffect(() => {
    alertsEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [alerts]);

  // Determine SaaS card status
  const saasStatus: 'green' | 'yellow' | 'gray' | 'red' = !isLoggedIn
    ? 'gray'
    : saasReachable
      ? 'green'
      : 'red';

  // Determine connection card status
  const isActuallyConnected = connectionState === 'connected';
  const connectionStatus: 'green' | 'yellow' | 'gray' | 'red' = isActuallyConnected
    ? 'green'
    : connectionState === 'connecting' || connectionState === 'reconnecting'
      ? 'yellow'
      : 'red';

  // Determine heartbeat card status
  const heartbeatStatus: 'green' | 'yellow' | 'gray' | 'red' = !snapshot
    ? 'gray'
    : snapshot.intelligence.engineRunning
      ? 'green'
      : snapshot.intelligence.config.enabled
        ? 'yellow'
        : 'gray';

  // Determine memory card status
  const memoryStatus: 'green' | 'yellow' | 'gray' | 'red' = !snapshot
    ? 'gray'
    : snapshot.memory.totalEntries === 0
      ? 'gray'
      : snapshot.memory.storageSizeBytes > 50 * 1024 * 1024
        ? 'yellow'
        : 'green';

  return (
    <div className="flex flex-col h-full">
      {/* Header */}
      <div className="flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700">
        <div className="flex items-center gap-2">
          <Activity className="w-5 h-5 text-blue-500" />
          <h2 className="text-lg font-semibold text-gray-900 dark:text-gray-100">系统健康</h2>
        </div>
        <button
          onClick={() => { fetchSnapshot(); fetchAlerts(); }}
          disabled={loading}
          className="flex items-center gap-1 px-3 py-1.5 text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 disabled:opacity-50"
        >
          <RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />
          刷新
        </button>
      </div>

      {/* Content */}
      <div className="flex-1 overflow-y-auto p-4 space-y-4">
        {error && (
          <div className="p-3 text-sm text-red-600 bg-red-50 dark:bg-red-900/20 rounded-lg">
            加载失败: {error}
          </div>
        )}

        {/* Health Cards Grid */}
        <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
          {/* Agent Heartbeat Card */}
          <HealthCard
            title="Agent 心跳"
            icon={<Activity className="w-4 h-4" />}
            status={heartbeatStatus}
          >
            <div className="flex justify-between">
              <span>引擎状态</span>
              <span className={snapshot?.intelligence.engineRunning ? 'text-green-600' : 'text-gray-400'}>
                {snapshot?.intelligence.engineRunning ? '运行中' : '已停止'}
              </span>
            </div>
            <div className="flex justify-between">
              <span>检查间隔</span>
              <span>{snapshot?.intelligence.config.interval_minutes ?? '-'} 分钟</span>
            </div>
            <div className="flex justify-between">
              <span>上次检查</span>
              <span>{formatTime(snapshot?.intelligence.lastTick ?? null)}</span>
            </div>
            <div className="flex justify-between">
              <span>24h 告警数</span>
              <span>{snapshot?.intelligence.alertCount24h ?? 0}</span>
            </div>
            <div className="flex justify-between">
              <span>主动性级别</span>
              <span>{snapshot?.intelligence.config.proactivity_level ?? '-'}</span>
            </div>
          </HealthCard>

          {/* Connection Card */}
          <HealthCard
            title="连接状态"
            icon={isActuallyConnected ? <Wifi className="w-4 h-4" /> : <WifiOff className="w-4 h-4" />}
            status={connectionStatus}
          >
            <div className="flex justify-between">
              <span>连接模式</span>
              <span>{connectionMode === 'saas' ? 'SaaS 云端' : connectionMode === 'tauri' ? '本地模式' : connectionMode}</span>
            </div>
            <div className="flex justify-between">
              <span>连接状态</span>
              <span className={isActuallyConnected ? 'text-green-600' : connectionState === 'connecting' ? 'text-yellow-500' : 'text-red-500'}>
                {connectionState === 'connected' ? '已连接' : connectionState === 'connecting' ? '连接中...' : connectionState === 'reconnecting' ? '重连中...' : '未连接'}
              </span>
            </div>
            <div className="flex justify-between">
              <span>网关版本</span>
              <span>{gatewayVersion ?? '-'}</span>
            </div>
            <div className="flex justify-between">
              <span>SaaS 可达</span>
              <span className={saasReachable ? 'text-green-600' : 'text-red-500'}>
                {saasReachable ? '是' : '否'}
              </span>
            </div>
          </HealthCard>

          {/* SaaS Device Card */}
          <HealthCard
            title="SaaS 设备"
            icon={saasReachable ? <Cloud className="w-4 h-4" /> : <CloudOff className="w-4 h-4" />}
            status={saasStatus}
          >
            <div className="flex justify-between">
              <span>设备注册</span>
              <span>{isLoggedIn ? '已注册' : '未注册'}</span>
            </div>
            <div className="flex justify-between">
              <span>连续失败</span>
              <span className={consecutiveFailures > 0 ? 'text-yellow-500' : 'text-green-600'}>
                {consecutiveFailures}
              </span>
            </div>
            <div className="flex justify-between">
              <span>服务状态</span>
              <span className={saasReachable ? 'text-green-600' : 'text-red-500'}>
                {saasReachable ? '在线' : isLoggedIn ? '离线 (已降级)' : '未连接'}
              </span>
            </div>
          </HealthCard>

          {/* Memory Card */}
          <HealthCard
            title="记忆管道"
            icon={<Database className="w-4 h-4" />}
            status={memoryStatus}
          >
            <div className="flex justify-between">
              <span>记忆条目</span>
              <span>{snapshot?.memory.totalEntries ?? 0}</span>
            </div>
            <div className="flex justify-between">
              <span>存储大小</span>
              <span>{formatBytes(snapshot?.memory.storageSizeBytes ?? 0)}</span>
            </div>
            <div className="flex justify-between">
              <span>上次提取</span>
              <span>{formatTime(snapshot?.memory.lastExtraction ?? null)}</span>
            </div>
          </HealthCard>
        </div>

        {/* Alerts History */}
        <div className="rounded-lg border border-gray-200 dark:border-gray-700">
          <div className="flex items-center gap-2 p-3 border-b border-gray-200 dark:border-gray-700">
            <AlertTriangle className="w-4 h-4 text-yellow-500" />
            <h3 className="text-sm font-medium text-gray-900 dark:text-gray-100">最近告警</h3>
            <span className="ml-auto text-xs text-gray-400">
              {alerts.reduce((sum, r) => sum + r.alerts.length, 0)} 条
            </span>
          </div>
          <div className="max-h-64 overflow-y-auto divide-y divide-gray-100 dark:divide-gray-800">
            {alerts.length === 0 ? (
              <div className="p-4 text-center text-sm text-gray-400">暂无告警记录</div>
            ) : (
              alerts.map((result, ri) =>
                result.alerts.map((alert, ai) => (
                  <div key={`${ri}-${ai}`} className="flex items-start gap-2 p-3 hover:bg-gray-50 dark:hover:bg-gray-800/50">
                    <span className={`mt-0.5 ${formatUrgency(alert.urgency).color}`}>
                      {alert.urgency === 'high' ? (
                        <XCircle className="w-3.5 h-3.5" />
                      ) : alert.urgency === 'medium' ? (
                        <AlertTriangle className="w-3.5 h-3.5" />
                      ) : (
                        <CheckCircle className="w-3.5 h-3.5" />
                      )}
                    </span>
                    <div className="flex-1 min-w-0">
                      <div className="flex items-center gap-2">
                        <span className="text-xs font-medium text-gray-900 dark:text-gray-100 truncate">
                          {alert.title}
                        </span>
                        <span className={`text-xs px-1 rounded ${formatUrgency(alert.urgency).color} bg-opacity-10`}>
                          {formatUrgency(alert.urgency).label}
                        </span>
                      </div>
                      <p className="text-xs text-gray-500 dark:text-gray-400 truncate">{alert.content}</p>
                    </div>
                    <span className="text-xs text-gray-400 whitespace-nowrap flex items-center gap-1">
                      <Clock className="w-3 h-3" />
                      {formatTime(alert.timestamp)}
                    </span>
                  </div>
                ))
              )
            )}
            <div ref={alertsEndRef} />
          </div>
        </div>
      </div>
    </div>
  );
}
