"use client";

/**
 * Admin → Platform Analytics → Conversion Funnel
 *
 * Five-stage funnel aggregated over every TrackedSession in the
 * selected window for a brand. Drop-off percentages + source /
 * entry-page breakdowns help answer "where are we losing people
 * on the way to a conversion?" without dropping into raw SQL.
 */

import { useCallback, useEffect, useMemo, useState } from "react";
import Link from "next/link";
import {
  TrendingUp, ArrowLeft, Loader2, Users, Eye, MousePointerClick,
  ClipboardList, CheckCircle2, Globe, LayoutList,
} from "lucide-react";
import {
  PageHeader, SectionHeader, Card, CardHeader, EmptyState,
} from "@/components/admin";

// ─── Types ─────────────────────────────────────────────────────────

interface BrandOption { id: string; name: string }

interface Stage { id: number; label: string; count: number }
interface SourceRow {
  source: string;
  visits: number;
  engaged: number;
  intent: number;
  started: number;
  converted: number;
  conversionRate: number;
}
interface PageRow {
  page: string;
  visits: number;
  converted: number;
  conversionRate: number;
}

interface FunnelPayload {
  scope: { brandId: string; range: string; fromISO: string };
  stages: Stage[];
  bySource: SourceRow[];
  byEntryPage: PageRow[];
  totals: { sessions: number; conversions: number; conversionRate: number };
  error?: string;
}

type Range = "1d" | "7d" | "30d" | "90d";

const RANGES: Array<{ id: Range; label: string }> = [
  { id: "1d",  label: "Today" },
  { id: "7d",  label: "7d" },
  { id: "30d", label: "30d" },
  { id: "90d", label: "90d" },
];

// Stage colour ramp — solid at the top, gradually cooler toward
// the conversion end of the funnel. Matches the session explorer
// pill palette so the two pages feel consistent.
const STAGE_COLORS: Record<number, { bar: string; chip: string; icon: typeof Users }> = {
  1: { bar: "bg-slate-500",    chip: "bg-slate-100 text-slate-700",      icon: Users },
  2: { bar: "bg-blue-500",     chip: "bg-blue-50 text-blue-700",         icon: Eye },
  3: { bar: "bg-violet-500",   chip: "bg-violet-50 text-violet-700",     icon: ClipboardList },
  4: { bar: "bg-amber-500",    chip: "bg-amber-50 text-amber-700",       icon: MousePointerClick },
  5: { bar: "bg-emerald-500",  chip: "bg-emerald-50 text-emerald-700",   icon: CheckCircle2 },
};

// ─── Helpers ──────────────────────────────────────────────────────

function pct(part: number, whole: number): number {
  return whole > 0 ? Math.round((part / whole) * 1000) / 10 : 0;
}

// ─── Page ──────────────────────────────────────────────────────────

