"use client";

/**
 * Toxic Backlinks panel
 * ──────────────────────
 * Displays every non-disavowed backlink at score >= 40 (Moderate Risk
 * and above) with the full colour-coded severity ladder from
 * backlink-toxicity. Each row:
 *
 *   • Source domain with favicon.
 *   • Coloured toxicity badge (score + tier label + emoji).
 *   • Inline score bar at full 5-colour gradient.
 *   • Expandable "Why is this toxic?" details showing the heuristic
 *     reasons the scorer recorded. Pulled from Backlink.toxicityReasons
 *     (populated on every sync by calculateToxicityScore).
 *   • Bulk-select checkbox for the disavow flow.
 *
 * Header features:
 *   • Health bar — horizontal stacked Healthy/Low/Moderate/High/Toxic
 *     distribution with count + percentage badges per bucket so the
 *     user can see the overall link profile at a glance.
 *   • "Analyze Toxicity" button — re-runs scoring across every
 *     non-disavowed backlink via POST /api/backlinks/rescore. Useful
 *     for legacy rows that predate the current heuristic set.
 */

import { Fragment, useState } from "react";
import {
  ShieldAlert, Download, Loader2, Check, ChevronDown, ChevronUp,
  Sparkles,
} from "lucide-react";
import { scoreToTier, TIER_COLORS, type ToxicityTier } from "@/lib/services/backlink-toxicity";

export interface ToxicLink {
  id: string;
  sourceDomain: string;
  toxicityScore: number | null;
  qualityTier: string | null;
  toxicityReasons?: string[];
}

interface HealthBuckets {
  healthy: number;
  lowRisk: number;
  moderate: number;
  highRisk: number;
  toxic: number;
}

interface Props {
  brandId: string;
  /** All toxic-tier (score >= 40) non-disavowed backlinks. */
  links: ToxicLink[];
  /** Bucket counts across ALL active backlinks (not just the `links` above).
   *  Drives the header health bar. Server-source-of-truth: see
   *  /api/backlinks/summary's `health` field. Optional so older summary
   *  responses that don't return the bucket counts still render. */
  health?: HealthBuckets;
  onDisavow: (ids: string[]) => void;
  /** Called after a successful rescore so the parent can refresh state. */
  onRescored?: () => void;
}

/** Normalise the qualityTier column — handles both the current
 *  capitalised labels ("High Risk") and legacy AI values
 *  (excellent/good/neutral/poor/toxic) by falling back to the score. */
function resolveTier(score: number | null, tier: string | null): ToxicityTier {
  if (tier && (tier in TIER_COLORS)) return tier as ToxicityTier;
  return scoreToTier(score ?? 0);
}

const HEALTH_META: Array<{ key: keyof HealthBuckets; tier: ToxicityTier }> = [
  { key: "healthy",   tier: "Healthy" },
  { key: "lowRisk",   tier: "Low Risk" },
  { key: "moderate",  tier: "Moderate Risk" },
  { key: "highRisk",  tier: "High Risk" },
  { key: "toxic",     tier: "Toxic" },
];

