"use client";

import { useState, useEffect, useCallback } from "react";
import { Card } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { StatCard } from "@/components/ui/stat-card";
import {
  Network,
  RefreshCw,
  Server,
  Cloud,
  Wifi,
  Activity,
  Clock,
  TrendingUp,
  TrendingDown,
  Minus,
  AlertTriangle,
} from "lucide-react";

interface TopologyNode {
  backend_id: string;
  backend_type: string;
  name: string;
  url: string;
  is_local: boolean;
  status: "online" | "degraded" | "offline";
  latency_ms: number;
  latency_bucket: "green" | "yellow" | "red" | "gray";
  p50_ms: number;
  p95_ms: number;
  p99_ms: number;
  models: string[];
  last_seen: string | null;
  last_check: string | null;
  consecutive_failures: number;
  uptime_percent: number;
  trend: "improving" | "stable" | "degrading";
}

interface TopologyData {
  timestamp: string | null;
  nodes: TopologyNode[];
  total_backends: number;
  healthy_backends: number;
  avg_latency_ms: number;
}

const bucketColors: Record<string, string> = {
  green: "bg-emerald-500",
  yellow: "bg-yellow-500",
  red: "bg-red-500",
  gray: "bg-gray-600",
};

const bucketBorderColors: Record<string, string> = {
  green: "border-emerald-500/30",
  yellow: "border-yellow-500/30",
  red: "border-red-500/30",
  gray: "border-gray-600/30",
};

const statusLabels: Record<string, { label: string; color: string }> = {
  online: { label: "Online", color: "text-emerald-400" },
  degraded: { label: "Degraded", color: "text-yellow-400" },
  offline: { label: "Offline", color: "text-red-400" },
};

function BackendIcon({ type }: { type: string }) {
  switch (type) {
    case "ollama":
      return <Server size={16} />;
    case "openai":
    case "anthropic":
    case "google":
    case "openrouter":
      return <Cloud size={16} />;
    case "lan":
      return <Wifi size={16} />;
    default:
      return <Server size={16} />;
  }
}

function TrendIcon({ trend }: { trend: string }) {
  switch (trend) {
    case "improving":
      return <TrendingDown size={14} className="text-emerald-400" />;
    case "degrading":
      return <TrendingUp size={14} className="text-red-400" />;
    default:
      return <Minus size={14} className="text-gray-500" />;
  }
}

function formatMs(ms: number): string {
  if (ms < 1) return "<1ms";
  if (ms < 1000) return `${Math.round(ms)}ms`;
  return `${(ms / 1000).toFixed(1)}s`;
}

function timeAgo(iso: string | null): string {
  if (!iso) return "Never";
  const diff = Date.now() - new Date(iso).getTime();
  const seconds = Math.floor(diff / 1000);
  if (seconds < 60) return `${seconds}s ago`;
  const minutes = Math.floor(seconds / 60);
  if (minutes < 60) return `${minutes}m ago`;
  const hours = Math.floor(minutes / 60);
  return `${hours}h ago`;
}

