"use client";

/**
 * Admin → Analytics → Radar
 * ─────────────────────────
 * Brand Strength Radar — 8 dimensions per brand + a platform-wide
 * aggregate. Custom SVG implementation (no recharts dep) so the
 * dashboard renders identically in dev / staging / prod regardless
 * of whether recharts types are installed.
 *
 * Header: average platform health (traffic-light), brand count,
 * and the platform radar plot. Below: leaderboard top 10 / bottom
 * 10 by health.
 */

import { useEffect, useMemo, useState } from "react";
import {
  Target, Loader2, TrendingUp, TrendingDown,
  AlertTriangle, Sparkles, BarChart3, ArrowRight, Info,
} from "lucide-react";
import Link from "next/link";

interface Dimension { id: string; label: string }

interface LeaderRow { brandId: string; brandName: string; domain: string; health: number }

interface PlatformInsights {
  weakestDimension: { id: string; label: string; avgScore: number };
  strongestDimension: { id: string; label: string; avgScore: number };
  mostImproved: { brandId: string; brandName: string; health: number } | null;
  needsAttention: { brandId: string; brandName: string; health: number } | null;
  distribution: Record<"0-20" | "20-40" | "40-60" | "60-80" | "80-100", number>;
}

interface PlatformPayload {
  dimensions: Dimension[];
  averages: Record<string, number>;
  averageHealth: number;
  brandCount: number;
  platformInsights: PlatformInsights | null;
  dimensionWeakness: Record<string, number>;
  leaderboard: { top: LeaderRow[]; bottom: LeaderRow[] };
}

