import { useState, useEffect, useCallback } from 'react';

const SERVICES = [
  {
    name: 'Ollama',
    url: 'http://localhost:11434',
    healthPath: '/api/tags',
    uiUrl: null,
    description: 'Local LLM runtime',
    category: 'AI & LLM',
  },
  {
    name: 'Open WebUI',
    url: 'http://localhost:3030',
    healthPath: '/',
    uiUrl: 'http://localhost:3030',
    description: 'Chat interface',
    category: 'AI & LLM',
  },
  {
    name: 'OpenClaw Gateway',
    url: 'http://localhost:8080',
    healthPath: '/',
    uiUrl: null,
    description: 'Agent gateway',
    category: 'Agent',
  },
  {
    name: 'OpenClaw Bridge',
    url: 'http://localhost:8081',
    healthPath: '/',
    uiUrl: null,
    description: 'HTTP-to-CLI bridge',
    category: 'Agent',
  },
  {
    name: 'Wyoming STT',
    url: 'http://localhost:10300',
    healthPath: '/',
    uiUrl: null,
    description: 'Whisper speech-to-text',
    category: 'Voice',
    tcp: true,
  },
  {
    name: 'Wyoming TTS',
    url: 'http://localhost:10301',
    healthPath: '/',
    uiUrl: null,
    description: 'Kokoro text-to-speech',
    category: 'Voice',
    tcp: true,
  },
  {
    name: 'Wyoming Satellite',
    url: 'http://localhost:10700',
    healthPath: '/',
    uiUrl: null,
    description: 'Mac Mini mic/speaker satellite',
    category: 'Voice',
    tcp: true,
  },
  {
    name: 'Home Assistant',
    url: 'https://10.0.0.199:8123',
    healthPath: '/api/',
    uiUrl: 'https://10.0.0.199:8123',
    description: 'Smart home platform',
    category: 'Smart Home',
  },
  {
    name: 'Uptime Kuma',
    url: 'http://localhost:3001',
    healthPath: '/',
    uiUrl: 'http://localhost:3001',
    description: 'Service health monitoring',
    category: 'Infrastructure',
  },
  {
    name: 'n8n',
    url: 'http://localhost:5678',
    healthPath: '/',
    uiUrl: 'http://localhost:5678',
    description: 'Workflow automation',
    category: 'Infrastructure',
  },
  {
    name: 'code-server',
    url: 'http://localhost:8090',
    healthPath: '/',
    uiUrl: 'http://localhost:8090',
    description: 'Browser-based VS Code',
    category: 'Infrastructure',
  },
  {
    name: 'Portainer',
    url: 'https://10.0.0.199:9443',
    healthPath: '/',
    uiUrl: 'https://10.0.0.199:9443',
    description: 'Docker management',
    category: 'Infrastructure',
  },
  {
    name: 'Gitea',
    url: 'http://10.0.0.199:3000',
    healthPath: '/',
    uiUrl: 'http://10.0.0.199:3000',
    description: 'Self-hosted Git',
    category: 'Infrastructure',
  },
];