export default function TopologyPage() {
  const [topology, setTopology] = useState<TopologyData | null>(null);
  const [loading, setLoading] = useState(true);
  const [pinging, setPinging] = useState(false);
  const [error, setError] = useState("");
  const [viewMode, setViewMode] = useState<"diagram" | "table">("diagram");

  const fetchTopology = useCallback(async () => {
    try {
      const res = await fetch("/api/topology");
      if (res.ok) {
        const data = await res.json();
        setTopology(data);
        setError("");
      } else {
        setError("Failed to fetch topology");
      }
    } catch {
      setError("Failed to connect");
    } finally {
      setLoading(false);
    }
  }, []);

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

  const triggerPing = async () => {
    setPinging(true);
    try {
      const res = await fetch("/api/topology/ping", { method: "POST" });
      if (res.ok) {
        const data = await res.json();
        setTopology(data);
        setError("");
      }
    } catch {
      setError("Ping failed");
    } finally {
      setPinging(false);
    }
  };

  const nodes = topology?.nodes ?? [];
  const onlineCount = nodes.filter((n) => n.status === "online").length;
  const localCount = nodes.filter((n) => n.is_local).length;
  const cloudCount = nodes.filter((n) => !n.is_local).length;

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold text-white">Network Topology</h1>
          <p className="mt-1 text-sm text-gray-400">
            Backend connectivity map with latency indicators
          </p>
        </div>
        <div className="flex items-center gap-3">
          <div className="flex rounded-lg border border-gray-700 bg-gray-800">
            <button
              onClick={() => setViewMode("diagram")}
              className={`px-3 py-1.5 text-xs font-medium ${
                viewMode === "diagram"
                  ? "bg-indigo-600 text-white"
                  : "text-gray-400 hover:text-white"
              } rounded-l-lg`}
            >
              Diagram
            </button>
            <button
              onClick={() => setViewMode("table")}
              className={`px-3 py-1.5 text-xs font-medium ${
                viewMode === "table"
                  ? "bg-indigo-600 text-white"
                  : "text-gray-400 hover:text-white"
              } rounded-r-lg`}
            >
              Table
            </button>
          </div>
          <Button
            variant="secondary"
            size="sm"
            onClick={triggerPing}
            disabled={pinging}
          >
            <RefreshCw size={14} className={pinging ? "animate-spin" : ""} />
            {pinging ? "Pinging..." : "Ping All"}
          </Button>
        </div>
      </div>

      {error && (
        <div className="flex items-center gap-2 rounded-lg border border-red-800/50 bg-red-900/20 px-4 py-3 text-sm text-red-400">
          <AlertTriangle size={16} />
          {error}
        </div>
      )}

      {/* Stats */}
      <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
        <StatCard
          title="Total Backends"
          value={String(topology?.total_backends ?? 0)}
          icon={<Network size={20} />}
        />
        <StatCard
          title="Healthy"
          value={`${onlineCount} / ${nodes.length}`}
          changeType={
            onlineCount === nodes.length
              ? "positive"
              : onlineCount > 0
                ? "neutral"
                : "negative"
          }
          change={
            nodes.length > 0
              ? `${Math.round((onlineCount / nodes.length) * 100)}% online`
              : "No backends"
          }
          icon={<Activity size={20} />}
        />
        <StatCard
          title="Avg Latency"
          value={formatMs(topology?.avg_latency_ms ?? 0)}
          icon={<Clock size={20} />}
        />
        <StatCard
          title="Local / Cloud"
          value={`${localCount} / ${cloudCount}`}
          icon={<Server size={20} />}
        />
      </div>

      {/* Latency legend */}
      <div className="flex items-center gap-6 text-xs text-gray-400">
        <span className="font-medium text-gray-300">Latency:</span>
        <span className="flex items-center gap-1.5">
          <span className="inline-block h-2.5 w-2.5 rounded-full bg-emerald-500" />
          &lt;100ms
        </span>
        <span className="flex items-center gap-1.5">
          <span className="inline-block h-2.5 w-2.5 rounded-full bg-yellow-500" />
          100-500ms
        </span>
        <span className="flex items-center gap-1.5">
          <span className="inline-block h-2.5 w-2.5 rounded-full bg-red-500" />
          &gt;500ms
        </span>
        <span className="flex items-center gap-1.5">
          <span className="inline-block h-2.5 w-2.5 rounded-full bg-gray-600" />
          Offline
        </span>
      </div>

      {loading ? (
        <div className="py-12 text-center text-gray-500">
          Loading topology...
        </div>
      ) : nodes.length === 0 ? (
        <Card>
          <div className="py-12 text-center">
            <Network className="mx-auto mb-4 h-12 w-12 text-gray-500" />
            <p className="text-sm text-gray-400">
              No backends discovered yet. Run llmhosts serve or add cloud API keys.
            </p>
          </div>
        </Card>
      ) : viewMode === "diagram" ? (
        /* Diagram View */
        <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
          {nodes.map((node) => {
            const statusInfo = statusLabels[node.status] ?? statusLabels.offline;
            return (
              <Card
                key={node.backend_id}
                className={`border-l-4 ${bucketBorderColors[node.latency_bucket]}`}
              >
                <div className="flex items-start justify-between">
                  <div className="flex items-center gap-3">
                    <div
                      className={`flex h-10 w-10 items-center justify-center rounded-lg ${
                        node.status === "online"
                          ? "bg-emerald-900/30 text-emerald-400"
                          : node.status === "degraded"
                            ? "bg-yellow-900/30 text-yellow-400"
                            : "bg-gray-800 text-gray-500"
                      }`}
                    >
                      <BackendIcon type={node.backend_type} />
                    </div>
                    <div>
                      <h3 className="text-sm font-semibold text-gray-100">
                        {node.name}
                      </h3>
                      <p className="text-xs text-gray-500">
                        {node.backend_type}
                        {node.is_local ? " (local)" : " (cloud)"}
                      </p>
                    </div>
                  </div>
                  <div className="flex items-center gap-1.5">
                    <span
                      className={`inline-block h-2 w-2 rounded-full ${bucketColors[node.latency_bucket]}`}
                    />
                    <span className={`text-xs font-medium ${statusInfo.color}`}>
                      {statusInfo.label}
                    </span>
                  </div>
                </div>

                {/* Latency bar */}
                <div className="mt-4">
                  <div className="flex items-center justify-between text-xs text-gray-400">
                    <span>Avg latency</span>
                    <span className="font-mono font-medium text-gray-200">
                      {node.status !== "offline"
                        ? formatMs(node.latency_ms)
                        : "--"}
                    </span>
                  </div>
                  <div className="mt-1 h-1.5 overflow-hidden rounded-full bg-gray-800">
                    <div
                      className={`h-full rounded-full ${bucketColors[node.latency_bucket]}`}
                      style={{
                        width: `${Math.min(100, (node.latency_ms / 1000) * 100)}%`,
                      }}
                    />
                  </div>
                </div>

                {/* Percentiles */}
                {node.status !== "offline" && (
                  <div className="mt-3 grid grid-cols-3 gap-2 text-center">
                    <div>
                      <p className="text-[10px] uppercase text-gray-500">p50</p>
                      <p className="text-xs font-medium text-gray-300">
                        {formatMs(node.p50_ms)}
                      </p>
                    </div>
                    <div>
                      <p className="text-[10px] uppercase text-gray-500">p95</p>
                      <p className="text-xs font-medium text-gray-300">
                        {formatMs(node.p95_ms)}
                      </p>
                    </div>
                    <div>
                      <p className="text-[10px] uppercase text-gray-500">p99</p>
                      <p className="text-xs font-medium text-gray-300">
                        {formatMs(node.p99_ms)}
                      </p>
                    </div>
                  </div>
                )}

                {/* Footer */}
                <div className="mt-3 flex items-center justify-between border-t border-gray-800 pt-3">
                  <div className="flex items-center gap-1 text-xs text-gray-500">
                    <TrendIcon trend={node.trend} />
                    <span className="capitalize">{node.trend}</span>
                  </div>
                  <div className="flex items-center gap-3 text-xs text-gray-500">
                    <span>{node.models.length} models</span>
                    <span>{node.uptime_percent.toFixed(1)}% uptime</span>
                  </div>
                </div>
                <div className="mt-1 text-[10px] text-gray-500">
                  Last seen: {timeAgo(node.last_seen)}
                </div>
              </Card>
            );
          })}
        </div>
      ) : (
        /* Table View */
        <Card>
          <div className="overflow-x-auto">
            <table className="w-full text-left text-sm">
              <thead>
                <tr className="border-b border-gray-800 text-xs uppercase text-gray-500">
                  <th className="pb-3 pr-4">Backend</th>
                  <th className="pb-3 pr-4">Type</th>
                  <th className="pb-3 pr-4">Status</th>
                  <th className="pb-3 pr-4">Latency</th>
                  <th className="pb-3 pr-4">p50</th>
                  <th className="pb-3 pr-4">p95</th>
                  <th className="pb-3 pr-4">Trend</th>
                  <th className="pb-3 pr-4">Uptime</th>
                  <th className="pb-3 pr-4">Models</th>
                  <th className="pb-3">Last Seen</th>
                </tr>
              </thead>
              <tbody>
                {nodes.map((node) => {
                  const statusInfo =
                    statusLabels[node.status] ?? statusLabels.offline;
                  return (
                    <tr
                      key={node.backend_id}
                      className="border-b border-gray-800/50"
                    >
                      <td className="py-3 pr-4">
                        <div className="flex items-center gap-2">
                          <span
                            className={`inline-block h-2 w-2 rounded-full ${bucketColors[node.latency_bucket]}`}
                          />
                          <span className="font-medium text-gray-200">
                            {node.name}
                          </span>
                        </div>
                      </td>
                      <td className="py-3 pr-4 text-gray-400">
                        <span className="flex items-center gap-1.5">
                          <BackendIcon type={node.backend_type} />
                          {node.backend_type}
                        </span>
                      </td>
                      <td className="py-3 pr-4">
                        <span className={`font-medium ${statusInfo.color}`}>
                          {statusInfo.label}
                        </span>
                      </td>
                      <td className="py-3 pr-4 font-mono text-gray-300">
                        {node.status !== "offline"
                          ? formatMs(node.latency_ms)
                          : "--"}
                      </td>
                      <td className="py-3 pr-4 font-mono text-gray-400">
                        {node.status !== "offline"
                          ? formatMs(node.p50_ms)
                          : "--"}
                      </td>
                      <td className="py-3 pr-4 font-mono text-gray-400">
                        {node.status !== "offline"
                          ? formatMs(node.p95_ms)
                          : "--"}
                      </td>
                      <td className="py-3 pr-4">
                        <span className="flex items-center gap-1">
                          <TrendIcon trend={node.trend} />
                          <span className="text-xs capitalize text-gray-400">
                            {node.trend}
                          </span>
                        </span>
                      </td>
                      <td className="py-3 pr-4 text-gray-400">
                        {node.uptime_percent.toFixed(1)}%
                      </td>
                      <td className="py-3 pr-4 text-gray-400">
                        {node.models.length}
                      </td>
                      <td className="py-3 text-gray-500">
                        {timeAgo(node.last_seen)}
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </Card>
      )}
    </div>
  );
}
