"use client";

/**
 * Admin → Data Export — premium operations-center surface.
 *
 * Each export rendered as a card with an icon chip, file-type
 * indicator, description, and a download CTA that flips to a
 * loading state while the file is being generated. After a
 * successful download the card stamps "Last exported X ago" +
 * record count + KB.
 */

import { useState } from "react";
import {
  Download, Loader2, Database, Users as UsersIcon, Globe, TrendingUp,
  FileJson, FileSpreadsheet, ArrowRight,
} from "lucide-react";
import { PageHeader, Card, CardHeader } from "@/components/admin";

interface ExportCard {
  id: "platform-metrics" | "user-data" | "brand-data" | "growth-data";
  title: string;
  description: string;
  icon: typeof Database;
  endpoint: string;
  fileExt: "csv" | "json";
  /** Approximate row count we expect for the data dictionary
   *  hint — purely informational. */
  hint: string;
}

const CARDS: ExportCard[] = [
  {
    id: "platform-metrics",
    title: "Platform Metrics",
    description: "Headline totals + DAU/WAU/MAU + 30d deltas. Sourced from the latest monthly snapshot, falling back to live aggregation.",
    icon: Database,
    endpoint: "/api/admin/export/platform-metrics?format=csv",
    fileExt: "csv",
    hint: "~25 metric rows + dictionary",
  },
  {
    id: "user-data",
    title: "User Data (Anonymized)",
    description: "Per-user signup date, brand count, last login, feature-adoption score. UserId hashed; no email, name, or avatar.",
    icon: UsersIcon,
    endpoint: "/api/admin/export/user-data",
    fileExt: "csv",
    hint: "1 row per user account",
  },
  {
    id: "brand-data",
    title: "Brand Data",
    description: "Per-brand plan, member count, event/session/conversion totals, latest audit score, feature adoption, last activity.",
    icon: Globe,
    endpoint: "/api/admin/export/brand-data",
    fileExt: "csv",
    hint: "1 row per brand",
  },
  {
    id: "growth-data",
    title: "Growth Time Series",
    description: "Trailing 24 months of new users, new brands, events, sessions, conversions, AI calls, site tags deployed.",
    icon: TrendingUp,
    endpoint: "/api/admin/export/growth-data",
    fileExt: "csv",
    hint: "24 rows · monthly buckets",
  },
];

interface ExportRecord {
  generatedAt: string;
  recordCount?: number;
  bytes: number;
}

function formatBytes(b: number): string {
  if (b < 1024) return `${b} B`;
  if (b < 1024 * 1024) return `${(b / 1024).toFixed(1)} KB`;
  return `${(b / 1024 / 1024).toFixed(2)} MB`;
}

function formatRelative(iso: string): string {
  try {
    const sec = Math.floor((Date.now() - new Date(iso).getTime()) / 1000);
    if (sec < 60) return "just now";
    if (sec < 3600) return `${Math.floor(sec / 60)}m ago`;
    if (sec < 86_400) return `${Math.floor(sec / 3600)}h ago`;
    return `${Math.floor(sec / 86_400)}d ago`;
  } catch { return ""; }
}

