"use client";

import { useEffect, useMemo, useState } from "react";
import { Copy, Loader2, Save, Trash2 } from "lucide-react";
import { AffiliationMobileDock, AffiliationSidebar, AffiliatePanel, StatusPill } from "@/components/affiliation/affiliation-ui";
import { formatMoney } from "@/lib/utils";

type AdminPayload = {
  stats: { affiliates: number; clicks: number; registrations: number; ftd: number; commissions: string; payable: string };
  chart: Array<{ date: string; amount: number }>;
  offers: Offer[];
  links: LinkItem[];
  payouts: Array<{ id: string; affiliate: string; amount: string; currency: string; status: string; periodStart: string; periodEnd: string }>;
  recentAccounts: Account[];
  topAffiliates: Array<{ accountId: string; displayName: string; email: string; amount: string }>;
};

type Offer = {
  id: string;
  code: string;
  name: string;
  type: "CPA" | "RS" | "HYBRID";
  status: string;
  cpaAmount: string | null;
  revenueShareBps: number | null;
  hybridCpaAmount: string | null;
  hybridRevenueShareBps: number | null;
  minFtdAmount: string;
  cookieDays: number;
  terms: string;
};

type Account = {
  id: string;
  publicId: string;
  displayName: string;
  email: string;
  country: string;
  status: string;
  offer: { id: string; code: string; name: string } | null;
};

type LinkItem = {
  id: string;
  accountId: string;
  affiliate: string;
  affiliateEmail: string;
  code: string;
  label: string;
  landingPath: string;
  status: string;
  rewardType: "CPA" | "RS" | "HYBRID";
  cpaAmount: string | null;
  revenueShareBps: number | null;
  minCpaDepositAmount: string;
  cpaValidationMode: "FIRST_DEPOSIT" | "CUMULATIVE_DEPOSIT";
  cpaWindowDays: number | null;
  allowedCountries: string[];
  terms: string | null;
  url: string;
  createdAt: string;
};

const blankLinkForm = {
  accountId: "",
  label: "",
  landingPath: "/",
  status: "active",
  rewardType: "HYBRID",
  cpaAmount: "140",
  revenueSharePercent: "45",
  minCpaDepositAmount: "21",
  cpaValidationMode: "CUMULATIVE_DEPOSIT",
  cpaWindowDays: "",
  allowedCountries: "FR,BE,CH",
  terms: ""
};

