"use client";

import { Suspense, useState, useEffect, useCallback, useMemo } from "react";
import { useSearchParams, useRouter } from "next/navigation";
import {
  UsageStats,
  RequestLogger,
  CardSkeleton,
  SegmentedControl,
  Card,
  Badge,
  Button,
} from "@/shared/components";
import Pagination from "@/shared/components/Pagination";
import RequestDetailsTab from "./components/RequestDetailsTab";
import { formatTokens, formatCurrency, calculateTrendData, calculateModelBreakdown } from "@/lib/usage/aggregation";
import {
  LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer,
  PieChart, Pie, Cell,
} from "recharts";

const PERIODS = [
  { value: "today", label: "Today" },
  { value: "24h", label: "24h" },
  { value: "7d", label: "7D" },
  { value: "30d", label: "30D" },
  { value: "60d", label: "60D" },
];

const DATE_PRESETS = [
  { value: "", label: "All time" },
  { value: "7d", label: "Last 7 days" },
  { value: "30d", label: "Last 30 days" },
  { value: "custom", label: "Custom range" },
];

export default function UsageClient({ isAdmin, users, currentUser }) {
  return (
    <Suspense fallback={<CardSkeleton />}>
      <UsageContent isAdmin={isAdmin} users={users} currentUser={currentUser} />
    </Suspense>
  );
}

function UsageContent({ isAdmin, users, currentUser }) {
  const searchParams = useSearchParams();
  const router = useRouter();

  const [period, setPeriod] = useState("today");

  const tabFromUrl = searchParams.get("tab");
  const activeTab = tabFromUrl && ["overview", "logs", "details", "table"].includes(tabFromUrl)
    ? tabFromUrl
    : "overview";

  const handleTabChange = (value) => {
    if (value === activeTab) return;
    const params = new URLSearchParams(searchParams);
    params.set("tab", value);
    router.push(`/dashboard/usage?${params.toString()}`, { scroll: false });
  };

  return (
    <div className="flex min-w-0 flex-col gap-6 px-1 sm:px-0">
      <div>
        <h1 className="text-2xl font-semibold">Usage Analytics</h1>
        <p className="text-sm text-text-muted mt-1">Track token usage, costs, and request history</p>
      </div>



      <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
        <SegmentedControl
          options={[
            { value: "overview", label: "Overview" },
            { value: "table", label: "Table" },
            { value: "details", label: "Details" },
          ]}
          value={activeTab}
          onChange={handleTabChange}
          className="w-full sm:w-auto"
        />
        {activeTab === "overview" && (
          <SegmentedControl
            options={PERIODS}
            value={period}
            onChange={setPeriod}
            size="sm"
            className="w-full sm:w-auto"
          />
        )}
      </div>

      {activeTab === "overview" && (
        <Suspense fallback={<CardSkeleton />}>
          <UsageStats period={period} setPeriod={setPeriod} hidePeriodSelector />
        </Suspense>
      )}
      {activeTab === "table" && (
        <UsageTableView isAdmin={isAdmin} users={users} currentUser={currentUser} />
      )}
      {activeTab === "logs" && <RequestLogger />}
      {activeTab === "details" && <RequestDetailsTab />}
    </div>
  );
}



function SortIcon({ field, currentSort, currentOrder }) {
  if (currentSort !== field) return <span className="ml-1 opacity-20">↕</span>;
  return <span className="ml-1">{currentOrder === "asc" ? "↑" : "↓"}</span>;
}