export default function FunnelPage() {
  const [brands, setBrands] = useState<BrandOption[]>([]);
  const [brandId, setBrandId] = useState<string>("");
  const [range, setRange] = useState<Range>("30d");
  const [data, setData] = useState<FunnelPayload | null>(null);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    fetch("/api/admin/brands?limit=500")
      .then((r) => r.ok ? r.json() : null)
      .then((d) => {
        if (Array.isArray(d?.brands)) {
          const list: BrandOption[] = d.brands.map((b: { id: string; name: string }) => ({ id: b.id, name: b.name }));
          setBrands(list);
          if (!brandId && list.length > 0) setBrandId(list[0].id);
        }
      })
      .catch(() => {});
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const load = useCallback(() => {
    if (!brandId) return;
    const params = new URLSearchParams({ brandId, range });
    setLoading(true);
    fetch(`/api/admin/analytics/funnel?${params.toString()}`)
      .then((r) => r.ok ? r.json() : null)
      .then((d: FunnelPayload | null) => setData(d))
      .finally(() => setLoading(false));
  }, [brandId, range]);

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

  const stages = data?.stages ?? [];
  const firstCount = stages[0]?.count ?? 0;

  const stageRows = useMemo(() => {
    return stages.map((s, i) => {
      const prev = i === 0 ? s.count : stages[i - 1].count;
      const dropOff = i === 0 ? 0 : prev > 0 ? Math.round(((prev - s.count) / prev) * 1000) / 10 : 0;
      const widthPct = firstCount > 0 ? (s.count / firstCount) * 100 : 0;
      const color = STAGE_COLORS[s.id] ?? STAGE_COLORS[1];
      return { ...s, dropOff, widthPct, color };
    });
  }, [stages, firstCount]);

  return (
    <div className="space-y-6">
      <PageHeader
        title="Conversion Funnel"
        subtitle="Five-stage funnel aggregated across every session for the selected brand"
        icon={TrendingUp}
        actions={
          <div className="flex items-center gap-2">
            <Link
              href="/admin/analytics"
              className="inline-flex items-center gap-1 px-2.5 py-1.5 text-[11px] font-semibold text-slate-600 bg-white border border-slate-200 rounded-lg hover:bg-slate-50"
            >
              <ArrowLeft className="w-3 h-3" /> Analytics
            </Link>
            <select
              value={brandId}
              onChange={(e) => setBrandId(e.target.value)}
              className="px-3 py-1.5 text-xs bg-white border border-slate-200 rounded-lg min-w-[220px]"
            >
              {brands.length === 0 && <option value="">Loading brands…</option>}
              {brands.map((b) => (<option key={b.id} value={b.id}>{b.name}</option>))}
            </select>
            <div className="inline-flex bg-slate-100 rounded-lg p-0.5">
              {RANGES.map((r) => (
                <button
                  key={r.id}
                  onClick={() => setRange(r.id)}
                  className={`px-2.5 py-1 text-[11px] font-semibold rounded-md transition-colors ${
                    range === r.id ? "bg-white text-slate-900 shadow-sm" : "text-slate-500 hover:text-slate-700"
                  }`}
                >{r.label}</button>
              ))}
            </div>
          </div>
        }
      />

      {/* Totals summary */}
      {data && (
        <div className="grid grid-cols-1 md:grid-cols-3 gap-3">
          <SummaryStat
            icon={Users}
            label="Sessions"
            value={data.totals.sessions.toLocaleString()}
            accent="text-slate-700"
            bg="bg-slate-100"
          />
          <SummaryStat
            icon={CheckCircle2}
            label="Conversions"
            value={data.totals.conversions.toLocaleString()}
            accent="text-emerald-700"
            bg="bg-emerald-50"
          />
          <SummaryStat
            icon={TrendingUp}
            label="Conversion rate"
            value={`${data.totals.conversionRate.toFixed(1)}%`}
            accent={data.totals.conversionRate >= 10 ? "text-emerald-700" : data.totals.conversionRate >= 2 ? "text-amber-700" : "text-slate-600"}
            bg={data.totals.conversionRate >= 10 ? "bg-emerald-50" : data.totals.conversionRate >= 2 ? "bg-amber-50" : "bg-slate-100"}
          />
        </div>
      )}

      {/* Funnel visualisation */}
      <section>
        <SectionHeader title="Funnel stages" />
        <Card>
          {loading && !data ? (
            <div className="p-8 flex items-center justify-center text-xs text-slate-500">
              <Loader2 className="w-4 h-4 animate-spin mr-2" /> Loading funnel…
            </div>
          ) : !data || firstCount === 0 ? (
            <EmptyState
              icon={TrendingUp}
              title="No sessions in range"
              description="Widen the range or confirm the Site Tag is firing for this brand."
            />
          ) : (
            <div className="p-5 space-y-3">
              {stageRows.map((s, i) => {
                const Icon = s.color.icon;
                const share = pct(s.count, firstCount);
                return (
                  <div key={s.id}>
                    <div className="flex items-center justify-between text-[11px] mb-1">
                      <div className="flex items-center gap-2">
                        <span className={`inline-flex items-center justify-center w-5 h-5 rounded text-[10px] font-bold ${s.color.chip}`}>
                          {s.id}
                        </span>
                        <Icon className="w-3.5 h-3.5 text-slate-500" />
                        <span className="font-semibold text-slate-700">{s.label}</span>
                      </div>
                      <div className="flex items-center gap-3 tabular-nums">
                        <span className="font-bold text-slate-900">{s.count.toLocaleString()}</span>
                        <span className="text-slate-500">{share.toFixed(1)}%</span>
                        {i > 0 && s.dropOff > 0 && (
                          <span className="text-[10px] text-rose-600 font-semibold">
                            −{s.dropOff.toFixed(1)}% drop
                          </span>
                        )}
                      </div>
                    </div>
                    <div className="w-full bg-slate-100 rounded-lg h-5 overflow-hidden">
                      <div
                        className={`h-full rounded-lg ${s.color.bar} transition-all`}
                        style={{ width: `${Math.max(s.widthPct, 1.5)}%` }}
                      />
                    </div>
                  </div>
                );
              })}
            </div>
          )}
        </Card>
      </section>

      {/* Source breakdown */}
      <section>
        <SectionHeader title="Funnel by source" />
        <Card>
          <CardHeader title="Top traffic sources" right={data && <span className="text-[10px] text-slate-400">{data.bySource.length} source{data.bySource.length === 1 ? "" : "s"}</span>} />
          {!data || data.bySource.length === 0 ? (
            <EmptyState icon={Globe} title="No traffic sources yet" description="No sessions with identifiable UTM / referrer data in the selected window." />
          ) : (
            <div className="overflow-x-auto">
              <table className="w-full text-xs">
                <thead className="text-[10px] font-semibold uppercase tracking-widest text-slate-400 border-b border-slate-100 bg-slate-50/40">
                  <tr>
                    <th className="text-left px-4 py-2">Source</th>
                    <th className="text-right px-4 py-2">Visits</th>
                    <th className="text-right px-4 py-2">Engaged</th>
                    <th className="text-right px-4 py-2">Intent</th>
                    <th className="text-right px-4 py-2">Started</th>
                    <th className="text-right px-4 py-2">Converted</th>
                    <th className="text-right px-4 py-2">Conv Rate</th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-slate-100">
                  {data.bySource.map((s) => (
                    <tr key={s.source} className="hover:bg-slate-50 transition-colors">
                      <td className="px-4 py-2 font-mono text-[11px] text-slate-700 truncate max-w-[240px]" title={s.source}>{s.source}</td>
                      <td className="px-4 py-2 text-right tabular-nums text-slate-700">{s.visits.toLocaleString()}</td>
                      <td className="px-4 py-2 text-right tabular-nums text-slate-500">{s.engaged.toLocaleString()}</td>
                      <td className="px-4 py-2 text-right tabular-nums text-slate-500">{s.intent.toLocaleString()}</td>
                      <td className="px-4 py-2 text-right tabular-nums text-slate-500">{s.started.toLocaleString()}</td>
                      <td className="px-4 py-2 text-right tabular-nums font-semibold text-emerald-700">{s.converted.toLocaleString()}</td>
                      <td className="px-4 py-2 text-right">
                        <span className={`inline-flex items-center justify-end px-1.5 py-0.5 rounded border text-[10px] font-bold tabular-nums ${
                          s.conversionRate >= 10 ? "bg-emerald-50 text-emerald-700 border-emerald-200"
                            : s.conversionRate >= 2 ? "bg-amber-50 text-amber-700 border-amber-200"
                            : "bg-slate-100 text-slate-600 border-slate-200"
                        }`}>
                          {s.conversionRate.toFixed(1)}%
                        </span>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </Card>
      </section>

      {/* Entry page breakdown */}
      <section>
        <SectionHeader title="Funnel by entry page" />
        <Card>
          <CardHeader title="Landing pages" right={data && <span className="text-[10px] text-slate-400">{data.byEntryPage.length} page{data.byEntryPage.length === 1 ? "" : "s"}</span>} />
          {!data || data.byEntryPage.length === 0 ? (
            <EmptyState icon={LayoutList} title="No entry pages yet" description="No sessions recorded for the selected window." />
          ) : (
            <div className="overflow-x-auto">
              <table className="w-full text-xs">
                <thead className="text-[10px] font-semibold uppercase tracking-widest text-slate-400 border-b border-slate-100 bg-slate-50/40">
                  <tr>
                    <th className="text-left px-4 py-2">Entry Page</th>
                    <th className="text-right px-4 py-2">Visits</th>
                    <th className="text-right px-4 py-2">Converted</th>
                    <th className="text-right px-4 py-2">Conv Rate</th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-slate-100">
                  {data.byEntryPage.map((p) => (
                    <tr key={p.page} className="hover:bg-slate-50 transition-colors">
                      <td className="px-4 py-2 font-mono text-[11px] text-brand-600 truncate max-w-[320px]" title={p.page}>{p.page}</td>
                      <td className="px-4 py-2 text-right tabular-nums text-slate-700">{p.visits.toLocaleString()}</td>
                      <td className="px-4 py-2 text-right tabular-nums font-semibold text-emerald-700">{p.converted.toLocaleString()}</td>
                      <td className="px-4 py-2 text-right">
                        <span className={`inline-flex items-center justify-end px-1.5 py-0.5 rounded border text-[10px] font-bold tabular-nums ${
                          p.conversionRate >= 10 ? "bg-emerald-50 text-emerald-700 border-emerald-200"
                            : p.conversionRate >= 2 ? "bg-amber-50 text-amber-700 border-amber-200"
                            : "bg-slate-100 text-slate-600 border-slate-200"
                        }`}>
                          {p.conversionRate.toFixed(1)}%
                        </span>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </Card>
      </section>
    </div>
  );
}

function SummaryStat({
  icon: Icon, label, value, accent, bg,
}: {
  icon: typeof Users;
  label: string;
  value: string;
  accent: string;
  bg: string;
}) {
  return (
    <div className="bg-white rounded-xl border border-slate-200 px-4 py-4">
      <div className="flex items-center gap-2 mb-2">
        <span className={`w-7 h-7 rounded-lg ${bg} ${accent} flex items-center justify-center`}>
          <Icon className="w-3.5 h-3.5" />
        </span>
        <p className="text-[10px] font-bold uppercase tracking-widest text-slate-500">{label}</p>
      </div>
      <p className={`text-2xl font-bold tabular-nums leading-none ${accent}`}>{value}</p>
    </div>
  );
}
