import { createFileRoute, Link } from "@tanstack/react-router";
import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { useServerFn } from "@tanstack/react-start";
import { Loader2, RefreshCw, Download } from "lucide-react";
import {
  ResponsiveContainer,
  BarChart,
  Bar,
  XAxis,
  YAxis,
  Tooltip,
  Legend,
  CartesianGrid,
} from "recharts";
import { Button } from "@/components/ui/button";
import { leadAnalytics, isAdmin, type LeadAnalytics } from "@/lib/admin.functions";

export const Route = createFileRoute("/_authenticated/lead-analytics")({
  head: () => ({
    meta: [
      { title: "Lead Analytics — Gatavase Corporation" },
      {
        name: "description",
        content: "Submission outcomes, acceptance rates and failure reasons for Gatavase leads.",
      },
      { name: "robots", content: "noindex" },
      { property: "og:title", content: "Lead Analytics — Gatavase Corporation" },
      { property: "og:description", content: "Internal lead analytics dashboard." },
      { property: "og:url", content: "/lead-analytics" },
    ],
    links: [{ rel: "canonical", href: "/lead-analytics" }],
  }),
  component: LeadAnalyticsPage,
});

const WINDOWS = [
  { label: "24 hours", days: 1 },
  { label: "7 days", days: 7 },
  { label: "30 days", days: 30 },
  { label: "90 days", days: 90 },
];

const REASON_LABELS: Record<string, string> = {
  honeypot: "Bot honeypot / too fast",
  captcha: "CAPTCHA failed",
  rate_limited: "Rate limited",
  db_insert: "Database insert failed",
  validation: "Validation failed",
};

function LeadAnalyticsPage() {
  const checkAdmin = useServerFn(isAdmin);
  const fetchAnalytics = useServerFn(leadAnalytics);
  const [windowDays, setWindowDays] = useState(30);

  const adminQuery = useQuery({ queryKey: ["is-admin"], queryFn: () => checkAdmin({}) });
  const analyticsQuery = useQuery({
    queryKey: ["lead-analytics", windowDays],
    queryFn: () => fetchAnalytics({ data: { windowDays } }),
    enabled: adminQuery.data?.isAdmin === true,
  });

  if (adminQuery.isLoading) {
    return (
      <div className="grid min-h-[60vh] place-items-center">
        <Loader2 className="size-6 animate-spin text-primary" />
      </div>
    );
  }

  if (!adminQuery.data?.isAdmin) {
    return (
      <div className="mx-auto max-w-lg px-5 py-28 text-center">
        <h1 className="text-2xl font-bold">Admin access required</h1>
        <p className="mt-3 text-muted-foreground">
          Your account does not have permission to view lead analytics.
        </p>
      </div>
    );
  }

  const data = analyticsQuery.data;

  return (
    <div className="mx-auto max-w-6xl px-5 py-16">
      <div className="flex flex-wrap items-end justify-between gap-4">
        <div>
          <p className="font-mono text-xs tracking-[0.2em] text-primary uppercase">Analytics</p>
          <h1 className="mt-2 text-3xl font-bold">Lead submission analytics</h1>
          <p className="mt-2 text-sm text-muted-foreground">
            Outcomes, acceptance rate and failure reasons across the selected window.{" "}
            <Link to="/admin" className="text-primary hover:underline">
              Go to the lead dashboard
            </Link>
            .
          </p>
        </div>
        <div className="flex gap-2">
          <Button variant="outline" size="sm" onClick={() => analyticsQuery.refetch()}>
            <RefreshCw className="size-4" /> Refresh
          </Button>
          <Button
            variant="outline"
            size="sm"
            disabled={!analyticsQuery.data}
            onClick={() => analyticsQuery.data && exportCsv(analyticsQuery.data, windowDays)}
          >
            <Download className="size-4" /> Export CSV
          </Button>
        </div>
      </div>

      <div className="mt-6 flex flex-wrap gap-2">
        {WINDOWS.map((w) => (
          <Button
            key={w.days}
            size="sm"
            variant={windowDays === w.days ? "default" : "outline"}
            onClick={() => setWindowDays(w.days)}
          >
            {w.label}
          </Button>
        ))}
      </div>

      {analyticsQuery.isLoading || !data ? (
        <div className="grid h-64 place-items-center">
          <Loader2 className="size-6 animate-spin text-primary" />
        </div>
      ) : (
        <>
          <div className="mt-8 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
            <Stat label="Total attempts" value={data.totals.all} />
            <Stat label="Accepted" value={data.totals.accepted} />
            <Stat label="Rejected" value={data.totals.rejected} />
            <Stat label="Acceptance rate" value={`${data.acceptanceRate}%`} />
          </div>

          <div className="panel mt-8 p-6">
            <h2 className="text-lg font-semibold">Outcomes over time</h2>
            <div className="mt-6 h-72">
              <ResponsiveContainer width="100%" height="100%">
                <BarChart data={data.buckets}>
                  <CartesianGrid strokeDasharray="3 3" stroke="hsl(var(--border))" />
                  <XAxis dataKey="label" tick={{ fontSize: 11 }} stroke="currentColor" />
                  <YAxis allowDecimals={false} tick={{ fontSize: 11 }} stroke="currentColor" />
                  <Tooltip
                    contentStyle={{
                      background: "hsl(var(--background))",
                      border: "1px solid hsl(var(--border))",
                      borderRadius: 8,
                      fontSize: 12,
                    }}
                  />
                  <Legend wrapperStyle={{ fontSize: 12 }} />
                  <Bar dataKey="accepted" stackId="a" fill="hsl(var(--primary))" />
                  <Bar dataKey="rejected" stackId="a" fill="hsl(var(--muted-foreground))" />
                  <Bar dataKey="failed" stackId="a" fill="hsl(var(--destructive))" />
                </BarChart>
              </ResponsiveContainer>
            </div>
          </div>

          <div className="mt-8 grid gap-6 lg:grid-cols-2">
            <div className="panel p-6">
              <h2 className="text-lg font-semibold">Failure & rejection reasons</h2>
              {data.reasons.length === 0 ? (
                <p className="mt-3 text-sm text-muted-foreground">
                  No rejected or failed submissions in this window.
                </p>
              ) : (
                <ul className="mt-4 space-y-3">
                  {data.reasons.map((r) => (
                    <li key={r.reason} className="flex items-center justify-between text-sm">
                      <span>{REASON_LABELS[r.reason] ?? r.reason}</span>
                      <span className="font-mono text-muted-foreground">{r.count}</span>
                    </li>
                  ))}
                </ul>
              )}
            </div>

            <div className="panel p-6">
              <h2 className="text-lg font-semibold">Stored leads by source</h2>
              {data.sources.length === 0 ? (
                <p className="mt-3 text-sm text-muted-foreground">No stored leads in this window.</p>
              ) : (
                <ul className="mt-4 space-y-3">
                  {data.sources.map((s) => (
                    <li key={s.source} className="flex items-center justify-between text-sm">
                      <span>{s.source}</span>
                      <span className="font-mono text-muted-foreground">{s.count}</span>
                    </li>
                  ))}
                </ul>
              )}
            </div>
          </div>

          <div className="panel mt-8 overflow-x-auto p-6">
            <h2 className="text-lg font-semibold">Recent submission events</h2>
            <table className="mt-4 w-full text-left text-sm">
              <thead className="text-xs text-muted-foreground uppercase">
                <tr>
                  <th className="py-2 pr-4">When</th>
                  <th className="py-2 pr-4">Outcome</th>
                  <th className="py-2 pr-4">Reason</th>
                  <th className="py-2">Email</th>
                </tr>
              </thead>
              <tbody>
                {data.recent.map((e, i) => (
                  <tr key={`${e.created_at}-${i}`} className="border-t border-border">
                    <td className="py-2 pr-4 whitespace-nowrap">
                      {new Date(e.created_at).toLocaleString()}
                    </td>
                    <td className="py-2 pr-4">{e.outcome}</td>
                    <td className="py-2 pr-4">{e.reason ? (REASON_LABELS[e.reason] ?? e.reason) : "—"}</td>
                    <td className="py-2 break-all">{e.email || "—"}</td>
                  </tr>
                ))}
                {data.recent.length === 0 ? (
                  <tr>
                    <td colSpan={4} className="py-4 text-muted-foreground">
                      No events recorded in this window.
                    </td>
                  </tr>
                ) : null}
              </tbody>
            </table>
          </div>
        </>
      )}
    </div>
  );
}