function SummaryCards({ summary }) {
  if (!summary) return null;

  const cards = [
    {
      label: "Total Tokens",
      value: formatTokens(summary.totalTokens),
      icon: "token",
    },
    {
      label: "Total Cost",
      value: formatCurrency(summary.totalCost),
      icon: "payments",
    },
    {
      label: "Requests",
      value: summary.requestCount?.toLocaleString() ?? "0",
      icon: "call_received",
    },
    {
      label: "Error Rate",
      value:
        summary.requestCount > 0
          ? `${((summary.errorCount / summary.requestCount) * 100).toFixed(1)}%`
          : "0%",
      icon: "error_outline",
    },
  ];

  return (
    <div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
      {cards.map((c) => (
        <Card key={c.label} padding="sm" className="flex flex-col gap-2">
          <div className="flex items-center gap-2 text-text-muted">
            <span className="material-symbols-outlined text-[18px]">{c.icon}</span>
            <span className="text-xs font-medium uppercase tracking-wide">{c.label}</span>
          </div>
          <span className="text-2xl font-semibold text-text-main">{c.value}</span>
        </Card>
      ))}
    </div>
  );
}

function Filters({
  isAdmin,
  users,
  currentUser,
  selectedUserId,
  setSelectedUserId,
  datePreset,
  setDatePreset,
  startDate,
  setStartDate,
  endDate,
  setEndDate,
  modelFilter,
  setModelFilter,
  modelOptions,
}) {
  const isCustomRange = datePreset === "custom";

  return (
    <div className="flex flex-wrap items-end gap-3">
      {isAdmin && users.length > 0 && (
        <div className="flex flex-col gap-1">
          <label className="text-xs text-text-muted font-medium">User</label>
          <select
            value={selectedUserId}
            onChange={(e) => setSelectedUserId(e.target.value)}
            className="h-9 px-3 rounded-[10px] border border-border-subtle bg-surface text-sm text-text-main focus:outline-none focus:ring-2 focus:ring-brand-500/20 cursor-pointer"
          >
            <option value={currentUser.id}>My usage</option>
            {users.map((u) => (
              <option key={u.id} value={u.id}>
                {u.username || u.email || u.id}
              </option>
            ))}
          </select>
        </div>
      )}

      <div className="flex flex-col gap-1">
        <label className="text-xs text-text-muted font-medium">Period</label>
        <select
          value={datePreset}
          onChange={(e) => {
            setDatePreset(e.target.value);
            if (e.target.value !== "custom") {
              setStartDate("");
              setEndDate("");
            }
          }}
          className="h-9 px-3 rounded-[10px] border border-border-subtle bg-surface text-sm text-text-main focus:outline-none focus:ring-2 focus:ring-brand-500/20 cursor-pointer"
        >
          {DATE_PRESETS.map((p) => (
            <option key={p.value} value={p.value}>
              {p.label}
            </option>
          ))}
        </select>
      </div>

      {isCustomRange && (
        <>
          <div className="flex flex-col gap-1">
            <label className="text-xs text-text-muted font-medium">From</label>
            <input
              type="date"
              value={startDate}
              onChange={(e) => setStartDate(e.target.value)}
              className="h-9 px-3 rounded-[10px] border border-border-subtle bg-surface text-sm text-text-main focus:outline-none focus:ring-2 focus:ring-brand-500/20 cursor-pointer"
            />
          </div>
          <div className="flex flex-col gap-1">
            <label className="text-xs text-text-muted font-medium">To</label>
            <input
              type="date"
              value={endDate}
              onChange={(e) => setEndDate(e.target.value)}
              className="h-9 px-3 rounded-[10px] border border-border-subtle bg-surface text-sm text-text-main focus:outline-none focus:ring-2 focus:ring-brand-500/20 cursor-pointer"
            />
          </div>
        </>
      )}

      <div className="flex flex-col gap-1">
        <label className="text-xs text-text-muted font-medium">Model</label>
        <select
          value={modelFilter}
          onChange={(e) => setModelFilter(e.target.value)}
          className="h-9 px-3 rounded-[10px] border border-border-subtle bg-surface text-sm text-text-main focus:outline-none focus:ring-2 focus:ring-brand-500/20 cursor-pointer"
        >
          <option value="">All models</option>
          {modelOptions.map((m) => (
            <option key={m} value={m}>
              {m}
            </option>
          ))}
        </select>
      </div>
    </div>
  );
}