export default function AdminExportPage() {
  const [busy, setBusy] = useState<string | null>(null);
  const [records, setRecords] = useState<Record<string, ExportRecord>>({});
  const [error, setError] = useState<string | null>(null);

  async function run(card: ExportCard) {
    setBusy(card.id);
    setError(null);
    try {
      const res = await fetch(card.endpoint);
      if (!res.ok) throw new Error(`Server returned ${res.status}`);
      const blob = await res.blob();
      let recordCount: number | undefined;
      if (card.fileExt === "csv") {
        const text = await blob.text();
        const lines = text.split("\n").filter((l) => l.trim().length > 0);
        recordCount = Math.max(0, lines.length - 1);
        const refreshed = new Blob([text], { type: "text/csv" });
        triggerDownload(refreshed, `${card.id}-${new Date().toISOString().slice(0, 10)}.${card.fileExt}`);
      } else {
        triggerDownload(blob, `${card.id}-${new Date().toISOString().slice(0, 10)}.${card.fileExt}`);
      }
      setRecords((prev) => ({
        ...prev,
        [card.id]: { generatedAt: new Date().toISOString(), recordCount, bytes: blob.size },
      }));
    } catch (e) {
      setError(e instanceof Error ? e.message : "Export failed");
    } finally { setBusy(null); }
  }

  return (
    <div className="space-y-6 transition-opacity duration-200">
      <PageHeader
        title="Data Export"
        subtitle="One-click data-room exports — every download streams straight to your browser."
        icon={Download}
      />

      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
        {CARDS.map((card) => {
          const record = records[card.id];
          const Icon = card.icon;
          const FileIcon = card.fileExt === "json" ? FileJson : FileSpreadsheet;
          const isBusy = busy === card.id;

          return (
            <Card key={card.id} className="overflow-hidden">
              <div className="p-5 flex flex-col h-full">
                <div className="flex items-start gap-3 mb-3">
                  <span className="w-10 h-10 rounded-xl bg-gradient-to-br from-slate-100 to-slate-200 text-slate-600 flex items-center justify-center shrink-0">
                    <Icon className="w-5 h-5" />
                  </span>
                  <div className="flex-1 min-w-0">
                    <div className="flex items-center gap-2">
                      <h2 className="text-sm font-semibold text-slate-900 truncate">{card.title}</h2>
                      <span className="inline-flex items-center gap-1 text-[9px] font-bold uppercase tracking-widest text-slate-500 bg-slate-100 rounded px-1.5 py-0.5">
                        <FileIcon className="w-2.5 h-2.5" />
                        {card.fileExt}
                      </span>
                    </div>
                    <p className="text-[11px] text-slate-400 mt-0.5">{card.hint}</p>
                  </div>
                </div>

                <p className="text-xs text-slate-500 leading-relaxed flex-1 mb-4">{card.description}</p>

                {/* Loading indicator — replaces the description line during generation */}
                {isBusy && (
                  <div className="mb-3 px-3 py-2 rounded-lg bg-blue-50 border border-blue-100 flex items-center gap-2">
                    <Loader2 className="w-3.5 h-3.5 animate-spin text-blue-600" />
                    <span className="text-[11px] text-blue-700 font-semibold">Generating…</span>
                    {/* Indeterminate progress bar */}
                    <span className="ml-auto block w-16 h-1 bg-blue-200 rounded-full overflow-hidden">
                      <span className="block w-1/3 h-full bg-blue-500 rounded-full animate-pulse" />
                    </span>
                  </div>
                )}

                <div className="flex items-center gap-3">
                  <button
                    onClick={() => run(card)}
                    disabled={isBusy}
                    className="inline-flex items-center gap-1.5 px-4 py-2 rounded-lg bg-brand-600 text-white text-xs font-semibold hover:bg-brand-700 disabled:opacity-50"
                  >
                    {isBusy ? <Loader2 className="w-3.5 h-3.5 animate-spin" /> : <Download className="w-3.5 h-3.5" />}
                    Download
                    <ArrowRight className="w-3 h-3 opacity-50" />
                  </button>
                  {record && (
                    <div className="text-[11px] text-slate-500">
                      Last run <span className="font-semibold text-slate-700">{formatRelative(record.generatedAt)}</span>
                      {record.recordCount != null && <span className="ml-1.5">· <span className="font-semibold text-slate-700">{record.recordCount.toLocaleString()}</span> rows</span>}
                      <span className="ml-1.5">· {formatBytes(record.bytes)}</span>
                    </div>
                  )}
                </div>
              </div>
            </Card>
          );
        })}
      </div>

      {error && (
        <div className="rounded-xl border border-rose-200 bg-rose-50 px-4 py-3 text-xs text-rose-700">{error}</div>
      )}

      <Card>
        <CardHeader title="Data dictionary" />
        <div className="p-4 text-xs text-slate-600 leading-relaxed">
          Every export ships with a stable column shape. The Platform Metrics export
          includes a <code className="font-mono text-slate-700">dictionary</code> object documenting
          each field. The other three exports use self-describing CSV headers (brandId, plan, eventCount, etc.).
          Reach out before changing column names — downstream investor decks reference these directly.
        </div>
      </Card>
    </div>
  );
}

function triggerDownload(blob: Blob, filename: string) {
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = filename;
  a.click();
  URL.revokeObjectURL(url);
}