export default function AdminRadarPage() {
  const [data, setData] = useState<PlatformPayload | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch("/api/admin/analytics/radar")
      .then((r) => (r.ok ? r.json() : null))
      .then((d) => setData(d))
      .finally(() => setLoading(false));
  }, []);

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

  const dimensions = data.dimensions;
  const averages = data.averages;
  const healthColor = data.averageHealth >= 80 ? "text-emerald-600"
    : data.averageHealth >= 50 ? "text-amber-600" : "text-red-600";

  // Sort dimensions to render the radar — alphabetical-by-id is fine,
  // we just need a stable order.
  const dimsSorted = [...dimensions];

  return (
    <div className="space-y-6">
      <div>
        <h1 className="text-2xl font-bold text-slate-900 flex items-center gap-2">
          <Target className="w-5 h-5 text-slate-700" /> Brand Strength Radar
        </h1>
        <p className="text-slate-500 text-sm mt-1">
          Eight-dimension health score across {data.brandCount} brand{data.brandCount !== 1 ? "s" : ""}.
        </p>
      </div>

      {/* Platform headline */}
      <div className="bg-white border border-slate-200 rounded-xl p-6 grid grid-cols-1 md:grid-cols-2 gap-6 items-center">
        <div className="flex flex-col items-center md:items-start">
          <p className="text-[10px] font-bold uppercase tracking-widest text-slate-400">Platform health</p>
          <p className={`text-6xl font-bold tabular-nums ${healthColor}`}>{data.averageHealth}</p>
          <p className="text-xs text-slate-500 mt-1">
            Average across all brands. <span className="font-semibold">Higher = better.</span>
          </p>
          <ul className="mt-4 space-y-1 text-xs">
            {dimsSorted.map((d) => {
              const score = averages[d.id] ?? 0;
              const color = score >= 70 ? "text-emerald-600" : score >= 40 ? "text-amber-600" : "text-red-600";
              return (
                <li key={d.id} className="flex items-center gap-3">
                  <span className="text-slate-700 w-40">{d.label}</span>
                  <div className="flex-1 h-1.5 bg-slate-100 rounded-full overflow-hidden">
                    <div
                      className={`h-full rounded-full ${score >= 70 ? "bg-emerald-500" : score >= 40 ? "bg-amber-500" : "bg-red-500"}`}
                      style={{ width: `${score}%` }}
                    />
                  </div>
                  <span className={`font-bold tabular-nums w-8 text-right ${color}`}>{score}</span>
                </li>
              );
            })}
          </ul>
        </div>
        <div className="flex justify-center">
          <RadarChart
            dimensions={dimsSorted}
            scores={averages}
            color="#6366F1"
            size={480}
          />
        </div>
      </div>

      {/* Platform-wide insights */}
      {data.platformInsights && (
        <PlatformInsightsCard
          insights={data.platformInsights}
          dimensionWeakness={data.dimensionWeakness}
          dimensions={dimensions}
        />
      )}

      {/* Per-dimension deep dive — one expandable card per dimension.
          Currently shows the platform AVERAGE score per dimension;
          clicking a card opens a recommendations/details view wired
          to /api/admin/analytics/radar?brandId=... when a specific
          brand is selected (future enhancement). */}
      <section>
        <div className="flex items-center gap-2 mb-3">
          <h2 className="text-sm font-bold text-slate-800">Dimension deep-dive</h2>
          <span className="text-[10px] text-slate-400 uppercase tracking-widest">Platform averages</span>
        </div>
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-3">
          {dimensions.map((d) => (
            <DimensionCard
              key={d.id}
              id={d.id}
              label={d.label}
              score={averages[d.id] ?? 0}
              brandsWeakOnThis={data.dimensionWeakness[d.id] ?? 0}
              totalBrands={data.brandCount}
            />
          ))}
        </div>
      </section>

      {/* Leaderboard */}
      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
        <Leaderboard
          title="Top 10 brands"
          icon={TrendingUp}
          accent="emerald"
          rows={data.leaderboard.top}
        />
        <Leaderboard
          title="Bottom 10 brands (focus area)"
          icon={TrendingDown}
          accent="red"
          rows={data.leaderboard.bottom}
        />
      </div>

      {/* Placeholder for the 12-month trend chart. Ships once
          PlatformSnapshot carries per-month radar averages — until
          then we surface the expectation so the section isn't empty. */}
      <div className="rounded-xl border border-dashed border-slate-300 bg-slate-50/40 px-4 py-6 text-center">
        <BarChart3 className="w-5 h-5 text-slate-400 inline-block mb-1" />
        <p className="text-xs font-bold uppercase tracking-widest text-slate-500">Platform health trend</p>
        <p className="text-[11px] text-slate-500 mt-1 leading-relaxed max-w-lg mx-auto">
          Collecting baseline data. The 12-month platform-health line chart turns on once
          PlatformSnapshot captures monthly radar averages (trend available after 30 days).
        </p>
      </div>
    </div>
  );
}

// ─── Platform-wide insights card ──────────────────────────────────