const CATEGORY_ICONS = {
  'AI & LLM': (
    <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
      <path strokeLinecap="round" strokeLinejoin="round" d="M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09zM18.259 8.715L18 9.75l-.259-1.035a3.375 3.375 0 00-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 002.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 002.455 2.456L21.75 6l-1.036.259a3.375 3.375 0 00-2.455 2.456zM16.894 20.567L16.5 21.75l-.394-1.183a2.25 2.25 0 00-1.423-1.423L13.5 18.75l1.183-.394a2.25 2.25 0 001.423-1.423l.394-1.183.394 1.183a2.25 2.25 0 001.423 1.423l1.183.394-1.183.394a2.25 2.25 0 00-1.423 1.423z" />
    </svg>
  ),
  'Agent': (
    <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
      <path strokeLinecap="round" strokeLinejoin="round" d="M8.25 3v1.5M4.5 8.25H3m18 0h-1.5M4.5 12H3m18 0h-1.5m-15 3.75H3m18 0h-1.5M8.25 19.5V21M12 3v1.5m0 15V21m3.75-18v1.5m0 15V21m-9-1.5h10.5a2.25 2.25 0 002.25-2.25V6.75a2.25 2.25 0 00-2.25-2.25H6.75A2.25 2.25 0 004.5 6.75v10.5a2.25 2.25 0 002.25 2.25zm.75-12h9v9h-9v-9z" />
    </svg>
  ),
  'Voice': (
    <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
      <path strokeLinecap="round" strokeLinejoin="round" d="M12 18.75a6 6 0 006-6v-1.5m-6 7.5a6 6 0 01-6-6v-1.5m6 7.5v3.75m-3.75 0h7.5M12 15.75a3 3 0 01-3-3V4.5a3 3 0 116 0v8.25a3 3 0 01-3 3z" />
    </svg>
  ),
  'Smart Home': (
    <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
      <path strokeLinecap="round" strokeLinejoin="round" d="M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" />
    </svg>
  ),
  'Infrastructure': (
    <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
      <path strokeLinecap="round" strokeLinejoin="round" d="M5.25 14.25h13.5m-13.5 0a3 3 0 01-3-3m3 3a3 3 0 100 6h13.5a3 3 0 100-6m-16.5-3a3 3 0 013-3h13.5a3 3 0 013 3m-19.5 0a4.5 4.5 0 01.9-2.7L5.737 5.1a3.375 3.375 0 012.7-1.35h7.126c1.062 0 2.062.5 2.7 1.35l2.587 3.45a4.5 4.5 0 01.9 2.7m0 0a3 3 0 01-3 3m0 3h.008v.008h-.008v-.008zm0-6h.008v.008h-.008v-.008zm-3 6h.008v.008h-.008v-.008zm0-6h.008v.008h-.008v-.008z" />
    </svg>
  ),
};

function StatusDot({ status }) {
  const colors = {
    online: 'bg-emerald-400 shadow-emerald-400/50',
    offline: 'bg-red-400 shadow-red-400/50',
    checking: 'bg-amber-400 shadow-amber-400/50 animate-pulse',
    unknown: 'bg-gray-500',
  };
  return (
    <span className={`inline-block w-2.5 h-2.5 rounded-full shadow-lg ${colors[status] || colors.unknown}`} />
  );
}

