"use client";

import { useState, useEffect, useCallback, useMemo } from "react";
import { StatCard } from "@/components/ui/stat-card";
import { Card } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { DataTable, type Column } from "@/components/ui/data-table";
import {
  Database,
  Layers,
  Zap,
  Brain,
  Trash2,
  RefreshCw,
  ChevronDown,
  ChevronRight,
  AlertTriangle,
} from "lucide-react";
import {
  PieChart,
  Pie,
  BarChart,
  Bar,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  ResponsiveContainer,
  Cell,
  Legend,
} from "recharts";

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

interface CacheTierStats {
  tier: string;
  name: string;
  enabled: boolean;
  total_entries: number;
  total_size_bytes: number;
  hit_count: number;
  miss_count: number;
  hit_rate: number;
  entries_by_model: Record<string, number>;
  false_positive_rate: number | null;
  delta_target: number | null;
  avg_threshold: number | null;
  min_threshold: number | null;
  max_threshold: number | null;
  threshold_distribution: Record<string, number> | null;
  total_namespaces: number | null;
  entries_by_namespace: Record<string, number> | null;
  hit_rate_by_namespace: Record<string, number> | null;
}

interface CacheStatsData {
  tiers_active: string[];
  combined_hit_rate: number;
  total_entries: number;
  total_size_bytes: number;
  tiers: CacheTierStats[];
}

interface CacheEntryRow {
  cache_key: string;
  tier: string;
  model: string;
  hit_count: number;
  size_bytes: number;
  created_at: string;
  expires_at: string;
  namespace: string | null;
}

interface NamespaceItem {
  namespace_key: string;
  entry_count: number;
  hit_rate: number;
}

// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------

const TIER_COLORS: Record<string, string> = {
  exact: "#10b981",
  namespace: "#8b5cf6",
  vcache: "#3b82f6",
};

const TIER_ICONS: Record<string, React.ReactNode> = {
  exact: <Database size={20} />,
  namespace: <Layers size={20} />,
  vcache: <Brain size={20} />,
};

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

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 formatRate(rate: number): string {
  return `${(rate * 100).toFixed(1)}%`;
}

// ---------------------------------------------------------------------------
// Component
// ---------------------------------------------------------------------------