function UsageDataTable({ records, sortBy, setSortBy, sortOrder, setSortOrder }) {
  const handleSort = (field) => {
    if (sortBy === field) {
      setSortOrder(sortOrder === "asc" ? "desc" : "asc");
    } else {
      setSortBy(field);
      setSortOrder("desc");
    }
  };

  const sorted = useMemo(() => {
    return [...records].sort((a, b) => {
      const aVal = a[sortBy];
      const bVal = b[sortBy];
      const dir = sortOrder === "asc" ? 1 : -1;
      if (typeof aVal === "string" && typeof bVal === "string") return aVal.localeCompare(bVal) * dir;
      return ((aVal ?? 0) - (bVal ?? 0)) * dir;
    });
  }, [records, sortBy, sortOrder]);

  const columns = [
    { field: "timestamp", label: "Date", align: "left" },
    { field: "model", label: "Model", align: "left" },
    { field: "inputTokens", label: "Input", align: "right" },
    { field: "outputTokens", label: "Output", align: "right" },
    { field: "cost", label: "Cost", align: "right" },
    { field: "status", label: "Status", align: "center" },
  ];

  return (
    <Card padding="none" className="overflow-hidden">
      <div className="overflow-x-auto">
        <table className="w-full text-sm text-left">
          <thead className="bg-bg-subtle/30 text-text-muted uppercase text-xs">
            <tr>
              {columns.map((col) => (
                <th
                  key={col.field}
                  className={`px-6 py-3 cursor-pointer hover:bg-bg-subtle/50 transition-colors select-none ${
                    col.align === "right" ? "text-right" : col.align === "center" ? "text-center" : ""
                  }`}
                  onClick={() => handleSort(col.field)}
                >
                  {col.label}
                  <SortIcon field={col.field} currentSort={sortBy} currentOrder={sortOrder} />
                </th>
              ))}
            </tr>
          </thead>
          <tbody className="divide-y divide-border-subtle">
            {sorted.map((r) => (
              <tr key={r.id} className="hover:bg-surface-2/50 transition-colors">
                <td className="px-6 py-3 text-text-main whitespace-nowrap">
                  {formatDateTime(r.timestamp)}
                </td>
                <td className="px-6 py-3 text-text-main">
                  <span className="font-mono text-xs">{r.model}</span>
                </td>
                <td className="px-6 py-3 text-right text-text-muted tabular-nums">
                  {r.inputTokens?.toLocaleString() ?? "—"}
                </td>
                <td className="px-6 py-3 text-right text-text-muted tabular-nums">
                  {r.outputTokens?.toLocaleString() ?? "—"}
                </td>
                <td className="px-6 py-3 text-right font-medium text-text-main tabular-nums">
                  ${(r.cost ?? 0).toFixed(4)}
                </td>
                <td className="px-6 py-3 text-center">
                  <Badge
                    variant={r.status === "error" ? "error" : "success"}
                    size="sm"
                    dot
                  >
                    {r.status ?? "ok"}
                  </Badge>
                </td>
              </tr>
            ))}
            {sorted.length === 0 && (
              <tr>
                <td colSpan={6} className="px-6 py-12 text-center text-text-muted">
                  No usage records found
                </td>
              </tr>
            )}
          </tbody>
        </table>
      </div>
    </Card>
  );
}

function formatDateTime(iso) {
  if (!iso) return "—";
  const d = new Date(iso);
  return d.toLocaleDateString(undefined, {
    month: "short",
    day: "numeric",
    hour: "2-digit",
    minute: "2-digit",
  });
}

function getDateRange(preset) {
  const now = new Date();
  const fmt = (d) => d.toISOString().split("T")[0];
  if (preset === "7d") {
    const s = new Date(now);
    s.setDate(s.getDate() - 7);
    return { startDate: fmt(s), endDate: fmt(now) };
  }
  if (preset === "30d") {
    const s = new Date(now);
    s.setDate(s.getDate() - 30);
    return { startDate: fmt(s), endDate: fmt(now) };
  }
  return { startDate: "", endDate: "" };
}