function PlatformInsightsCard({
  insights, dimensionWeakness, dimensions,
}: {
  insights: PlatformInsights;
  dimensionWeakness: Record<string, number>;
  dimensions: Dimension[];
}) {
  const dimLabel = (id: string) => dimensions.find((d) => d.id === id)?.label ?? id;
  const topWeak = Object.entries(dimensionWeakness)
    .sort(([, a], [, b]) => b - a)
    .slice(0, 3)
    .map(([id, count]) => ({ id, count, label: dimLabel(id) }));
  const distEntries: Array<[string, number]> = Object.entries(insights.distribution);
  const distTotal = distEntries.reduce((s, [, v]) => s + v, 0) || 1;

  return (
    <section className="bg-white border border-slate-200 rounded-xl overflow-hidden">
      <div className="px-5 py-3 border-b border-slate-100 flex items-center gap-2">
        <Sparkles className="w-4 h-4 text-violet-600" />
        <h2 className="font-semibold text-slate-900 text-sm">Platform insights</h2>
      </div>
      <div className="grid grid-cols-1 md:grid-cols-4 divide-y md:divide-y-0 md:divide-x divide-slate-100">
        <InsightCell
          icon={TrendingDown}
          label="Weakest dimension"
          primary={insights.weakestDimension.label}
          value={`${insights.weakestDimension.avgScore}/100`}
          tone="rose"
        />
        <InsightCell
          icon={TrendingUp}
          label="Strongest dimension"
          primary={insights.strongestDimension.label}
          value={`${insights.strongestDimension.avgScore}/100`}
          tone="emerald"
        />
        <InsightCell
          icon={Sparkles}
          label="Top-performing brand"
          primary={insights.mostImproved?.brandName ?? "—"}
          value={insights.mostImproved ? `Health ${insights.mostImproved.health}` : ""}
          tone="violet"
        />
        <InsightCell
          icon={AlertTriangle}
          label="Needs attention"
          primary={insights.needsAttention?.brandName ?? "—"}
          value={insights.needsAttention ? `Health ${insights.needsAttention.health}` : ""}
          tone="amber"
        />
      </div>

      {/* Distribution + top-3 weakest dims */}
      <div className="grid grid-cols-1 md:grid-cols-2 gap-0 border-t border-slate-100">
        <div className="p-5 border-b md:border-b-0 md:border-r border-slate-100">
          <p className="text-[10px] font-bold uppercase tracking-widest text-slate-500 mb-2">Health distribution</p>
          <div className="space-y-1.5">
            {distEntries.map(([bucket, count]) => {
              const pct = Math.round((count / distTotal) * 100);
              const color =
                bucket === "0-20"  ? "bg-rose-500" :
                bucket === "20-40" ? "bg-orange-500" :
                bucket === "40-60" ? "bg-amber-500" :
                bucket === "60-80" ? "bg-lime-500" :
                                      "bg-emerald-500";
              return (
                <div key={bucket} className="flex items-center gap-3 text-[11px]">
                  <span className="text-slate-500 w-14 font-mono">{bucket}</span>
                  <div className="flex-1 h-2 bg-slate-100 rounded-full overflow-hidden">
                    <div className={`h-full rounded-full ${color}`} style={{ width: `${pct}%` }} />
                  </div>
                  <span className="text-slate-700 tabular-nums w-10 text-right">{count}</span>
                  <span className="text-slate-400 tabular-nums w-10 text-right">{pct}%</span>
                </div>
              );
            })}
          </div>
        </div>
        <div className="p-5">
          <p className="text-[10px] font-bold uppercase tracking-widest text-slate-500 mb-2">
            Platform-wide focus areas
          </p>
          {topWeak.length === 0 ? (
            <p className="text-xs text-slate-500">No dimension emerges as a clear platform-wide weakness — scores are well-distributed.</p>
          ) : (
            <ul className="space-y-1.5">
              {topWeak.map((w) => (
                <li key={w.id} className="flex items-center gap-2 text-[11px]">
                  <AlertTriangle className="w-3 h-3 text-amber-500" />
                  <span className="text-slate-700">
                    <span className="font-semibold">{w.count}</span> brands weakest on <span className="font-semibold">{w.label}</span>
                  </span>
                </li>
              ))}
            </ul>
          )}
        </div>
      </div>
    </section>
  );
}

function InsightCell({
  icon: Icon, label, primary, value, tone,
}: {
  icon: typeof TrendingUp;
  label: string;
  primary: string;
  value: string;
  tone: "rose" | "emerald" | "violet" | "amber";
}) {
  const toneClasses: Record<typeof tone, string> = {
    rose: "text-rose-600",
    emerald: "text-emerald-600",
    violet: "text-violet-600",
    amber: "text-amber-600",
  };
  return (
    <div className="p-5">
      <p className="text-[10px] font-bold uppercase tracking-widest text-slate-500 flex items-center gap-1">
        <Icon className={`w-3 h-3 ${toneClasses[tone]}`} />{label}
      </p>
      <p className="text-sm font-semibold text-slate-900 truncate mt-1.5">{primary}</p>
      <p className="text-[10px] text-slate-400 mt-0.5">{value}</p>
    </div>
  );
}

