"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { CheckCircle2, ExternalLink, FileText, Loader2, RefreshCw, ShieldAlert, XCircle } from "lucide-react";
import { cn } from "@/lib/utils";

type KycDocument = {
  id: string;
  type: string;
  status: string;
  metadata?: unknown;
  uploadedAt: string;
  viewUrl: string;
};

type KycCase = {
  id: string;
  status: string;
  openedAt: string;
  amlScore: number | null;
  pepMatch: boolean;
  sanctionsMatch: boolean;
  countryRisk: string | null;
  user: {
    id: string;
    email: string;
    username: string;
    name: string;
    country: string | null;
  };
  documents: KycDocument[];
  decisions: Array<{ id: string; status: string; reason: string; createdAt: string }>;
};

const statuses = ["ALL", "PENDING", "APPROVED", "REJECTED", "EXPIRED"] as const;

export function AdminKycDashboard() {
  const [cases, setCases] = useState<KycCase[]>([]);
  const [status, setStatus] = useState<(typeof statuses)[number]>("PENDING");
  const [selectedCaseId, setSelectedCaseId] = useState<string | null>(null);
  const [message, setMessage] = useState("");
  const [loading, setLoading] = useState(true);
  const [actionId, setActionId] = useState<string | null>(null);
  const [decisionReason, setDecisionReason] = useState("Documents vérifiés par le support.");

  const loadCases = useCallback(async () => {
    setLoading(true);
    setMessage("");
    const response = await fetch(`/api/admin/kyc/cases?status=${encodeURIComponent(status)}`, { cache: "no-store" });
    const payload = await response.json();
    setLoading(false);
    if (!payload.ok) {
      setMessage(payload.error?.message ?? "Chargement KYC impossible");
      return;
    }
    setCases(payload.data.cases);
  }, [status]);

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

  useEffect(() => {
    if (!selectedCaseId && cases.length) {
      setSelectedCaseId(cases[0].id);
    }
  }, [cases, selectedCaseId]);

  const selectedCase = useMemo(() => cases.find((kycCase) => kycCase.id === selectedCaseId) ?? cases[0] ?? null, [cases, selectedCaseId]);

  async function decideDocument(documentId: string, nextStatus: "accepted" | "rejected") {
    setActionId(documentId);
    setMessage("");
    const response = await fetch(`/api/admin/kyc/documents/${documentId}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        status: nextStatus,
        reason: nextStatus === "accepted" ? "Document accepté." : "Document refusé, fichier illisible ou incomplet."
      })
    });
    const payload = await response.json();
    setActionId(null);
    if (!payload.ok) {
      setMessage(payload.error?.message ?? "Décision document impossible");
      return;
    }
    await loadCases();
  }

  async function decideCase(nextStatus: "APPROVED" | "REJECTED" | "EXPIRED") {
    if (!selectedCase) return;
    setActionId(`case-${nextStatus}`);
    setMessage("");
    const response = await fetch("/api/admin/kyc/decision", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        caseId: selectedCase.id,
        status: nextStatus,
        reason: decisionReason || "Décision KYC."
      })
    });
    const payload = await response.json();
    setActionId(null);
    if (!payload.ok) {
      setMessage(payload.error?.message ?? "Décision KYC impossible");
      return;
    }
    await loadCases();
  }

  return (
    <section className="surface rounded-lg p-4">
      <div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
        <div className="flex items-center gap-2">
          <ShieldAlert className="h-5 w-5 text-felt" />
          <div>
            <h2 className="text-lg font-black text-white">File KYC</h2>
            <p className="mt-0.5 text-xs font-semibold text-slate-500">Documents reçus, décisions par fichier et validation finale.</p>
          </div>
        </div>
        <div className="flex gap-2">
          <select value={status} onChange={(event) => setStatus(event.target.value as (typeof statuses)[number])} className="h-9 rounded-lg border border-white/10 bg-[#101521] px-3 text-xs font-bold text-white">
            {statuses.map((item) => (
              <option key={item} value={item}>
                {item === "ALL" ? "Tous" : item}
              </option>
            ))}
          </select>
          <button onClick={() => void loadCases()} className="grid h-9 w-9 place-items-center rounded-lg bg-white/[0.06] text-slate-200">
            {loading ? <Loader2 className="h-4 w-4 animate-spin" /> : <RefreshCw className="h-4 w-4" />}
          </button>
        </div>
      </div>

      {message ? <div className="mt-3 rounded-lg border border-ember/25 bg-ember/10 p-2.5 text-xs font-bold text-ember">{message}</div> : null}

      <div className="mt-4 grid gap-3 xl:grid-cols-[0.78fr_1.22fr]">
        <div className="overflow-hidden rounded-lg border border-white/10">
          <div className="border-b border-white/10 bg-white/[0.035] px-3 py-2 text-xs font-black uppercase text-slate-500">
            {cases.length} dossier(s)
          </div>
          <div className="max-h-[580px] divide-y divide-white/10 overflow-y-auto">
            {cases.map((kycCase) => (
              <button
                key={kycCase.id}
                onClick={() => setSelectedCaseId(kycCase.id)}
                className={cn(
                  "block w-full px-3 py-3 text-left transition",
                  selectedCase?.id === kycCase.id ? "bg-felt/10" : "bg-white/[0.02] hover:bg-white/[0.05]"
                )}
              >
                <div className="flex items-center justify-between gap-2">
                  <span className="truncate text-sm font-black text-white">{kycCase.user.email}</span>
                  <StatusBadge status={kycCase.status} />
                </div>
                <div className="mt-1 flex flex-wrap gap-1.5 text-[11px] font-semibold text-slate-500">
                  <span>{kycCase.user.name}</span>
                  <span>{documentSummary(kycCase.documents)}</span>
                  <span>{formatDate(kycCase.openedAt)}</span>
                </div>
              </button>
            ))}
            {!cases.length ? <div className="p-4 text-sm font-semibold text-slate-500">Aucun dossier dans cette file.</div> : null}
          </div>
        </div>

        {selectedCase ? (
          <div className="rounded-lg border border-white/10 bg-white/[0.025] p-3">
            <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
              <div className="min-w-0">
                <div className="text-xs font-black uppercase text-felt">Client</div>
                <h3 className="mt-1 truncate text-lg font-black text-white">{selectedCase.user.email}</h3>
                <p className="mt-1 text-xs font-semibold text-slate-500">
                  @{selectedCase.user.username} · {selectedCase.user.country ?? "Pays non renseigné"} · ouvert {formatDate(selectedCase.openedAt)}
                </p>
              </div>
              <StatusBadge status={selectedCase.status} />
            </div>

            <div className="mt-3 grid gap-2 sm:grid-cols-3">
              <RiskTile label="AML" value={selectedCase.amlScore ?? "n/d"} />
              <RiskTile label="PEP" value={selectedCase.pepMatch ? "Match" : "RAS"} />
              <RiskTile label="Sanctions" value={selectedCase.sanctionsMatch ? "Match" : "RAS"} />
            </div>

            <div className="mt-4 space-y-2">
              {selectedCase.documents.map((document) => (
                <article key={document.id} className="rounded-lg border border-white/10 bg-[#101521] p-3">
                  <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
                    <div className="min-w-0">
                      <div className="flex items-center gap-2">
                        <FileText className="h-4 w-4 text-felt" />
                        <h4 className="truncate text-sm font-black text-white">{documentLabel(document.type)}</h4>
                      </div>
                      <p className="mt-1 text-xs font-semibold text-slate-500">
                        {documentFileName(document.metadata)} · reçu {formatDate(document.uploadedAt)}
                      </p>
                    </div>
                    <StatusBadge status={document.status} />
                  </div>
                  <div className="mt-3 grid gap-2 sm:grid-cols-3">
                    <a href={document.viewUrl} target="_blank" rel="noreferrer" className="flex h-9 items-center justify-center gap-2 rounded-lg border border-white/10 bg-white/[0.06] text-xs font-black text-white">
                      <ExternalLink className="h-3.5 w-3.5" />
                      Voir
                    </a>
                    <button
                      onClick={() => void decideDocument(document.id, "accepted")}
                      disabled={actionId === document.id}
                      className="flex h-9 items-center justify-center gap-2 rounded-lg bg-felt text-xs font-black text-ink-950 disabled:opacity-50"
                    >
                      {actionId === document.id ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <CheckCircle2 className="h-3.5 w-3.5" />}
                      Accepter
                    </button>
                    <button
                      onClick={() => void decideDocument(document.id, "rejected")}
                      disabled={actionId === document.id}
                      className="flex h-9 items-center justify-center gap-2 rounded-lg border border-ember/30 bg-ember/10 text-xs font-black text-ember disabled:opacity-50"
                    >
                      <XCircle className="h-3.5 w-3.5" />
                      Refuser
                    </button>
                  </div>
                </article>
              ))}
              {!selectedCase.documents.length ? <div className="rounded-lg border border-dashed border-white/10 p-4 text-sm font-semibold text-slate-500">Aucun document reçu.</div> : null}
            </div>

            <div className="mt-4 rounded-lg border border-white/10 bg-[#101521] p-3">
              <label className="text-[11px] font-black uppercase text-slate-500">
                Note de décision
                <textarea value={decisionReason} onChange={(event) => setDecisionReason(event.target.value)} className="mt-1 min-h-16 w-full rounded-lg border-white/10 bg-ink-900 text-sm text-white" />
              </label>
              <div className="mt-3 grid gap-2 sm:grid-cols-3">
                <CaseButton label="Valider KYC" loading={actionId === "case-APPROVED"} onClick={() => void decideCase("APPROVED")} tone="felt" />
                <CaseButton label="Refuser" loading={actionId === "case-REJECTED"} onClick={() => void decideCase("REJECTED")} tone="ember" />
                <CaseButton label="Expirer" loading={actionId === "case-EXPIRED"} onClick={() => void decideCase("EXPIRED")} tone="gold" />
              </div>
            </div>
          </div>
        ) : null}
      </div>
    </section>
  );
}

function RiskTile({ label, value }: { label: string; value: string | number }) {
  return (
    <div className="rounded-lg bg-white/[0.04] p-2.5">
      <div className="text-[11px] font-black uppercase text-slate-500">{label}</div>
      <div className="mt-1 text-sm font-black text-white">{value}</div>
    </div>
  );
}

function CaseButton({ label, loading, onClick, tone }: { label: string; loading: boolean; onClick: () => void; tone: "felt" | "ember" | "gold" }) {
  return (
    <button
      onClick={onClick}
      disabled={loading}
      className={cn(
        "flex h-9 items-center justify-center gap-2 rounded-lg text-xs font-black disabled:opacity-50",
        tone === "felt" && "bg-felt text-ink-950",
        tone === "ember" && "border border-ember/30 bg-ember/10 text-ember",
        tone === "gold" && "border border-gold/30 bg-gold/10 text-gold"
      )}
    >
      {loading ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : null}
      {label}
    </button>
  );
}

function StatusBadge({ status }: { status: string }) {
  const normalized = status.toUpperCase();
  const tone = normalized.includes("APPROVED") || normalized.includes("ACCEPTED") ? "bg-felt/10 text-felt" : normalized.includes("PENDING") || normalized.includes("UPLOADED") ? "bg-gold/10 text-gold" : "bg-ember/10 text-ember";
  return <span className={cn("w-fit rounded-md px-2 py-1 text-[10px] font-black uppercase", tone)}>{status}</span>;
}

function documentSummary(documents: KycDocument[]) {
  const accepted = documents.filter((document) => document.status === "accepted").length;
  return `${accepted}/${documents.length} docs acceptés`;
}

function documentLabel(type: string) {
  if (type === "IDENTITY_FRONT") return "Pièce d'identité recto";
  if (type === "IDENTITY_BACK") return "Pièce d'identité verso";
  if (type === "PROOF_OF_ADDRESS") return "Justificatif de domicile";
  return "Document complémentaire";
}

function documentFileName(metadata: unknown) {
  if (metadata && typeof metadata === "object" && "originalName" in metadata && typeof metadata.originalName === "string") {
    return metadata.originalName;
  }
  return "fichier sécurisé";
}

function formatDate(value: string) {
  return new Intl.DateTimeFormat("fr-FR", { day: "2-digit", month: "2-digit", hour: "2-digit", minute: "2-digit" }).format(new Date(value));
}