const CHART_COLORS = ["#6366f1", "#8b5cf6", "#a78bfa", "#c4b5fd", "#ddd6fe", "#ede9fe"];

function UsageCharts({ records }) {
  const [chartMode, setChartMode] = useState("tokens");
  const trendData = useMemo(() => calculateTrendData(records, 30), [records]);
  const modelData = useMemo(() => calculateModelBreakdown(records), [records]);

  const fmtYAxis = chartMode === "tokens"
    ? (v) => formatTokens(v)
    : (v) => `$${(v || 0).toFixed(2)}`;

  const fmtTooltip = (value) =>
    chartMode === "tokens" ? formatTokens(value) : `$${(value || 0).toFixed(4)}`;

  return (
    <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
      <Card padding="sm" className="flex flex-col gap-3">
        <div className="flex items-center justify-between">
          <h3 className="text-sm font-medium text-text-main">Usage Trend (30 days)</h3>
          <div className="grid w-full grid-cols-2 items-center gap-1 rounded-lg border border-border bg-bg-subtle p-1 sm:w-auto">
            <button
              onClick={() => setChartMode("tokens")}
              className={`px-3 py-1 rounded-md text-xs font-medium transition-colors ${chartMode === "tokens" ? "bg-primary text-white shadow-sm" : "text-text-muted hover:text-text hover:bg-bg-hover"}`}
            >
              Tokens
            </button>
            <button
              onClick={() => setChartMode("cost")}
              className={`px-3 py-1 rounded-md text-xs font-medium transition-colors ${chartMode === "cost" ? "bg-primary text-white shadow-sm" : "text-text-muted hover:text-text hover:bg-bg-hover"}`}
            >
              Cost
            </button>
          </div>
        </div>
        {trendData.some((d) => d.tokens > 0 || d.cost > 0) ? (
          <ResponsiveContainer width="100%" height={250}>
            <LineChart data={trendData} margin={{ top: 4, right: 8, left: 0, bottom: 0 }}>
              <CartesianGrid strokeDasharray="3 3" strokeOpacity={0.1} />
              <XAxis
                dataKey="date"
                tick={{ fontSize: 10, fill: "currentColor", fillOpacity: 0.5 }}
                tickLine={false}
                axisLine={false}
                interval="preserveStartEnd"
                tickFormatter={(d) => {
                  const dt = new Date(d + "T00:00:00");
                  return dt.toLocaleDateString(undefined, { month: "short", day: "numeric" });
                }}
              />
              <YAxis
                tick={{ fontSize: 10, fill: "currentColor", fillOpacity: 0.5 }}
                tickLine={false}
                axisLine={false}
                tickFormatter={fmtYAxis}
                width={50}
              />
              <Tooltip
                contentStyle={{
                  backgroundColor: "var(--color-bg)",
                  border: "1px solid var(--color-border)",
                  borderRadius: "8px",
                  fontSize: "12px",
                }}
                labelFormatter={(d) => {
                  const dt = new Date(d + "T00:00:00");
                  return dt.toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" });
                }}
                formatter={(value, name) => [fmtTooltip(value), name === "tokens" ? "Tokens" : "Cost"]}
              />
              <Line
                type="monotone"
                dataKey={chartMode === "tokens" ? "tokens" : "cost"}
                stroke="#6366f1"
                strokeWidth={2}
                dot={false}
                activeDot={{ r: 4, fill: "#6366f1" }}
              />
            </LineChart>
          </ResponsiveContainer>
        ) : (
          <div className="h-[250px] flex items-center justify-center text-text-muted text-sm">
            No data available
          </div>
        )}
      </Card>

      <Card padding="sm" className="flex flex-col gap-3">
        <h3 className="text-sm font-medium text-text-main">Model Breakdown</h3>
        {modelData.length > 0 ? (
          <ResponsiveContainer width="100%" height={250}>
            <PieChart>
              <Pie
                data={modelData}
                dataKey="totalTokens"
                nameKey="model"
                cx="50%"
                cy="50%"
                outerRadius={80}
                label={({ model, percent }) =>
                  model.length > 20 ? `${model.slice(0, 18)}… (${(percent * 100).toFixed(0)}%)` : `${model} (${(percent * 100).toFixed(0)}%)`
                }
                labelLine={{ strokeOpacity: 0.3 }}
              >
                {modelData.map((entry, index) => (
                  <Cell key={entry.model} fill={CHART_COLORS[index % CHART_COLORS.length]} />
                ))}
              </Pie>
              <Tooltip
                contentStyle={{
                  backgroundColor: "var(--color-bg)",
                  border: "1px solid var(--color-border)",
                  borderRadius: "8px",
                  fontSize: "12px",
                }}
                formatter={(value, name) => [formatTokens(value), name]}
              />
            </PieChart>
          </ResponsiveContainer>
        ) : (
          <div className="h-[250px] flex items-center justify-center text-text-muted text-sm">
            No data available
          </div>
        )}
      </Card>
    </div>
  );
}