// ─── Per-dimension card ───────────────────────────────────────────
//
// Compact platform-level card for each of the 8 dimensions. Shows
// the platform-average score, how many brands score weak on this
// dimension, and a deep-link to the relevant feature page. The
// card is intentionally PLATFORM-level (not per-brand) here — the
// per-brand deep dive is wired to the dedicated single-brand radar
// page (future enhancement; the API endpoint is already serving it
// at GET /api/admin/analytics/radar?brandId=X).

const DIM_CTA: Record<string, { href: string; label: string }> = {
  technical:   { href: "/technical-audit",     label: "Open Technical Audit" },
  content:     { href: "/content-audit",       label: "Open Content Audit" },
  search:      { href: "/rank-tracker",        label: "Open Rank Tracker" },
  traffic:     { href: "/site-tag-analytics",  label: "Open Analytics" },
  conversion:  { href: "/site-tag-analytics",  label: "Open Analytics" },
  competitive: { href: "/competitors",         label: "Manage Competitors" },
  ai:          { href: "/ai-visibility",       label: "Run AI Visibility" },
  maturity:    { href: "/settings/integrations", label: "Manage Integrations" },
};

function DimensionCard({
  id, label, score, brandsWeakOnThis, totalBrands,
}: {
  id: string;
  label: string;
  score: number;
  brandsWeakOnThis: number;
  totalBrands: number;
}) {
  const cta = DIM_CTA[id];
  const colorClass = score >= 70 ? "text-emerald-600"
    : score >= 40 ? "text-amber-600"
    : "text-rose-600";
  const bg = score >= 70 ? "bg-emerald-500"
    : score >= 40 ? "bg-amber-500"
    : "bg-rose-500";
  const weakPct = totalBrands > 0 ? Math.round((brandsWeakOnThis / totalBrands) * 100) : 0;

  return (
    <div className="bg-white border border-slate-200 rounded-xl p-4 flex flex-col gap-2">
      <div className="flex items-baseline justify-between gap-2">
        <p className="text-xs font-bold text-slate-800 truncate">{label}</p>
        <span className={`text-lg font-bold tabular-nums ${colorClass}`}>{score}</span>
      </div>
      <div className="h-1.5 bg-slate-100 rounded-full overflow-hidden">
        <div className={`h-full rounded-full ${bg}`} style={{ width: `${score}%` }} />
      </div>
      {brandsWeakOnThis > 0 ? (
        <p className="text-[10px] text-slate-500 flex items-center gap-1">
          <AlertTriangle className="w-2.5 h-2.5 text-amber-500" />
          <span className="font-semibold">{brandsWeakOnThis}</span> of {totalBrands} brands weakest on this
          {totalBrands > 0 && weakPct > 0 && <span className="text-slate-400"> ({weakPct}%)</span>}
        </p>
      ) : (
        <p className="text-[10px] text-slate-500 flex items-center gap-1">
          <Info className="w-2.5 h-2.5 text-slate-400" />
          No brand is blocked on this dimension.
        </p>
      )}
      {cta && (
        <Link
          href={cta.href}
          className="text-[10px] font-semibold text-brand-600 hover:text-brand-700 inline-flex items-center gap-1 mt-auto"
        >
          {cta.label} <ArrowRight className="w-2.5 h-2.5" />
        </Link>
      )}
    </div>
  );
}

// ─── Leaderboard ──────────────────────────────────────────────────