export default function ToxicPanel({ brandId, links, health, onDisavow, onRescored }: Props) {
  const [selected, setSelected] = useState<Set<string>>(new Set());
  const [disavowing, setDisavowing] = useState(false);
  const [downloading, setDownloading] = useState(false);
  const [rescoring, setRescoring] = useState(false);
  const [expanded, setExpanded] = useState<Set<string>>(new Set());

  // Sort by toxicity descending so the worst rows come first regardless
  // of insertion order on the server.
  const sorted = [...links].sort((a, b) => (b.toxicityScore ?? 0) - (a.toxicityScore ?? 0));

  function toggle(id: string) {
    setSelected((prev) => { const n = new Set(prev); n.has(id) ? n.delete(id) : n.add(id); return n; });
  }
  function toggleAll() {
    selected.size === sorted.length ? setSelected(new Set()) : setSelected(new Set(sorted.map((l) => l.id)));
  }
  function toggleExpand(id: string) {
    setExpanded((prev) => { const n = new Set(prev); n.has(id) ? n.delete(id) : n.add(id); return n; });
  }

  async function disavow() {
    if (selected.size === 0) return;
    setDisavowing(true);
    await fetch("/api/backlinks/disavow", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ brandId, backlinkIds: Array.from(selected) }) });
    onDisavow(Array.from(selected));
    setSelected(new Set());
    setDisavowing(false);
  }

  async function downloadDisavow() {
    setDownloading(true);
    const res = await fetch(`/api/backlinks/disavow-file?brandId=${brandId}`);
    if (res.ok) {
      const text = await res.text();
      const blob = new Blob([text], { type: "text/plain" });
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = `disavow-${new Date().toISOString().split("T")[0]}.txt`;
      document.body.appendChild(a); a.click(); a.remove();
      URL.revokeObjectURL(url);
    }
    setDownloading(false);
  }

  async function rescore() {
    setRescoring(true);
    try {
      await fetch("/api/backlinks/rescore", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ brandId }),
      });
      onRescored?.();
    } finally { setRescoring(false); }
  }

  // ── Empty state ──────────────────────────────────────────────────
  if (sorted.length === 0) {
    return (
      <div className="bg-white rounded-xl border border-green-200 p-5">
        <div className="flex items-center justify-between mb-3">
          <div className="flex items-center gap-2">
            <Check className="w-5 h-5 text-green-500" />
            <h3 className="text-sm font-bold text-slate-800">No Toxic Backlinks</h3>
          </div>
          <button
            onClick={rescore}
            disabled={rescoring}
            className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-semibold text-violet-700 bg-violet-50 border border-violet-200 rounded-lg hover:bg-violet-100 disabled:opacity-50"
          >
            {rescoring ? <Loader2 className="w-3.5 h-3.5 animate-spin" /> : <Sparkles className="w-3.5 h-3.5" />}
            Analyze Toxicity
          </button>
        </div>
        <p className="text-xs text-slate-500">All backlinks have acceptable toxicity scores (score below 40).</p>
        {health && <div className="mt-3"><HealthBar health={health} /></div>}
      </div>
    );
  }

  return (
    <div className="bg-white rounded-xl border border-red-200 overflow-hidden">
      {/* Header */}
      <div className="flex items-center justify-between px-5 py-3 border-b border-red-100 bg-red-50 flex-wrap gap-2">
        <div className="flex items-center gap-2">
          <ShieldAlert className="w-4 h-4 text-red-500" />
          <h3 className="text-sm font-bold text-red-800">Toxic Backlinks ({sorted.length})</h3>
          <span className="text-[10px] text-red-500">Score ≥ 40 · sorted worst-first</span>
        </div>
        <div className="flex gap-2">
          <button
            onClick={rescore}
            disabled={rescoring}
            className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-semibold text-violet-700 bg-violet-50 border border-violet-200 rounded-lg hover:bg-violet-100 disabled:opacity-50"
          >
            {rescoring ? <Loader2 className="w-3 h-3 animate-spin" /> : <Sparkles className="w-3 h-3" />}
            {rescoring ? "Analyzing…" : "Analyze Toxicity"}
          </button>
          <button onClick={disavow} disabled={selected.size === 0 || disavowing} className="px-3 py-1.5 bg-red-600 text-white text-xs font-semibold rounded-lg hover:bg-red-700 disabled:opacity-50">
            {disavowing ? <Loader2 className="w-3 h-3 animate-spin" /> : `Disavow ${selected.size > 0 ? `(${selected.size})` : ""}`}
          </button>
          <button onClick={downloadDisavow} disabled={downloading} className="flex items-center gap-1 px-3 py-1.5 border border-red-200 text-red-700 text-xs font-semibold rounded-lg hover:bg-red-50 disabled:opacity-50">
            {downloading ? <Loader2 className="w-3 h-3 animate-spin" /> : <Download className="w-3 h-3" />} Disavow File
          </button>
        </div>
      </div>

      {/* Health bar — full distribution across the whole link set */}
      {health && <div className="px-5 py-3 border-b border-slate-100"><HealthBar health={health} /></div>}

      {/* Row list */}
      <table className="w-full text-sm">
        <thead>
          <tr className="border-b border-red-50 bg-red-50/50">
            <th className="px-4 py-2 text-left w-10">
              <input type="checkbox" checked={selected.size === sorted.length} onChange={toggleAll} className="rounded" />
            </th>
            <th className="px-3 py-2 text-left text-[10px] font-bold text-slate-500 uppercase">Domain</th>
            <th className="px-3 py-2 text-left text-[10px] font-bold text-slate-500 uppercase w-64">Toxicity</th>
            <th className="px-3 py-2 text-center text-[10px] font-bold text-slate-500 uppercase">Tier</th>
            <th className="px-3 py-2 text-right text-[10px] font-bold text-slate-500 uppercase w-24">Why?</th>
          </tr>
        </thead>
        <tbody className="divide-y divide-slate-100">
          {sorted.map((l) => {
            const score = l.toxicityScore ?? 0;
            const tier = resolveTier(l.toxicityScore, l.qualityTier);
            const meta = TIER_COLORS[tier];
            const isExpanded = expanded.has(l.id);
            const reasons = l.toxicityReasons ?? [];
            return (
              <Fragment key={l.id}>
                <tr className="hover:bg-red-50/30">
                  <td className="px-4 py-2.5">
                    <input type="checkbox" checked={selected.has(l.id)} onChange={() => toggle(l.id)} className="rounded" />
                  </td>
                  <td className="px-3 py-2.5 text-xs font-semibold text-slate-800">
                    <span className="inline-flex items-center gap-1.5">
                      <img
                        src={`https://www.google.com/s2/favicons?domain=${l.sourceDomain}&sz=16`}
                        alt=""
                        width={14}
                        height={14}
                        className="inline-block shrink-0"
                        loading="lazy"
                      />
                      {l.sourceDomain}
                    </span>
                  </td>
                  <td className="px-3 py-2.5">
                    {/* Score bar: width = score %, colour = tier colour.
                        Kept on a light slate track so the tier colour
                        reads cleanly regardless of the page theme. */}
                    <div className="flex items-center gap-2">
                      <div className="flex-1 h-2 bg-slate-100 rounded-full overflow-hidden">
                        <div className="h-full rounded-full" style={{ width: `${score}%`, backgroundColor: meta.bar }} />
                      </div>
                      <span className="text-xs font-bold tabular-nums w-8 text-right" style={{ color: meta.bar }}>
                        {score}
                      </span>
                    </div>
                  </td>
                  <td className="px-3 py-2.5 text-center">
                    <span className={`inline-flex items-center gap-1 text-[10px] font-bold px-2 py-0.5 rounded-full border ${meta.bg} ${meta.text} ${meta.border}`}>
                      <span aria-hidden>{meta.emoji}</span>
                      {tier}
                    </span>
                  </td>
                  <td className="px-3 py-2.5 text-right">
                    {reasons.length > 0 ? (
                      <button
                        onClick={() => toggleExpand(l.id)}
                        className="inline-flex items-center gap-1 text-[11px] font-semibold text-slate-500 hover:text-slate-700"
                      >
                        {reasons.length} reason{reasons.length === 1 ? "" : "s"}
                        {isExpanded ? <ChevronUp className="w-3 h-3" /> : <ChevronDown className="w-3 h-3" />}
                      </button>
                    ) : (
                      <span className="text-[11px] text-slate-300">—</span>
                    )}
                  </td>
                </tr>
                {isExpanded && reasons.length > 0 && (
                  <tr className="bg-red-50/20">
                    <td colSpan={5} className="px-5 py-3">
                      <p className="text-[10px] font-bold uppercase tracking-widest text-slate-400 mb-1.5">Why is this toxic?</p>
                      <ul className="space-y-1">
                        {reasons.map((r, i) => (
                          <li key={i} className="text-xs text-slate-600 flex items-start gap-2">
                            <span className="text-red-500 mt-0.5">•</span>
                            <span>{r}</span>
                          </li>
                        ))}
                      </ul>
                    </td>
                  </tr>
                )}
              </Fragment>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

// ─── Health distribution bar ──────────────────────────────────────────────

function HealthBar({ health }: { health: HealthBuckets }) {
  const total = Math.max(1, health.healthy + health.lowRisk + health.moderate + health.highRisk + health.toxic);
  return (
    <div>
      <div className="flex items-center justify-between mb-1.5">
        <p className="text-[10px] font-bold uppercase tracking-widest text-slate-400">
          Backlink health distribution
        </p>
        <p className="text-[10px] text-slate-400">{total.toLocaleString()} total</p>
      </div>
      <div className="flex h-2 rounded-full overflow-hidden bg-slate-100">
        {HEALTH_META.map((h) => {
          const v = health[h.key];
          if (v === 0) return null;
          return (
            <div
              key={h.key}
              className="h-full"
              style={{ width: `${(v / total) * 100}%`, backgroundColor: TIER_COLORS[h.tier].bar }}
              title={`${h.tier}: ${v.toLocaleString()} (${((v / total) * 100).toFixed(0)}%)`}
            />
          );
        })}
      </div>
      <div className="flex flex-wrap gap-2 mt-2">
        {HEALTH_META.map((h) => {
          const v = health[h.key];
          const pct = total > 0 ? Math.round((v / total) * 100) : 0;
          const meta = TIER_COLORS[h.tier];
          return (
            <span
              key={h.key}
              className={`inline-flex items-center gap-1 text-[10px] font-semibold px-2 py-0.5 rounded border ${meta.bg} ${meta.text} ${meta.border}`}
            >
              <span
                className="inline-block w-1.5 h-1.5 rounded-full"
                style={{ backgroundColor: meta.bar }}
              />
              {h.tier}: {v.toLocaleString()} ({pct}%)
            </span>
          );
        })}
      </div>
    </div>
  );
}