function UsageTableView({ isAdmin, users, currentUser }) {
  const [selectedUserId, setSelectedUserId] = useState(currentUser?.id);
  const [datePreset, setDatePreset] = useState("");
  const [startDate, setStartDate] = useState("");
  const [endDate, setEndDate] = useState("");
  const [modelFilter, setModelFilter] = useState("");
  const [records, setRecords] = useState([]);
  const [summary, setSummary] = useState(null);
  const [page, setPage] = useState(1);
  const [totalPages, setTotalPages] = useState(1);
  const [totalItems, setTotalItems] = useState(0);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");
  const [sortBy, setSortBy] = useState("timestamp");
  const [sortOrder, setSortOrder] = useState("desc");
  const [viewMode, setViewMode] = useState("table");
  const [modelOptions, setModelOptions] = useState([]);
  const [exporting, setExporting] = useState(false);
  const pageSize = 50;

  const effectiveDates = useMemo(() => {
    if (datePreset === "custom") return { startDate, endDate };
    return getDateRange(datePreset);
  }, [datePreset, startDate, endDate]);

  const handleExport = async (format) => {
    setExporting(true);
    try {
      const params = new URLSearchParams();
      params.set("format", format);
      if (isAdmin && selectedUserId) params.set("userId", selectedUserId);
      if (effectiveDates.startDate) params.set("startDate", effectiveDates.startDate);
      if (effectiveDates.endDate) params.set("endDate", effectiveDates.endDate);
      if (modelFilter) params.set("model", modelFilter);

      const res = await fetch(`/api/usage/export?${params}`);
      if (!res.ok) throw new Error("Export failed");

      const blob = await res.blob();
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = `usage-export.${format}`;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
    } catch (err) {
      console.error("Export error:", err);
      setError(err.message || "Export failed");
    } finally {
      setExporting(false);
    }
  };

  useEffect(() => {
    setPage(1);
  }, [selectedUserId, effectiveDates.startDate, effectiveDates.endDate, modelFilter]);

  const fetchUsage = useCallback(async () => {
    setLoading(true);
    setError("");
    try {
      const params = new URLSearchParams();
      if (isAdmin && selectedUserId) params.set("userId", selectedUserId);
      if (effectiveDates.startDate) params.set("startDate", effectiveDates.startDate);
      if (effectiveDates.endDate) params.set("endDate", effectiveDates.endDate);
      if (modelFilter) params.set("model", modelFilter);
      params.set("page", page.toString());
      params.set("limit", pageSize.toString());

      const res = await fetch(`/api/usage?${params}`);
      if (!res.ok) {
        const data = await res.json().catch(() => ({}));
        throw new Error(data.error || "Failed to fetch usage");
      }
      const data = await res.json();
      setRecords(data.records || []);
      setSummary(data.summary || null);
      setTotalPages(data.totalPages || 1);
      setTotalItems(data.total || 0);

      const incoming = data.records || [];
      setModelOptions((prev) => {
        const merged = new Set([...prev, ...incoming.map((r) => r.model).filter(Boolean)]);
        return [...merged].sort();
      });
    } catch (err) {
      console.error("Failed to fetch usage:", err);
      setError(err.message);
    } finally {
      setLoading(false);
    }
  }, [isAdmin, selectedUserId, effectiveDates.startDate, effectiveDates.endDate, modelFilter, page, pageSize]);

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

  return (
    <div className="flex flex-col gap-5">
      <SummaryCards summary={summary} />

      <div className="flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between">
        <Filters
          isAdmin={isAdmin}
          users={users}
          currentUser={currentUser}
          selectedUserId={selectedUserId}
          setSelectedUserId={setSelectedUserId}
          datePreset={datePreset}
          setDatePreset={setDatePreset}
          startDate={startDate}
          setStartDate={setStartDate}
          endDate={endDate}
          setEndDate={setEndDate}
          modelFilter={modelFilter}
          setModelFilter={setModelFilter}
          modelOptions={modelOptions}
        />
        <div className="flex items-center gap-2 ml-auto">
          <Button
            variant="outline"
            size="sm"
            onClick={() => handleExport("csv")}
            disabled={exporting || records.length === 0}
            className="flex items-center gap-1.5"
          >
            {exporting ? (
              <span className="material-symbols-outlined text-[16px] animate-spin">progress_activity</span>
            ) : (
              <span className="material-symbols-outlined text-[16px]">download</span>
            )}
            CSV
          </Button>
          <Button
            variant="outline"
            size="sm"
            onClick={() => handleExport("pdf")}
            disabled={exporting || records.length === 0}
            className="flex items-center gap-1.5"
          >
            {exporting ? (
              <span className="material-symbols-outlined text-[16px] animate-spin">progress_activity</span>
            ) : (
              <span className="material-symbols-outlined text-[16px]">picture_as_pdf</span>
            )}
            PDF
          </Button>
        </div>
        <SegmentedControl
          options={[
            { value: "table", label: "Table", icon: "table_chart" },
            { value: "chart", label: "Chart", icon: "bar_chart" },
          ]}
          value={viewMode}
          onChange={setViewMode}
          size="sm"
          className="shrink-0"
        />
      </div>

      {error && (
        <Card padding="sm" className="border-red-500/30 bg-red-500/5">
          <div className="flex items-center gap-3">
            <span className="material-symbols-outlined text-red-500 text-[20px]">error</span>
            <span className="text-sm text-red-600 dark:text-red-400">{error}</span>
            <Button variant="ghost" size="sm" onClick={fetchUsage} className="ml-auto">
              Retry
            </Button>
          </div>
        </Card>
      )}

      {viewMode === "table" ? (
        <>
          <div className="relative">
            {loading && (
              <div className="absolute inset-0 z-10 flex items-center justify-center bg-surface/60 backdrop-blur-[1px] rounded-[14px]">
                <span className="material-symbols-outlined text-text-muted text-[28px] animate-spin">
                  progress_activity
                </span>
              </div>
            )}
            <UsageDataTable
              records={records}
              sortBy={sortBy}
              setSortBy={setSortBy}
              sortOrder={sortOrder}
              setSortOrder={setSortOrder}
            />
          </div>

          <Pagination
            currentPage={page}
            pageSize={pageSize}
            totalItems={totalItems}
            onPageChange={setPage}
          />
        </>
      ) : (
        <UsageCharts records={records} />
      )}
    </div>
  );
}