function Leaderboard({
  title, icon: Icon, accent, rows,
}: {
  title: string; icon: typeof TrendingUp; accent: "emerald" | "red";
  rows: Array<{ brandId: string; brandName: string; domain: string; health: number }>;
}) {
  if (rows.length === 0) return null;
  const accentClass = accent === "emerald" ? "text-emerald-600" : "text-red-600";
  // Top-3 medal palette — gold / silver / bronze for the leaderboard
  // "podium" rows. Bottom leaderboards skip the medals entirely.
  const MEDAL_BG = ["bg-amber-100 text-amber-700", "bg-slate-200 text-slate-600", "bg-orange-100 text-orange-700"];
  return (
    <div className="bg-white border border-slate-100 rounded-xl shadow-sm overflow-hidden">
      <div className="px-4 py-3 border-b border-slate-100 flex items-center gap-2">
        <Icon className={`w-4 h-4 ${accentClass}`} />
        <h2 className="font-semibold text-slate-900 text-sm">{title}</h2>
      </div>
      <ul className="divide-y divide-slate-100">
        {rows.map((r, i) => {
          const color = r.health >= 80 ? "text-emerald-700 bg-emerald-50"
            : r.health >= 50 ? "text-amber-700 bg-amber-50" : "text-rose-700 bg-rose-50";
          const isPodium = accent === "emerald" && i < 3;
          return (
            <li key={r.brandId} className="px-4 py-2.5 flex items-center gap-3 hover:bg-slate-50">
              {isPodium ? (
                <span className={`w-6 h-6 rounded-full flex items-center justify-center text-[10px] font-bold tabular-nums shrink-0 ${MEDAL_BG[i]}`}>
                  {i + 1}
                </span>
              ) : (
                <span className="w-6 text-right text-[10px] font-bold text-slate-400 tabular-nums">{i + 1}</span>
              )}
              <Link
                href={`/admin/brands?q=${encodeURIComponent(r.domain)}`}
                className="flex-1 text-xs font-semibold text-slate-800 hover:text-brand-600 truncate"
              >
                {r.brandName}
              </Link>
              <span className="text-[10px] text-slate-400 truncate max-w-[140px] font-mono">{r.domain}</span>
              <span className={`text-[11px] font-semibold tabular-nums px-2 py-0.5 rounded-full ${color}`}>
                {r.health}
              </span>
            </li>
          );
        })}
      </ul>
    </div>
  );
}

// ─── Custom SVG radar ────────────────────────────────────────────
//
// 8-axis radar plot. Drawn from scratch because recharts' types
// aren't installed in the current env (would surface as a
// build/typecheck failure). SVG is a few dozen lines; the renderer
// math is identical to recharts' RadarChart.
//
// Label handling — the previous revision packed the chart into a
// tight square viewBox which clipped every outer-edge label ("Content
// Qua…", "Sea…") on 320px instances. We now:
//   1. Bump the default render size to 480px.
//   2. Expand the SVG viewBox with 80px padding on every side so the
//      label region has headroom outside the plot circle.
//   3. Render a SHORT axis label on the chart (one word — e.g.
//      "Content" for "Content Quality") so the horizontal space is
//      always sufficient, regardless of the brand name length. The
//      full label is already shown in the legend to the left.
//   4. Anchor labels dynamically based on their polar angle
//      (cos > 0.3 → start, cos < -0.3 → end, else middle) with a
//      small radial offset from the polygon edge so they don't
//      overlap the plot.

/** Map full radar-dimension label → short one-word label used on the
 *  chart. Kept as a local override to avoid shipping a full rename
 *  through brand-radar.ts (which every API consumer reads). */
const SHORT_LABEL: Record<string, string> = {
  "Technical Health":        "Technical",
  "Content Quality":         "Content",
  "Search Visibility":       "Search",
  "Traffic & Engagement":    "Traffic",
  "Conversion Performance":  "Conversion",
  "Conversion":              "Conversion",
  "Competitive Position":    "Competitive",
  "Competitive":             "Competitive",
  "AI Visibility":           "AI",
  "Data Maturity":           "Data",
};
function shortLabel(full: string): string {
  return SHORT_LABEL[full] ?? full.split(/[\s&]+/)[0];
}