export default function ServiceStatus() {
  const [statuses, setStatuses] = useState(() =>
    Object.fromEntries(SERVICES.map(s => [s.name, { status: 'checking', lastCheck: null, responseTime: null }]))
  );
  const [lastRefresh, setLastRefresh] = useState(null);

  const checkService = useCallback(async (service) => {
    try {
      // Route all checks through the server-side proxy to avoid CORS and
      // self-signed SSL cert issues in the browser.
      const target = encodeURIComponent(service.url + service.healthPath);
      const modeParam = service.tcp ? '&mode=tcp' : '';
      const controller = new AbortController();
      const timeout = setTimeout(() => controller.abort(), 8000);

      const res = await fetch(`/api/health?url=${target}${modeParam}`, { signal: controller.signal });
      clearTimeout(timeout);

      const data = await res.json();
      return { status: data.status, lastCheck: new Date(), responseTime: data.responseTime };
    } catch {
      return { status: 'offline', lastCheck: new Date(), responseTime: null };
    }
  }, []);

  const refreshAll = useCallback(async () => {
    // Mark all as checking
    setStatuses(prev =>
      Object.fromEntries(Object.entries(prev).map(([k, v]) => [k, { ...v, status: 'checking' }]))
    );

    const results = await Promise.allSettled(
      SERVICES.map(async (service) => {
        const result = await checkService(service);
        return { name: service.name, ...result };
      })
    );

    const newStatuses = {};
    for (const r of results) {
      if (r.status === 'fulfilled') {
        newStatuses[r.value.name] = {
          status: r.value.status,
          lastCheck: r.value.lastCheck,
          responseTime: r.value.responseTime,
        };
      }
    }
    setStatuses(prev => ({ ...prev, ...newStatuses }));
    setLastRefresh(new Date());
  }, [checkService]);

  useEffect(() => {
    refreshAll();
    const interval = setInterval(refreshAll, 30000);
    return () => clearInterval(interval);
  }, [refreshAll]);

  const categories = [...new Set(SERVICES.map(s => s.category))];
  const onlineCount = Object.values(statuses).filter(s => s.status === 'online').length;
  const offlineCount = Object.values(statuses).filter(s => s.status === 'offline').length;
  const totalCount = SERVICES.length;
  const allOnline = onlineCount === totalCount;

  return (
    <div className="space-y-8">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-3xl font-bold text-gray-100">Service Status</h1>
          <p className="text-sm text-gray-500 mt-1">
            {onlineCount}/{totalCount} services online
            {lastRefresh && (
              <span className="ml-3">
                Last check: {lastRefresh.toLocaleTimeString()}
              </span>
            )}
          </p>
        </div>
        <button
          onClick={refreshAll}
          className="flex items-center gap-2 px-4 py-2 bg-gray-800 hover:bg-gray-700 text-gray-300 rounded-lg border border-gray-700 transition-colors"
        >
          <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
            <path strokeLinecap="round" strokeLinejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182" />
          </svg>
          Refresh
        </button>
      </div>

      {/* Summary bar */}
      <div className="h-2 rounded-full bg-gray-800 overflow-hidden flex">
        {allOnline ? (
          <div
            className="h-full bg-gradient-to-r from-purple-500 to-indigo-500 transition-all duration-500"
            style={{ width: '100%' }}
          />
        ) : (
          <>
            <div
              className="h-full bg-gradient-to-r from-emerald-500 to-emerald-400 transition-all duration-500"
              style={{ width: `${(onlineCount / totalCount) * 100}%` }}
            />
            <div
              className="h-full bg-gradient-to-r from-red-500 to-red-400 transition-all duration-500"
              style={{ width: `${(offlineCount / totalCount) * 100}%` }}
            />
          </>
        )}
      </div>

      {/* Service grid by category */}
      {categories.map(category => (
        <div key={category}>
          <div className="flex items-center gap-2 mb-4">
            <span className="text-gray-400">{CATEGORY_ICONS[category]}</span>
            <h2 className="text-lg font-semibold text-gray-300">{category}</h2>
          </div>
          <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
            {SERVICES.filter(s => s.category === category).map(service => {
              const st = statuses[service.name] || { status: 'unknown' };
              return (
                <div
                  key={service.name}
                  className={`relative rounded-xl border p-4 transition-all duration-200 ${
                    st.status === 'online'
                      ? 'bg-gray-800/50 border-gray-700 hover:border-emerald-500/50'
                      : st.status === 'offline'
                      ? 'bg-gray-800/50 border-red-500/30 hover:border-red-500/50'
                      : 'bg-gray-800/50 border-gray-700'
                  }`}
                >
                  <div className="flex items-start justify-between">
                    <div className="flex-1">
                      <div className="flex items-center gap-2">
                        <StatusDot status={st.status} />
                        <h3 className="font-medium text-gray-200">{service.name}</h3>
                      </div>
                      <p className="text-xs text-gray-500 mt-1">{service.description}</p>
                      {st.responseTime !== null && (
                        <p className="text-xs text-gray-600 mt-0.5">{st.responseTime}ms</p>
                      )}
                    </div>
                    {service.uiUrl && (
                      <a
                        href={service.uiUrl}
                        target="_blank"
                        rel="noopener noreferrer"
                        className="text-xs px-2.5 py-1 rounded-md bg-gray-700 hover:bg-gray-600 text-gray-300 transition-colors flex items-center gap-1"
                      >
                        Open
                        <svg className="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                          <path strokeLinecap="round" strokeLinejoin="round" d="M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25" />
                        </svg>
                      </a>
                    )}
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      ))}
    </div>
  );
}