function csvCell(value: string | number | null) {
  return `"${String(value ?? "").replace(/"/g, '""')}"`;
}

function exportCsv(data: LeadAnalytics, windowDays: number) {
  const lines: string[] = [];
  lines.push("Section,Field 1,Field 2,Field 3,Field 4");
  lines.push(
    ["Totals", "attempts", data.totals.all, "acceptance rate", `${data.acceptanceRate}%`]
      .map(csvCell)
      .join(","),
  );
  lines.push(["Totals", "accepted", data.totals.accepted, "rejected", data.totals.rejected].map(csvCell).join(","));
  lines.push(["Totals", "failed", data.totals.failed, "", ""].map(csvCell).join(","));
  for (const r of data.reasons) {
    lines.push(["Reason", r.reason, r.count, "", ""].map(csvCell).join(","));
  }
  for (const s of data.sources) {
    lines.push(["Source", s.source, s.count, "", ""].map(csvCell).join(","));
  }
  for (const b of data.buckets) {
    lines.push(["Daily", b.label, b.accepted, b.rejected, b.failed].map(csvCell).join(","));
  }
  for (const e of data.recent) {
    lines.push(["Submission", e.created_at, e.outcome, e.reason ?? "", e.email ?? ""].map(csvCell).join(","));
  }
  const blob = new Blob([lines.join("\n")], { type: "text/csv;charset=utf-8" });
  const url = URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.href = url;
  link.download = `gatavase-lead-analytics-${windowDays}d.csv`;
  document.body.append(link);
  link.click();
  link.remove();
  URL.revokeObjectURL(url);
}

function Stat({ label, value }: { label: string; value: string | number }) {
  return (
    <div className="panel p-5">
      <p className="text-xs tracking-wide text-muted-foreground uppercase">{label}</p>
      <p className="mt-2 text-2xl font-bold">{value}</p>
    </div>
  );
}