export function AffiliateAdminDashboard() {
  const [data, setData] = useState<AdminPayload | null>(null);
  const [message, setMessage] = useState("");
  const [loading, setLoading] = useState(true);
  const [savingLink, setSavingLink] = useState(false);
  const [editingLinkId, setEditingLinkId] = useState<string | null>(null);
  const [linkForm, setLinkForm] = useState(blankLinkForm);

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

  async function load() {
    setLoading(true);
    const response = await fetch("/api/affiliation/admin/overview", { cache: "no-store" });
    const payload = await response.json();
    setLoading(false);
    if (!payload.ok) {
      setMessage(payload.error?.message ?? "Accès admin requis");
      return;
    }
    setData(payload.data);
    if (!linkForm.accountId && payload.data.recentAccounts?.[0]) {
      setLinkForm((current) => ({ ...current, accountId: payload.data.recentAccounts[0].id }));
    }
  }

  async function saveLink() {
    setSavingLink(true);
    setMessage("");
    const body = {
      id: editingLinkId ?? undefined,
      accountId: linkForm.accountId,
      label: linkForm.label,
      landingPath: linkForm.landingPath,
      status: linkForm.status,
      rewardType: linkForm.rewardType,
      cpaAmount: linkForm.rewardType === "RS" ? null : linkForm.cpaAmount,
      revenueShareBps: linkForm.rewardType === "CPA" ? null : Math.round(Number(linkForm.revenueSharePercent || 0) * 100),
      minCpaDepositAmount: linkForm.minCpaDepositAmount,
      cpaValidationMode: linkForm.cpaValidationMode,
      cpaWindowDays: linkForm.cpaWindowDays ? Number(linkForm.cpaWindowDays) : null,
      allowedCountries: linkForm.allowedCountries.split(",").map((country) => country.trim().toUpperCase()).filter(Boolean),
      terms: linkForm.terms || null
    };
    const response = await fetch("/api/affiliation/admin/links", {
      method: editingLinkId ? "PATCH" : "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(body)
    });
    const payload = await response.json();
    setSavingLink(false);
    if (!payload.ok) {
      setMessage(payload.error?.message ?? "Lien impossible à enregistrer");
      return;
    }
    setMessage(editingLinkId ? "Lien mis à jour." : "Lien créé.");
    setEditingLinkId(null);
    setLinkForm({ ...blankLinkForm, accountId: linkForm.accountId });
    await load();
  }

  async function deactivateLink(linkId: string) {
    const response = await fetch(`/api/affiliation/admin/links?id=${linkId}`, { method: "DELETE" });
    const payload = await response.json();
    if (!payload.ok) setMessage(payload.error?.message ?? "Désactivation impossible");
    else setMessage("Lien désactivé.");
    await load();
  }

  async function updateAccount(accountId: string, status: string, defaultOfferId?: string | null) {
    const response = await fetch("/api/affiliation/admin/accounts", {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ accountId, status, defaultOfferId })
    });
    const payload = await response.json();
    if (!payload.ok) setMessage(payload.error?.message ?? "Modification impossible");
    await load();
  }

  const chartPath = useMemo(() => buildPath(data?.chart ?? []), [data?.chart]);

  if (loading && !data) return <div className="grid min-h-screen place-items-center bg-[#020910] text-felt"><Loader2 className="h-6 w-6 animate-spin" /></div>;

  return (
    <div className="flex min-h-screen bg-[#020910] pb-20 text-white md:pb-0">
      <AffiliationSidebar admin />
      <main className="mx-auto w-full max-w-[1180px] space-y-3 p-3 md:p-4">
        <header className="flex items-center justify-between">
          <div>
            <div className="text-[11px] font-bold uppercase text-felt">Administration affiliation</div>
            <h1 className="text-xl font-extrabold text-white">Liens, deals et GEO</h1>
          </div>
          <StatusPill label="Admin" />
        </header>
        {message ? <div className="rounded-lg border border-gold/25 bg-gold/10 p-2 text-xs font-semibold text-gold">{message}</div> : null}

        <div className="grid gap-2 sm:grid-cols-2 lg:grid-cols-6">
          <Metric label="Affiliés" value={data?.stats.affiliates ?? 0} />
          <Metric label="Clics" value={data?.stats.clicks ?? 0} />
          <Metric label="Inscriptions" value={data?.stats.registrations ?? 0} />
          <Metric label="FTD" value={data?.stats.ftd ?? 0} />
          <Metric label="Commissions" value={formatMoney(data?.stats.commissions ?? "0")} />
          <Metric label="Payable" value={formatMoney(data?.stats.payable ?? "0")} />
        </div>

        <div className="grid gap-3 xl:grid-cols-[0.78fr_1.22fr]">
          <AffiliatePanel className="p-3" id="liens">
            <div className="flex items-center justify-between gap-3">
              <h2 className="text-sm font-bold text-white">{editingLinkId ? "Éditer un lien" : "Créer un lien affilié"}</h2>
              {editingLinkId ? (
                <button onClick={() => { setEditingLinkId(null); setLinkForm({ ...blankLinkForm, accountId: linkForm.accountId }); }} className="text-[11px] font-bold text-slate-400">
                  Annuler
                </button>
              ) : null}
            </div>
            <div className="mt-3 space-y-2">
              <label className="block text-[10px] font-bold uppercase text-slate-500">
                Affilié
                <select value={linkForm.accountId} onChange={(event) => setLinkForm({ ...linkForm, accountId: event.target.value })} className="mt-1 h-9 w-full rounded-lg border border-white/10 bg-white/[0.06] px-2 text-xs font-bold text-white">
                  {data?.recentAccounts.map((account) => <option key={account.id} value={account.id}>{account.displayName} · {account.email}</option>)}
                </select>
              </label>
              <div className="grid gap-2 sm:grid-cols-2">
                <Input label="Nom du lien" value={linkForm.label} onChange={(value) => setLinkForm({ ...linkForm, label: value })} placeholder="Spinbara sport GEO" />
                <Input label="Landing" value={linkForm.landingPath} onChange={(value) => setLinkForm({ ...linkForm, landingPath: value })} placeholder="/sports" />
              </div>
              <div className="grid gap-2 sm:grid-cols-3">
                <Select label="Type" value={linkForm.rewardType} onChange={(value) => setLinkForm({ ...linkForm, rewardType: value })} options={[["CPA", "CPA"], ["RS", "RS"], ["HYBRID", "Hybrid"]]} />
                <Input label="CPA €" value={linkForm.cpaAmount} onChange={(value) => setLinkForm({ ...linkForm, cpaAmount: value })} />
                <Input label="RS %" value={linkForm.revenueSharePercent} onChange={(value) => setLinkForm({ ...linkForm, revenueSharePercent: value })} />
              </div>
              <div className="grid gap-2 sm:grid-cols-3">
                <Input label="Dépôt min CPA" value={linkForm.minCpaDepositAmount} onChange={(value) => setLinkForm({ ...linkForm, minCpaDepositAmount: value })} />
                <Select label="Validation CPA" value={linkForm.cpaValidationMode} onChange={(value) => setLinkForm({ ...linkForm, cpaValidationMode: value })} options={[["FIRST_DEPOSIT", "Premier dépôt uniquement"], ["CUMULATIVE_DEPOSIT", "Cumul des dépôts"]]} />
                <Input label="Fenêtre jours" value={linkForm.cpaWindowDays} onChange={(value) => setLinkForm({ ...linkForm, cpaWindowDays: value })} placeholder="Illimité" />
              </div>
              <Input label="GEO autorisés" value={linkForm.allowedCountries} onChange={(value) => setLinkForm({ ...linkForm, allowedCountries: value })} placeholder="FR,BE,CH" />
              <textarea value={linkForm.terms} onChange={(event) => setLinkForm({ ...linkForm, terms: event.target.value })} placeholder="Conditions internes du lien, qualité trafic, exclusions..." className="min-h-20 w-full rounded-lg border border-white/10 bg-white/[0.06] p-2 text-xs font-semibold text-white placeholder:text-slate-500" />
              <button onClick={() => void saveLink()} disabled={savingLink || !linkForm.accountId || !linkForm.label} className="flex h-9 w-full items-center justify-center gap-2 rounded-lg bg-felt text-xs font-black text-ink-950 disabled:opacity-50">
                {savingLink ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Save className="h-3.5 w-3.5" />}
                {editingLinkId ? "Enregistrer les modifications" : "Créer le lien"}
              </button>
            </div>
          </AffiliatePanel>

          <AffiliatePanel className="p-3">
            <div className="flex items-center justify-between">
              <h2 className="text-sm font-bold text-white">Media items actifs</h2>
              <span className="text-[11px] font-semibold text-slate-500">{data?.links.length ?? 0}</span>
            </div>
            <div className="mt-3 overflow-x-auto">
              <div className="min-w-[820px] space-y-2">
                {data?.links.length ? data.links.map((link) => (
                  <div key={link.id} className="grid grid-cols-[1fr_0.8fr_0.8fr_1fr_auto] items-center gap-2 rounded-lg bg-white/[0.035] p-2 text-xs">
                    <div className="min-w-0">
                      <button onClick={() => editLink(link)} className="block truncate text-left font-bold text-felt">{link.label}</button>
                      <div className="truncate text-[11px] text-slate-500">{link.affiliate} · ID {link.code}</div>
                    </div>
                    <div>
                      <div className="font-bold text-white">{dealText(link)}</div>
                      <div className="text-[11px] text-slate-500">{conditionText(link)}</div>
                    </div>
                    <GeoPills countries={link.allowedCountries} />
                    <div className="truncate rounded-md bg-felt/10 px-2 py-1 text-[11px] font-semibold text-felt">{link.url}</div>
                    <div className="flex gap-1">
                      <button onClick={() => navigator.clipboard.writeText(`${window.location.origin}${link.url}`)} className="grid h-8 w-8 place-items-center rounded-lg border border-white/10 text-slate-300">
                        <Copy className="h-3.5 w-3.5" />
                      </button>
                      <button onClick={() => void deactivateLink(link.id)} className="grid h-8 w-8 place-items-center rounded-lg border border-ember/20 text-ember">
                        <Trash2 className="h-3.5 w-3.5" />
                      </button>
                    </div>
                  </div>
                )) : <Empty text="Aucun lien configuré." />}
              </div>
            </div>
          </AffiliatePanel>
        </div>

        <div className="grid gap-3 xl:grid-cols-[1fr_320px]">
          <AffiliatePanel className="p-3">
            <h2 className="text-sm font-bold text-white">Évolution des commissions</h2>
            {data?.chart.some((item) => item.amount > 0) ? (
              <svg viewBox="0 0 320 120" className="mt-3 h-40 w-full">
                <path d={chartPath.area} fill="rgba(15,191,143,.16)" />
                <path d={chartPath.line} fill="none" stroke="#10e0bd" strokeWidth="2" />
              </svg>
            ) : (
              <Empty text="Aucune commission enregistrée." />
            )}
          </AffiliatePanel>
          <AffiliatePanel className="p-3">
            <h2 className="text-sm font-bold text-white">Top affiliés</h2>
            <div className="mt-3 space-y-2">
              {data?.topAffiliates.length ? data.topAffiliates.map((item) => <Row key={item.accountId} title={item.displayName} meta={item.email} value={formatMoney(item.amount)} />) : <Empty text="Aucun affilié commissionné." />}
            </div>
          </AffiliatePanel>
        </div>

        <AffiliatePanel className="p-3" id="affilies">
          <h2 className="text-sm font-bold text-white">Affiliés</h2>
          <div className="mt-3 space-y-2">
            {data?.recentAccounts.length ? data.recentAccounts.map((account) => (
              <div key={account.id} className="grid gap-2 rounded-lg bg-white/[0.035] p-2 text-xs lg:grid-cols-[1fr_auto] lg:items-center">
                <div className="min-w-0">
                  <div className="font-bold text-white">{account.displayName}</div>
                  <div className="truncate text-[11px] text-slate-500">{account.email} · {account.publicId}</div>
                </div>
                <div className="grid grid-cols-3 gap-1">
                  <button onClick={() => void updateAccount(account.id, "ACTIVE", account.offer?.id)} className="h-8 rounded-lg bg-felt/15 text-[11px] font-bold text-felt">Activer</button>
                  <button onClick={() => void updateAccount(account.id, "SUSPENDED", account.offer?.id)} className="h-8 rounded-lg bg-gold/15 text-[11px] font-bold text-gold">Suspendre</button>
                  <button onClick={() => void updateAccount(account.id, "CLOSED", account.offer?.id)} className="h-8 rounded-lg bg-ember/15 text-[11px] font-bold text-ember">Fermer</button>
                </div>
              </div>
            )) : <Empty text="Aucun affilié enregistré." />}
          </div>
        </AffiliatePanel>
      </main>
      <AffiliationMobileDock admin />
    </div>
  );

  function editLink(link: LinkItem) {
    setEditingLinkId(link.id);
    setLinkForm({
      accountId: link.accountId,
      label: link.label,
      landingPath: link.landingPath,
      status: link.status,
      rewardType: link.rewardType,
      cpaAmount: link.cpaAmount ?? "",
      revenueSharePercent: link.revenueShareBps ? String(link.revenueShareBps / 100) : "",
      minCpaDepositAmount: link.minCpaDepositAmount,
      cpaValidationMode: link.cpaValidationMode,
      cpaWindowDays: link.cpaWindowDays ? String(link.cpaWindowDays) : "",
      allowedCountries: link.allowedCountries.join(","),
      terms: link.terms ?? ""
    });
    window.scrollTo({ top: 0, behavior: "smooth" });
  }
}

