"use client";

/**
 * Admin → Platform Analytics → Engagement
 *
 * DAU / WAU / MAU + DAU/MAU stickiness + feature adoption table +
 * cohort retention heatmap + activity distribution. All sourced
 * from PlatformEvent + User; no third-party deps. Designed to be
 * useful at low scale (3 users) and increasingly informative as
 * the platform grows.
 */

import { useEffect, useState } from "react";
import Link from "next/link";
import {
  Users, Activity, Loader2, AlertTriangle, RefreshCw, ArrowLeft,
  Gauge,
} from "lucide-react";
import {
  PageHeader, SectionHeader, Card, CardHeader, EmptyState, StatCard,
} from "@/components/admin";

interface ActiveUsers { dau: number; wau: number; mau: number; stickiness: number }
interface FeatureRow { action: string; category: string; users: number; sessions: number; lastUsed: string | null; pctOfUsers: number }
interface CohortWeek { index: number; retained: number; pct: number }
interface CohortRow { cohortLabel: string; cohortSize: number; weeks: CohortWeek[] }
interface ActivityDist { power: number; regular: number; occasional: number; dormant: number }
interface Payload {
  scope: { totalUsers: number; generatedAt: string };
  activeUsers: ActiveUsers;
  featureAdoption: FeatureRow[];
  cohortRetention: CohortRow[];
  activityDistribution: ActivityDist;
}

function relTime(iso: string | null): string {
  if (!iso) return "—";
  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 < 86400) return `${Math.floor(sec / 3600)}h ago`;
    return `${Math.floor(sec / 86400)}d ago`;
  } catch { return iso; }
}

function heatColor(pct: number): string {
  if (pct >= 80) return "bg-emerald-600 text-white";
  if (pct >= 60) return "bg-emerald-400 text-white";
  if (pct >= 40) return "bg-amber-300 text-amber-900";
  if (pct >= 20) return "bg-rose-300 text-rose-900";
  if (pct > 0)   return "bg-rose-500 text-white";
  return "bg-slate-100 text-slate-400";
}