function RadarChart({
  dimensions, scores, color, size,
}: {
  dimensions: Dimension[];
  scores: Record<string, number>;
  color: string;
  size: number;
}) {
  // viewBox padding — labels sit outside the plot circle, so the
  // viewBox must be larger than `size` to contain them. 80px on each
  // side accommodates the longest short label + the score tspan.
  const LABEL_PAD = 80;
  const cx = size / 2;
  const cy = size / 2;
  const radius = (size / 2) - 8; // smaller inset; labels live in the padded region now
  const n = dimensions.length;

  const points = useMemo(() => {
    return dimensions.map((d, i) => {
      const angle = (Math.PI * 2 * i) / n - Math.PI / 2;
      const score = scores[d.id] ?? 0;
      const r = (score / 100) * radius;
      // Label position — 22px outside the plot circle so the
      // text baseline doesn't collide with the outermost ring.
      const LABEL_OFFSET = 22;
      return {
        x: cx + Math.cos(angle) * r,
        y: cy + Math.sin(angle) * r,
        labelX: cx + Math.cos(angle) * (radius + LABEL_OFFSET),
        labelY: cy + Math.sin(angle) * (radius + LABEL_OFFSET),
        anchor: (
          Math.cos(angle) > 0.3 ? "start"
          : Math.cos(angle) < -0.3 ? "end"
          : "middle"
        ) as "start" | "end" | "middle",
        // Full label stays in the legend; chart shows the short
        // single-word form so it fits without truncation.
        label: shortLabel(d.label),
        fullLabel: d.label,
        score,
      };
    });
  }, [dimensions, scores, cx, cy, radius, n]);

  const polygon = points.map((p) => `${p.x.toFixed(2)},${p.y.toFixed(2)}`).join(" ");
  const ringRadii = [0.25, 0.5, 0.75, 1].map((r) => r * radius);

  // viewBox intentionally bigger than the chart size so the outer
  // labels render inside the SVG viewport. Width/height preserved
  // so CSS sizing stays predictable for the caller.
  const vbMin = -LABEL_PAD;
  const vbSize = size + LABEL_PAD * 2;

  return (
    <svg
      width={size}
      height={size}
      viewBox={`${vbMin} ${vbMin} ${vbSize} ${vbSize}`}
      preserveAspectRatio="xMidYMid meet"
    >
      {/* Concentric rings */}
      {ringRadii.map((r, idx) => (
        <circle
          key={idx}
          cx={cx}
          cy={cy}
          r={r}
          fill="none"
          stroke="#E2E8F0"
          strokeWidth={1}
        />
      ))}
      {/* Axis lines */}
      {dimensions.map((_, i) => {
        const angle = (Math.PI * 2 * i) / n - Math.PI / 2;
        return (
          <line
            key={i}
            x1={cx}
            y1={cy}
            x2={cx + Math.cos(angle) * radius}
            y2={cy + Math.sin(angle) * radius}
            stroke="#E2E8F0"
            strokeWidth={1}
          />
        );
      })}
      {/* Score polygon */}
      <polygon
        points={polygon}
        fill={color}
        fillOpacity={0.18}
        stroke={color}
        strokeWidth={2}
      />
      {/* Score dots */}
      {points.map((p, i) => (
        <circle key={i} cx={p.x} cy={p.y} r={3} fill={color} />
      ))}
      {/* Axis labels — short name on line 1, score on line 2.
          title tag carries the full label so the hover tooltip
          still discloses e.g. "Content Quality" from the
          "Content" axis. */}
      {points.map((p, i) => (
        <text
          key={i}
          x={p.labelX}
          y={p.labelY}
          fontSize={11}
          fontWeight={700}
          fill="#475569"
          textAnchor={p.anchor}
          dominantBaseline="middle"
        >
          <title>{p.fullLabel}</title>
          {p.label}
          <tspan x={p.labelX} dy={13} fontSize={11} fontWeight={800} fill={color}>
            {p.score}
          </tspan>
        </text>
      ))}
    </svg>
  );
}