function Metric({ label, value }: { label: string; value: string | number }) {
  return (
    <AffiliatePanel className="p-2.5">
      <div className="text-[10px] font-bold uppercase text-slate-500">{label}</div>
      <div className="mt-1 truncate text-base font-bold text-white">{value}</div>
    </AffiliatePanel>
  );
}

function Input({ label, value, onChange, placeholder }: { label: string; value: string; onChange: (value: string) => void; placeholder?: string }) {
  return (
    <label className="block text-[10px] font-bold uppercase text-slate-500">
      {label}
      <input value={value} placeholder={placeholder} onChange={(event) => onChange(event.target.value)} className="mt-1 h-9 w-full rounded-lg border border-white/10 bg-white/[0.06] px-2 text-xs font-bold text-white placeholder:text-slate-500" />
    </label>
  );
}

function Select({ label, value, onChange, options }: { label: string; value: string; onChange: (value: string) => void; options: Array<[string, string]> }) {
  return (
    <label className="block text-[10px] font-bold uppercase text-slate-500">
      {label}
      <select value={value} onChange={(event) => onChange(event.target.value)} className="mt-1 h-9 w-full rounded-lg border border-white/10 bg-white/[0.06] px-2 text-xs font-bold text-white">
        {options.map(([optionValue, labelText]) => <option key={optionValue} value={optionValue}>{labelText}</option>)}
      </select>
    </label>
  );
}