export default function EngagementPage() {
  const [data, setData] = useState<Payload | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [retryKey, setRetryKey] = useState(0);

  useEffect(() => {
    setError(null);
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), 15_000);
    fetch("/api/admin/analytics/engagement", { signal: controller.signal })
      .then(async (r) => {
        if (!r.ok) {
          let msg = `HTTP ${r.status}`;
          try { const body = await r.json(); if (body?.error) msg = `${msg}: ${body.error}`; } catch {}
          throw new Error(msg);
        }
        return r.json() as Promise<Payload>;
      })
      .then(setData)
      .catch((err: Error) => {
        if (err.name === "AbortError") setError("Request timed out after 15s — try Retry.");
        else setError(err.message || "Failed to load engagement.");
      })
      .finally(() => clearTimeout(timeoutId));
    return () => { clearTimeout(timeoutId); controller.abort(); };
  }, [retryKey]);

  if (error) {
    return (
      <div className="max-w-2xl mx-auto mt-16">
        <div className="rounded-xl border border-rose-200 bg-rose-50 p-6 text-center">
          <AlertTriangle className="w-8 h-8 text-rose-500 mx-auto mb-2" />
          <h2 className="text-sm font-bold text-slate-900">Couldn&apos;t load Engagement</h2>
          <p className="text-xs text-slate-600 mt-1">{error}</p>
          <button
            onClick={() => setRetryKey((k) => k + 1)}
            className="inline-flex items-center gap-1.5 px-3 py-1.5 mt-4 rounded-lg bg-white border border-slate-200 text-xs font-semibold text-slate-700 hover:bg-slate-50"
          >
            <RefreshCw className="w-3 h-3" /> Retry
          </button>
        </div>
      </div>
    );
  }

  if (!data) {
    return <div className="flex items-center justify-center py-24"><Loader2 className="w-5 h-5 text-slate-400 animate-spin" /></div>;
  }

  const distTotal = Object.values(data.activityDistribution).reduce((s, v) => s + v, 0) || 1;

  return (
    <div className="space-y-6">
      <PageHeader
        title="Engagement"
        subtitle={`${data.scope.totalUsers.toLocaleString()} total users · ${data.featureAdoption.length} active features in the last 30 days`}
        icon={Users}
        actions={
          <Link href="/admin/analytics" className="inline-flex items-center gap-1 text-[11px] text-slate-600 hover:text-slate-900">
            <ArrowLeft className="w-3 h-3" />Back to Analytics
          </Link>
        }
      />

      {/* Active users — 3 KPIs + stickiness gauge */}
      <section>
        <SectionHeader title="Active users" />
        <div className="grid grid-cols-2 md:grid-cols-4 gap-3">
          <StatCard label="DAU"  value={data.activeUsers.dau.toLocaleString()}  icon={Activity} variant="compact" valueClass="text-violet-600" />
          <StatCard label="WAU"  value={data.activeUsers.wau.toLocaleString()}  icon={Activity} variant="compact" valueClass="text-indigo-600" />
          <StatCard label="MAU"  value={data.activeUsers.mau.toLocaleString()}  icon={Activity} variant="compact" valueClass="text-blue-600" />
          <StatCard
            label="Stickiness · DAU/MAU"
            value={`${data.activeUsers.stickiness}%`}
            icon={Gauge}
            variant="compact"
            valueClass={data.activeUsers.stickiness >= 30 ? "text-emerald-600" : data.activeUsers.stickiness >= 15 ? "text-amber-600" : "text-rose-600"}
          />
        </div>
        <p className="text-[11px] text-slate-500 mt-2">
          Stickiness ≥ 30% = strong (users return ~3× per week). 15-30% = average. Below 15% = mostly weekly visitors.
        </p>
      </section>

      {/* Activity distribution */}
      <section>
        <SectionHeader title="Activity distribution" />
        <Card>
          <div className="p-5 grid grid-cols-1 md:grid-cols-4 gap-3">
            <DistCell label="Power"      hint="active in 24h"  count={data.activityDistribution.power}      total={distTotal} color="bg-emerald-500" />
            <DistCell label="Regular"    hint="active in 7d"   count={data.activityDistribution.regular}    total={distTotal} color="bg-blue-500" />
            <DistCell label="Occasional" hint="active in 30d"  count={data.activityDistribution.occasional} total={distTotal} color="bg-amber-500" />
            <DistCell label="Dormant"    hint="no activity 30d+" count={data.activityDistribution.dormant}    total={distTotal} color="bg-rose-500" />
          </div>
        </Card>
      </section>

      {/* Feature adoption */}
      <section>
        <SectionHeader title="Feature adoption" right={<span className="text-[10px] text-slate-400">last 30 days · top 25 by users</span>} />
        <Card>
          {data.featureAdoption.length === 0 ? (
            <EmptyState icon={Activity} title="No feature usage yet" description="PlatformEvent rows will populate this table as users interact with features." />
          ) : (
            <table className="w-full text-xs">
              <thead className="text-[10px] font-bold uppercase tracking-widest text-slate-400 border-b border-slate-100 bg-slate-50/40">
                <tr>
                  <th className="text-left px-4 py-2">Feature</th>
                  <th className="text-left px-4 py-2">Category</th>
                  <th className="text-right px-4 py-2">Users</th>
                  <th className="text-right px-4 py-2">% of users</th>
                  <th className="text-right px-4 py-2">Sessions</th>
                  <th className="text-right px-4 py-2">Last used</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-slate-100">
                {data.featureAdoption.map((f) => {
                  // Highlight under-adoption — features used by < 50% of the
                  // user base get a soft amber row to flag the gap.
                  const underused = f.pctOfUsers < 50 && data.scope.totalUsers >= 2;
                  return (
                    <tr key={f.action} className={underused ? "bg-amber-50/30" : "hover:bg-slate-50"}>
                      <td className="px-4 py-2 font-medium text-slate-800">
                        {f.action.replace(/_/g, " ")}
                        {underused && (
                          <span className="ml-2 text-[9px] font-bold uppercase tracking-widest text-amber-700 bg-amber-100 px-1.5 py-0.5 rounded">
                            underused
                          </span>
                        )}
                      </td>
                      <td className="px-4 py-2 text-[10px] text-slate-500 uppercase tracking-wider">{f.category}</td>
                      <td className="px-4 py-2 text-right tabular-nums font-semibold text-slate-900">{f.users.toLocaleString()}</td>
                      <td className="px-4 py-2 text-right tabular-nums text-slate-700">{f.pctOfUsers}%</td>
                      <td className="px-4 py-2 text-right tabular-nums text-slate-500">{f.sessions.toLocaleString()}</td>
                      <td className="px-4 py-2 text-right text-[10px] text-slate-500">{relTime(f.lastUsed)}</td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          )}
        </Card>
      </section>

      {/* Cohort retention heatmap */}
      <section>
        <SectionHeader title="Cohort retention heatmap"
          right={<span className="text-[10px] text-slate-400">Signup week × subsequent activity (last 90 days)</span>}
        />
        <Card>
          {data.cohortRetention.length === 0 ? (
            <EmptyState icon={Users} title="No cohorts in the last 90 days" description="As new users sign up + interact, this grid populates with weekly retention." />
          ) : (
            <div className="overflow-x-auto">
              <table className="w-full text-xs">
                <thead className="text-[10px] font-bold uppercase tracking-widest text-slate-400 border-b border-slate-100 bg-slate-50/40">
                  <tr>
                    <th className="text-left px-3 py-2 sticky left-0 bg-slate-50/40">Signup week</th>
                    <th className="text-right px-3 py-2">Size</th>
                    {Array.from({ length: 9 }).map((_, i) => (
                      <th key={i} className="text-center px-2 py-2">W{i}</th>
                    ))}
                  </tr>
                </thead>
                <tbody className="divide-y divide-slate-100">
                  {data.cohortRetention.map((c) => (
                    <tr key={c.cohortLabel}>
                      <td className="px-3 py-2 font-mono text-[11px] text-slate-700 sticky left-0 bg-white">{c.cohortLabel}</td>
                      <td className="px-3 py-2 text-right tabular-nums text-slate-600">{c.cohortSize}</td>
                      {c.weeks.map((w) => (
                        <td key={w.index} className="px-2 py-2 text-center">
                          <span className={`inline-block min-w-[36px] px-1.5 py-1 rounded text-[10px] font-bold tabular-nums ${heatColor(w.pct)}`}
                            title={`${w.retained}/${c.cohortSize} = ${w.pct}%`}>
                            {w.pct}%
                          </span>
                        </td>
                      ))}
                    </tr>
                  ))}
                </tbody>
              </table>
              <div className="px-4 py-2 border-t border-slate-100 bg-slate-50/40 text-[10px] text-slate-500">
                Each cell = % of the cohort active in that week (≥ 1 PlatformEvent). W0 is the signup week itself; W1+ measures return.
              </div>
            </div>
          )}
        </Card>
      </section>
    </div>
  );
}

function DistCell({
  label, hint, count, total, color,
}: {
  label: string;
  hint: string;
  count: number;
  total: number;
  color: string;
}) {
  const pct = total > 0 ? Math.round((count / total) * 100) : 0;
  return (
    <div>
      <p className="text-[10px] font-bold uppercase tracking-widest text-slate-500">{label}</p>
      <p className="text-[10px] text-slate-400 mb-1">{hint}</p>
      <p className="text-2xl font-bold text-slate-900 tabular-nums">{count.toLocaleString()}</p>
      <div className="h-1.5 bg-slate-100 rounded-full overflow-hidden mt-2">
        <div className={`h-full rounded-full ${color}`} style={{ width: `${pct}%` }} />
      </div>
      <p className="text-[10px] text-slate-500 mt-1 tabular-nums">{pct}%</p>
    </div>
  );
}