export default function CacheManagementPage() {
  const [stats, setStats] = useState<CacheStatsData | null>(null);
  const [entries, setEntries] = useState<CacheEntryRow[]>([]);
  const [entriesTotal, setEntriesTotal] = useState(0);
  const [namespaces, setNamespaces] = useState<NamespaceItem[]>([]);
  const [loading, setLoading] = useState(true);
  const [activeTier, setActiveTier] = useState("exact");
  const [expandedNs, setExpandedNs] = useState<string | null>(null);
  const [invalidating, setInvalidating] = useState(false);
  const [confirmClear, setConfirmClear] = useState(false);
  const [error, setError] = useState("");
  const [successMsg, setSuccessMsg] = useState("");

  // Fetch all data
  const fetchStats = useCallback(async () => {
    try {
      const res = await fetch("/api/cache/stats");
      if (res.ok) {
        const data = await res.json();
        setStats(data);
      }
    } catch {
      // graceful fallback
    }
  }, []);

  const fetchEntries = useCallback(
    async (tier: string) => {
      try {
        const res = await fetch(
          `/api/cache/entries?tier=${tier}&limit=50&offset=0`
        );
        if (res.ok) {
          const data = await res.json();
          setEntries(data.entries);
          setEntriesTotal(data.total);
        }
      } catch {
        // graceful fallback
      }
    },
    []
  );

  const fetchNamespaces = useCallback(async () => {
    try {
      const res = await fetch("/api/cache/namespaces");
      if (res.ok) {
        const data = await res.json();
        setNamespaces(data.namespaces);
      }
    } catch {
      // graceful fallback
    }
  }, []);

  const refreshAll = useCallback(async () => {
    setLoading(true);
    await Promise.all([fetchStats(), fetchEntries(activeTier), fetchNamespaces()]);
    setLoading(false);
  }, [fetchStats, fetchEntries, activeTier, fetchNamespaces]);

  useEffect(() => {
    refreshAll();
  }, [refreshAll]);

  useEffect(() => {
    fetchEntries(activeTier);
  }, [activeTier, fetchEntries]);

  // Invalidation handlers
  const handleInvalidateEntry = async (cacheKey: string) => {
    setError("");
    try {
      const res = await fetch("/api/cache/invalidate", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ cache_keys: [cacheKey] }),
      });
      if (res.ok) {
        const data = await res.json();
        setSuccessMsg(`Removed ${data.removed} entry`);
        setTimeout(() => setSuccessMsg(""), 3000);
        refreshAll();
      } else {
        setError("Failed to invalidate entry");
      }
    } catch {
      setError("Failed to invalidate entry");
    }
  };

  const handleClearAll = async () => {
    setInvalidating(true);
    setError("");
    try {
      const res = await fetch("/api/cache/invalidate", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ clear_all: true }),
      });
      if (res.ok) {
        const data = await res.json();
        setSuccessMsg(`Cleared ${data.removed} entries from all tiers`);
        setTimeout(() => setSuccessMsg(""), 3000);
        setConfirmClear(false);
        refreshAll();
      } else {
        setError("Failed to clear cache");
      }
    } catch {
      setError("Failed to clear cache");
    } finally {
      setInvalidating(false);
    }
  };

  const handleInvalidateNamespace = async (nsKey: string) => {
    setError("");
    try {
      const res = await fetch("/api/cache/invalidate", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ namespace: nsKey }),
      });
      if (res.ok) {
        const data = await res.json();
        setSuccessMsg(`Removed ${data.removed} entries from namespace`);
        setTimeout(() => setSuccessMsg(""), 3000);
        refreshAll();
      } else {
        setError("Failed to invalidate namespace");
      }
    } catch {
      setError("Failed to invalidate namespace");
    }
  };

  // Chart data
  const savingsByTier = useMemo(() => {
    if (!stats) return [];
    return stats.tiers.map((t) => ({
      name: t.name.replace(/^Tier \d+: /, ""),
      entries: t.total_entries,
      hitRate: t.hit_rate,
      hits: t.hit_count,
    }));
  }, [stats]);

  const hitRateByTier = useMemo(() => {
    if (!stats) return [];
    return stats.tiers.map((t) => ({
      name: t.name.replace(/^Tier \d+: /, ""),
      value: Math.round(t.hit_rate * 10000) / 100,
      fill: TIER_COLORS[t.tier] || "#6b7280",
    }));
  }, [stats]);

  const entriesByModelData = useMemo(() => {
    if (!stats) return [];
    const combined: Record<string, number> = {};
    for (const t of stats.tiers) {
      for (const [model, count] of Object.entries(t.entries_by_model || {})) {
        combined[model] = (combined[model] || 0) + count;
      }
    }
    return Object.entries(combined)
      .map(([model, count]) => ({ model, count }))
      .sort((a, b) => b.count - a.count)
      .slice(0, 10);
  }, [stats]);

  // Entry table columns
  const entryColumns: Column<CacheEntryRow>[] = [
    {
      key: "cache_key",
      header: "Key",
      render: (row) => (
        <code className="text-xs text-gray-400">{row.cache_key.slice(0, 16)}...</code>
      ),
    },
    { key: "model", header: "Model" },
    {
      key: "hit_count",
      header: "Hits",
      render: (row) => (
        <span className="font-medium text-gray-100">{row.hit_count}</span>
      ),
    },
    {
      key: "size_bytes",
      header: "Size",
      render: (row) => formatBytes(row.size_bytes),
    },
    {
      key: "created_at",
      header: "Created",
      render: (row) =>
        row.created_at
          ? new Date(row.created_at).toLocaleString()
          : "-",
    },
  ];

  if (activeTier === "namespace" || activeTier === "vcache") {
    entryColumns.splice(2, 0, {
      key: "namespace",
      header: "Namespace",
      render: (row) => (
        <span className="text-xs text-indigo-400">
          {row.namespace || "__default__"}
        </span>
      ),
    });
  }

  return (
    <div className="space-y-8">
      {/* Page header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold text-gray-100">Cache Management</h1>
          <p className="mt-1 text-sm text-gray-400">
            Three-tier cache: Exact Hash, Namespace, vCache Semantic
          </p>
        </div>
        <div className="flex gap-2">
          <Button variant="secondary" size="sm" onClick={refreshAll}>
            <RefreshCw size={14} />
            Refresh
          </Button>
          {confirmClear ? (
            <div className="flex gap-2">
              <Button
                variant="danger"
                size="sm"
                onClick={handleClearAll}
                disabled={invalidating}
              >
                {invalidating ? "Clearing..." : "Confirm Clear All"}
              </Button>
              <Button
                variant="secondary"
                size="sm"
                onClick={() => setConfirmClear(false)}
              >
                Cancel
              </Button>
            </div>
          ) : (
            <Button
              variant="danger"
              size="sm"
              onClick={() => setConfirmClear(true)}
            >
              <Trash2 size={14} />
              Clear All
            </Button>
          )}
        </div>
      </div>

      {/* Alerts */}
      {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}
          <button
            onClick={() => setError("")}
            className="ml-auto text-red-400 hover:text-red-300"
          >
            Dismiss
          </button>
        </div>
      )}
      {successMsg && (
        <div className="rounded-lg border border-emerald-800/50 bg-emerald-900/20 px-4 py-3 text-sm text-emerald-400">
          {successMsg}
        </div>
      )}

      {loading ? (
        <p className="py-8 text-center text-sm text-gray-500">Loading cache statistics...</p>
      ) : (
        <>
          {/* Summary stat cards */}
          <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
            <StatCard
              title="Combined Hit Rate"
              value={formatRate(stats?.combined_hit_rate ?? 0)}
              change={`${stats?.tiers_active.length ?? 0} tiers active`}
              changeType="positive"
              icon={<Zap size={20} />}
            />
            <StatCard
              title="Total Entries"
              value={String(stats?.total_entries ?? 0)}
              change="Across all tiers"
              changeType="neutral"
              icon={<Database size={20} />}
            />
            <StatCard
              title="Total Size"
              value={formatBytes(stats?.total_size_bytes ?? 0)}
              change="Response data cached"
              changeType="neutral"
              icon={<Layers size={20} />}
            />
            <StatCard
              title="Active Tiers"
              value={stats?.tiers_active.join(", ") ?? "None"}
              change="exact -> namespace -> vcache"
              changeType="neutral"
              icon={<Brain size={20} />}
            />
          </div>

          {/* Per-tier cards */}
          <div className="grid gap-4 lg:grid-cols-3">
            {(stats?.tiers ?? []).map((tier) => (
              <Card
                key={tier.tier}
                title={tier.name}
                icon={TIER_ICONS[tier.tier]}
              >
                <div className="space-y-3">
                  <div className="grid grid-cols-2 gap-3">
                    <div>
                      <p className="text-xs text-gray-500">Hit Rate</p>
                      <p className="text-lg font-bold text-gray-100">
                        {formatRate(tier.hit_rate)}
                      </p>
                    </div>
                    <div>
                      <p className="text-xs text-gray-500">Entries</p>
                      <p className="text-lg font-bold text-gray-100">
                        {tier.total_entries}
                      </p>
                    </div>
                    {tier.total_size_bytes > 0 && (
                      <div>
                        <p className="text-xs text-gray-500">Size</p>
                        <p className="text-sm font-medium text-gray-300">
                          {formatBytes(tier.total_size_bytes)}
                        </p>
                      </div>
                    )}
                    {tier.hit_count + tier.miss_count > 0 && (
                      <div>
                        <p className="text-xs text-gray-500">Hits / Misses</p>
                        <p className="text-sm font-medium text-gray-300">
                          {tier.hit_count} / {tier.miss_count}
                        </p>
                      </div>
                    )}
                  </div>

                  {/* vCache-specific stats */}
                  {tier.tier === "vcache" && tier.false_positive_rate !== null && (
                    <div className="border-t border-gray-800 pt-3">
                      <div className="grid grid-cols-2 gap-3">
                        <div>
                          <p className="text-xs text-gray-500">FP Rate</p>
                          <p className="text-sm font-medium text-gray-300">
                            {(tier.false_positive_rate * 100).toFixed(3)}%
                          </p>
                        </div>
                        <div>
                          <p className="text-xs text-gray-500">Delta Target</p>
                          <p className="text-sm font-medium text-gray-300">
                            {tier.delta_target !== null
                              ? `${(tier.delta_target * 100).toFixed(1)}%`
                              : "-"}
                          </p>
                        </div>
                        {tier.avg_threshold !== null && (
                          <div>
                            <p className="text-xs text-gray-500">Avg Threshold</p>
                            <p className="text-sm font-medium text-gray-300">
                              {tier.avg_threshold.toFixed(4)}
                            </p>
                          </div>
                        )}
                        {tier.min_threshold !== null &&
                          tier.max_threshold !== null && (
                            <div>
                              <p className="text-xs text-gray-500">
                                Threshold Range
                              </p>
                              <p className="text-sm font-medium text-gray-300">
                                {tier.min_threshold.toFixed(3)} -{" "}
                                {tier.max_threshold.toFixed(3)}
                              </p>
                            </div>
                          )}
                      </div>
                    </div>
                  )}

                  {/* Namespace-specific stats */}
                  {tier.tier === "namespace" && tier.total_namespaces !== null && (
                    <div className="border-t border-gray-800 pt-3">
                      <p className="text-xs text-gray-500">
                        {tier.total_namespaces} namespace buckets
                      </p>
                    </div>
                  )}

                  {/* Hit rate visual bar */}
                  <div className="h-2 w-full overflow-hidden rounded-full bg-gray-800">
                    <div
                      className="h-full rounded-full transition-all duration-500"
                      style={{
                        width: `${Math.min(tier.hit_rate * 100, 100)}%`,
                        backgroundColor: TIER_COLORS[tier.tier] || "#6b7280",
                      }}
                    />
                  </div>
                </div>
              </Card>
            ))}

            {/* Show placeholder cards for inactive tiers */}
            {(stats?.tiers.length ?? 0) === 0 && (
              <Card title="No Cache Tiers Active">
                <p className="text-sm text-gray-500">
                  Cache system is not initialized. Start the LLMHosts proxy to
                  activate caching.
                </p>
              </Card>
            )}
          </div>

          {/* Charts row */}
          {(stats?.tiers.length ?? 0) > 0 && (
            <div className="grid gap-4 lg:grid-cols-2">
              {/* Hit Rate by Tier - Pie Chart */}
              <Card
                title="Hit Rate by Tier"
                description="Percentage of requests served from cache per tier"
              >
                {hitRateByTier.length > 0 ? (
                  <ResponsiveContainer width="100%" height={280}>
                    <PieChart>
                      <Pie
                        data={hitRateByTier}
                        cx="50%"
                        cy="50%"
                        labelLine={false}
                        label={(entry) => `${entry.name} ${entry.value}%`}
                        outerRadius={80}
                        dataKey="value"
                      >
                        {hitRateByTier.map((entry, index) => (
                          <Cell key={`cell-${index}`} fill={entry.fill} />
                        ))}
                      </Pie>
                      <Tooltip
                        contentStyle={{
                          backgroundColor: "#1f2937",
                          border: "1px solid #374151",
                          borderRadius: "6px",
                          color: "#f3f4f6",
                        }}
                        formatter={(value) => `${value}%`}
                      />
                    </PieChart>
                  </ResponsiveContainer>
                ) : (
                  <p className="py-8 text-center text-sm text-gray-500">
                    No hit rate data yet
                  </p>
                )}
              </Card>

              {/* Entries by Model - Bar Chart */}
              <Card
                title="Entries by Model"
                description="Top models across all cache tiers"
              >
                {entriesByModelData.length > 0 ? (
                  <ResponsiveContainer width="100%" height={280}>
                    <BarChart data={entriesByModelData} layout="vertical">
                      <CartesianGrid strokeDasharray="3 3" stroke="#374151" />
                      <XAxis type="number" stroke="#9ca3af" style={{ fontSize: "12px" }} />
                      <YAxis
                        dataKey="model"
                        type="category"
                        stroke="#9ca3af"
                        style={{ fontSize: "11px" }}
                        width={120}
                        tickFormatter={(value: string) =>
                          value.length > 18 ? value.slice(0, 18) + "..." : value
                        }
                      />
                      <Tooltip
                        contentStyle={{
                          backgroundColor: "#1f2937",
                          border: "1px solid #374151",
                          borderRadius: "6px",
                          color: "#f3f4f6",
                        }}
                      />
                      <Bar dataKey="count" fill="#8b5cf6" radius={[0, 4, 4, 0]} />
                    </BarChart>
                  </ResponsiveContainer>
                ) : (
                  <p className="py-8 text-center text-sm text-gray-500">
                    No model data yet
                  </p>
                )}
              </Card>
            </div>
          )}

          {/* Cache size by tier bar chart */}
          {savingsByTier.length > 0 && (
            <Card
              title="Entries per Tier"
              description="Total cached entries and hit counts per tier"
            >
              <ResponsiveContainer width="100%" height={250}>
                <BarChart data={savingsByTier}>
                  <CartesianGrid strokeDasharray="3 3" stroke="#374151" />
                  <XAxis dataKey="name" stroke="#9ca3af" style={{ fontSize: "12px" }} />
                  <YAxis stroke="#9ca3af" style={{ fontSize: "12px" }} />
                  <Tooltip
                    contentStyle={{
                      backgroundColor: "#1f2937",
                      border: "1px solid #374151",
                      borderRadius: "6px",
                      color: "#f3f4f6",
                    }}
                  />
                  <Legend wrapperStyle={{ color: "#9ca3af", fontSize: "12px" }} />
                  <Bar dataKey="entries" name="Entries" fill="#10b981" radius={[4, 4, 0, 0]} />
                  <Bar dataKey="hits" name="Hits" fill="#3b82f6" radius={[4, 4, 0, 0]} />
                </BarChart>
              </ResponsiveContainer>
            </Card>
          )}

          {/* Namespace browser */}
          {namespaces.length > 0 && (
            <Card
              title="Namespace Browser"
              icon={<Layers size={20} />}
              description="Explore entity-aware namespace buckets (Tier 1)"
            >
              <div className="space-y-1">
                {namespaces.map((ns) => (
                  <div key={ns.namespace_key}>
                    <button
                      onClick={() =>
                        setExpandedNs(
                          expandedNs === ns.namespace_key
                            ? null
                            : ns.namespace_key
                        )
                      }
                      className="flex w-full items-center gap-3 rounded-lg px-3 py-2 text-left transition-colors hover:bg-gray-800/50"
                    >
                      {expandedNs === ns.namespace_key ? (
                        <ChevronDown size={16} className="text-gray-500" />
                      ) : (
                        <ChevronRight size={16} className="text-gray-500" />
                      )}
                      <span className="flex-1 font-mono text-sm text-indigo-400">
                        {ns.namespace_key}
                      </span>
                      <span className="text-xs text-gray-500">
                        {ns.entry_count} entries
                      </span>
                      <span className="text-xs text-gray-500">
                        {formatRate(ns.hit_rate)} hit rate
                      </span>
                    </button>
                    {expandedNs === ns.namespace_key && (
                      <div className="ml-8 rounded-lg border border-gray-800 bg-gray-800/30 p-3">
                        <div className="flex items-center justify-between">
                          <div className="grid grid-cols-3 gap-4 text-sm">
                            <div>
                              <p className="text-xs text-gray-500">Entries</p>
                              <p className="font-medium text-gray-200">
                                {ns.entry_count}
                              </p>
                            </div>
                            <div>
                              <p className="text-xs text-gray-500">Hit Rate</p>
                              <p className="font-medium text-gray-200">
                                {formatRate(ns.hit_rate)}
                              </p>
                            </div>
                            <div>
                              <p className="text-xs text-gray-500">Key</p>
                              <p className="font-mono text-xs text-gray-400 break-all">
                                {ns.namespace_key}
                              </p>
                            </div>
                          </div>
                          <Button
                            variant="danger"
                            size="sm"
                            onClick={() =>
                              handleInvalidateNamespace(ns.namespace_key)
                            }
                          >
                            <Trash2 size={14} />
                            Clear
                          </Button>
                        </div>
                      </div>
                    )}
                  </div>
                ))}
              </div>
            </Card>
          )}

          {/* Entry browser */}
          <Card
            title="Cache Entries"
            description={`Browsing ${activeTier} tier (${entriesTotal} total)`}
          >
            {/* Tier tab selector */}
            <div className="mb-4 flex gap-2">
              {["exact", "namespace", "vcache"].map((tier) => (
                <button
                  key={tier}
                  onClick={() => setActiveTier(tier)}
                  className={`rounded-lg px-3 py-1.5 text-sm font-medium transition-colors ${
                    activeTier === tier
                      ? "bg-indigo-500/20 text-indigo-400"
                      : "text-gray-400 hover:bg-gray-800 hover:text-gray-200"
                  }`}
                >
                  {tier === "exact"
                    ? "Exact Hash"
                    : tier === "namespace"
                      ? "Namespace"
                      : "vCache"}
                </button>
              ))}
            </div>

            <DataTable<CacheEntryRow>
              columns={entryColumns}
              data={entries}
              keyExtractor={(row) => row.cache_key}
              emptyMessage={`No ${activeTier} cache entries yet.`}
              actions={(row) => (
                <Button
                  variant="danger"
                  size="sm"
                  onClick={() => handleInvalidateEntry(row.cache_key)}
                >
                  <Trash2 size={14} />
                </Button>
              )}
            />
          </Card>
        </>
      )}
    </div>
  );
}