function GeoPills({ countries }: { countries: string[] }) {
  if (!countries.length) return <span className="text-[11px] font-semibold text-slate-500">Tous pays</span>;
  return <div className="flex flex-wrap gap-1">{countries.map((country) => <span key={country} className="rounded-md bg-felt/10 px-1.5 py-0.5 text-[10px] font-black text-felt">{country}</span>)}</div>;
}

function Row({ title, meta, value }: { title: string; meta: string; value: string }) {
  return (
    <div className="flex items-center justify-between gap-2 rounded-lg bg-white/[0.035] p-2">
      <div className="min-w-0">
        <div className="truncate text-xs font-bold text-white">{title}</div>
        <div className="truncate text-[11px] text-slate-500">{meta}</div>
      </div>
      <div className="text-xs font-bold text-felt">{value}</div>
    </div>
  );
}

function Empty({ text }: { text: string }) {
  return <div className="rounded-lg border border-dashed border-white/10 bg-white/[0.02] p-3 text-xs font-semibold text-slate-500">{text}</div>;
}

function dealText(link: LinkItem) {
  const cpa = link.cpaAmount ? formatMoney(link.cpaAmount) : null;
  const rs = link.revenueShareBps ? `${(link.revenueShareBps / 100).toFixed(0)}% RS` : null;
  if (link.rewardType === "CPA") return cpa ? `${cpa} CPA` : "CPA";
  if (link.rewardType === "RS") return rs ?? "RS";
  return [cpa ? `${cpa} CPA` : null, rs].filter(Boolean).join(" + ") || "Hybrid";
}

function conditionText(link: LinkItem) {
  const mode = link.cpaValidationMode === "CUMULATIVE_DEPOSIT" ? "cumul" : "1er dépôt";
  const window = link.cpaWindowDays ? ` · ${link.cpaWindowDays}j` : "";
  return `Min ${formatMoney(link.minCpaDepositAmount)} · ${mode}${window}`;
}

function buildPath(points: Array<{ amount: number }>) {
  if (!points.length) return { line: "", area: "" };
  const max = Math.max(...points.map((item) => item.amount), 1);
  const coords = points.map((item, index) => {
    const x = (index / Math.max(1, points.length - 1)) * 320;
    const y = 110 - (item.amount / max) * 90;
    return [x, y] as const;
  });
  const line = coords.map(([x, y], index) => `${index === 0 ? "M" : "L"}${x.toFixed(1)} ${y.toFixed(1)}`).join(" ");
  return { line, area: `${line} L320 120 L0 120 Z` };
}
