"use client";

import { useEffect, useMemo, useState } from "react";
import { Check, ChevronDown, Crown, Gem, Gift, Loader2, LockKeyhole, Rocket, XCircle } from "lucide-react";
import { cn } from "@/lib/utils";

type VipPayload = {
  user: {
    id: string;
    email: string;
    username: string;
    currency: string;
  };
  progress: {
    tierKey: string;
    rollingVolume: string;
    lifetimeVolume: string;
  };
  tiers: VipTier[];
  bonuses: UserBonus[];
};

type VipTier = {
  key: string;
  name: string;
  minVolume: string;
  cashbackBps: number;
  rakebackBps: number;
  perks: unknown;
  sortOrder: number;
};

type UserBonus = {
  id: string;
  status: string;
  bonusAmount: string;
  wagerRequired: string;
  wagerProgress: string;
  expiresAt?: string | null;
  createdAt: string;
  promotion: {
    name: string;
    type: string;
    currency: string;
    terms: string;
    wageringMultiplier: string;
  };
};

const benefitRows = [
  { label: "Bonus quotidien", enabled: (tier: VipTier) => tier.rakebackBps > 0 },
  { label: "Bonus hebdomadaire", enabled: (tier: VipTier) => tier.cashbackBps > 0 },
  { label: "Bonus de montée en grade", enabled: (tier: VipTier) => levelBonusAmount(tier.perks) > 0 },
  { label: "Cashback sport", enabled: (tier: VipTier) => tier.cashbackBps >= 50 },
  { label: "Support prioritaire", enabled: (tier: VipTier) => perkValue(tier.perks, "support") === "priority" || Boolean(perkValue(tier.perks, "manager")) },
  { label: "Hôte VIP", enabled: (tier: VipTier) => Boolean(perkValue(tier.perks, "manager")) }
];

export function VipDashboard() {
  const [data, setData] = useState<VipPayload | null>(null);
  const [message, setMessage] = useState("");
  const [loading, setLoading] = useState(true);
  const [actingId, setActingId] = useState<string | null>(null);

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

  async function loadVip() {
    setLoading(true);
    setMessage("");
    const response = await fetch("/api/vip/me", { cache: "no-store" });
    const payload = await response.json();
    setLoading(false);

    if (!payload.ok) {
      setMessage(payload.error?.message ?? "Impossible de charger le VIP.");
      return;
    }

    setData(payload.data);
  }

  async function actOnBonus(id: string, action: "accept" | "refuse") {
    setActingId(id);
    setMessage("");
    const response = await fetch(`/api/vip/bonuses/${id}`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ action })
    });
    const payload = await response.json();
    setActingId(null);

    if (!payload.ok) {
      setMessage(payload.error?.message ?? "Action bonus impossible.");
      return;
    }

    await loadVip();
  }

  const sortedTiers = useMemo(() => [...(data?.tiers ?? [])].sort((left, right) => Number(left.minVolume) - Number(right.minVolume)), [data?.tiers]);
  const lifetimeVolume = Number(data?.progress.lifetimeVolume ?? 0);
  const currentTier =
    sortedTiers
      .filter((tier) => Number(tier.minVolume) <= lifetimeVolume)
      .at(-1) ??
    sortedTiers.find((tier) => tier.key === data?.progress.tierKey) ??
    sortedTiers[0];
  const currentIndex = currentTier ? sortedTiers.findIndex((tier) => tier.key === currentTier.key) : -1;
  const nextTier = sortedTiers.find((tier) => Number(tier.minVolume) > lifetimeVolume);
  const currentMinVolume = Number(currentTier?.minVolume ?? 0);
  const nextMinVolume = Number(nextTier?.minVolume ?? currentMinVolume);
  const progressPercent = nextTier ? clamp(((lifetimeVolume - currentMinVolume) / Math.max(1, nextMinVolume - currentMinVolume)) * 100, 0, 100) : 100;
  const visibleBonuses = useMemo(
    () => (data?.bonuses ?? []).filter((bonus) => bonus.status === "OFFERED" || bonus.status === "ACTIVE"),
    [data?.bonuses]
  );
  const offeredBonuses = visibleBonuses.filter((bonus) => bonus.status === "OFFERED");
  const currency = data?.user.currency ?? "EUR";

  return (
    <div className="space-y-4">
      <section className="rounded-lg border border-white/10 bg-[#11161c] p-3 shadow-panel sm:p-4">
        {loading ? (
          <div className="grid min-h-24 place-items-center">
            <Loader2 className="h-5 w-5 animate-spin text-felt" />
          </div>
        ) : null}

        {data ? (
          <>
            <div className="flex items-center gap-2.5">
              <span className="grid h-10 w-10 shrink-0 place-items-center rounded-lg bg-felt/10 text-felt">
                <Crown className="h-4 w-4" />
              </span>
              <div className="min-w-0 flex-1">
                <h1 className="text-xl font-extrabold leading-tight text-white">Programme VIP</h1>
                <div className="mt-0.5 flex min-w-0 items-center gap-1.5 text-xs font-semibold text-slate-400">
                  <span className="truncate">{data.user.username}</span>
                  <span className="text-slate-600">•</span>
                  <TierMark tier={currentTier} small />
                  <span>{currentTier?.name ?? "VIP"}</span>
                </div>
              </div>
            </div>

            <div className="mt-3 flex items-center justify-between gap-3">
              <h2 className="text-xs font-semibold text-white">Vos progrès VIP</h2>
              <span className="text-xs font-extrabold text-white">{progressPercent.toFixed(2).replace(".", ",")} %</span>
            </div>
            <div className="mt-2 h-1.5 overflow-hidden rounded-full bg-white/[0.11]">
              <div className="h-full rounded-full bg-felt" style={{ width: `${progressPercent}%` }} />
            </div>
            <div className="mt-2 flex items-center justify-between gap-3 text-[11px] font-semibold text-slate-400">
              <span className="flex min-w-0 items-center gap-1.5">
                <TierMark tier={currentTier} small />
                <span className="truncate">{currentTier?.name ?? "VIP"}</span>
              </span>
              <span className="flex min-w-0 items-center gap-1.5 text-right">
                <TierMark tier={nextTier} small />
                <span className="truncate">{nextTier ? nextTier.name : "Niveau max"}</span>
              </span>
            </div>
          </>
        ) : null}
      </section>

      {message ? <div className="rounded-lg border border-ember/30 bg-ember/10 p-3 text-sm font-semibold text-ember">{message}</div> : null}

      {data ? (
        <>
          <section className="space-y-4">
            <div className="flex items-center gap-2.5">
              <Gift className="h-5 w-5 text-felt" />
              <h2 className="text-xl font-extrabold text-white">Vos récompenses</h2>
              <span className="grid h-8 min-w-8 place-items-center rounded-lg bg-felt px-2.5 text-sm font-extrabold text-ink-950">{offeredBonuses.length}</span>
            </div>

            <div className="grid grid-cols-2 gap-2">
              {visibleBonuses.length ? (
                visibleBonuses.map((bonus) => (
                  <RewardCard key={bonus.id} bonus={bonus} acting={actingId === bonus.id} onAccept={() => void actOnBonus(bonus.id, "accept")} onRefuse={() => void actOnBonus(bonus.id, "refuse")} />
                ))
              ) : (
                <div className="col-span-2 rounded-lg border border-white/10 bg-[#11161c] p-4 text-xs font-semibold text-slate-400">
                  Aucune récompense disponible pour le moment.
                </div>
              )}
            </div>
          </section>

          <section className="space-y-4">
            <div className="flex items-center gap-2.5">
              <Crown className="h-5 w-5 text-felt" />
              <h2 className="text-xl font-extrabold text-white">Niveaux de VIP</h2>
            </div>
            <div className="space-y-2">
              {sortedTiers.map((tier, index) => {
                const unlocked = index <= currentIndex;
                const active = tier.key === currentTier?.key;
                return (
                  <details key={tier.key} open={active} className="group rounded-lg border border-white/10 bg-black/20">
                    <summary className="flex cursor-pointer list-none items-center gap-2.5 px-3 py-3 [&::-webkit-details-marker]:hidden">
                      <TierMark tier={tier} />
                      <span className={cn("min-w-0 flex-1 truncate text-base font-semibold", active ? "text-felt" : "text-white")}>{tier.name}</span>
                      <LockKeyhole className={cn("h-4 w-4", unlocked ? "text-felt" : "text-ember")} />
                      <ChevronDown className="h-4 w-4 text-slate-200 transition group-open:rotate-180" />
                    </summary>
                    <div className="mx-3 border-t border-white/10 pb-3 pt-2.5">
                      <div className="grid grid-cols-2 gap-3 text-xs">
                        <div className="text-slate-500">Niveau</div>
                        <div className="text-slate-500">Wager requis</div>
                        <div className="flex items-center gap-2 font-semibold text-white">
                          <TierMark tier={tier} small />
                          {tier.name}
                        </div>
                        <div className="font-semibold text-white">{money(tier.minVolume, currency)}</div>
                      </div>
                    </div>
                  </details>
                );
              })}
            </div>
          </section>

          <section className="space-y-4">
            <div className="flex items-center gap-2.5">
              <Rocket className="h-5 w-5 text-felt" />
              <h2 className="text-xl font-extrabold text-white">Bénéfices</h2>
            </div>
            <div className="overflow-x-auto pb-1 scrollbar-thin">
              <div className="min-w-[680px]">
                <div className="grid border-b border-white/15 pb-2.5 text-xs font-semibold text-slate-500" style={{ gridTemplateColumns: `190px repeat(${sortedTiers.length}, minmax(80px, 1fr))` }}>
                  <span>Rang VIP</span>
                  {sortedTiers.map((tier) => (
                    <span key={tier.key} className="text-center">
                      {tier.name}
                    </span>
                  ))}
                </div>
                <div className="mt-3 space-y-2">
                  {benefitRows.map((row, index) => (
                    <div
                      key={row.label}
                      className={cn("grid min-h-11 items-center rounded-lg px-3 text-xs", index % 2 ? "bg-[#11161c]" : "bg-transparent")}
                      style={{ gridTemplateColumns: `190px repeat(${sortedTiers.length}, minmax(80px, 1fr))` }}
                    >
                      <span className="font-semibold text-white">{row.label}</span>
                      {sortedTiers.map((tier) => (
                        <span key={`${row.label}-${tier.key}`} className="grid place-items-center">
                          {row.enabled(tier) ? (
                            <span className="grid h-6 w-6 place-items-center rounded-full bg-felt text-ink-950">
                              <Check className="h-3.5 w-3.5" />
                            </span>
                          ) : (
                            <span className="h-1 w-5 rounded-full bg-white/10" />
                          )}
                        </span>
                      ))}
                    </div>
                  ))}
                </div>
              </div>
            </div>
          </section>
        </>
      ) : null}
    </div>
  );
}

function RewardCard({ bonus, acting, onAccept, onRefuse }: { bonus: UserBonus; acting: boolean; onAccept: () => void; onRefuse: () => void }) {
  const wagerRequired = Number(bonus.wagerRequired);
  const wagerProgress = Number(bonus.wagerProgress);
  const progress = wagerRequired > 0 ? clamp((wagerProgress / wagerRequired) * 100, 0, 100) : 100;
  const isPendingWelcome = bonus.promotion.type === "welcome_deposit" && Number(bonus.bonusAmount) <= 0;

  return (
    <article className="min-h-[160px] rounded-lg border border-white/10 bg-[#11161c] p-2.5">
      <div className="flex items-start justify-between gap-2">
        <div className="min-w-0">
          <span className={cn("rounded-md px-2 py-0.5 text-[10px] font-bold uppercase", statusTone(bonus.status))}>{statusLabel(bonus.status)}</span>
          <h3 className="mt-2 line-clamp-2 text-xs font-semibold leading-4 text-white">{bonus.promotion.name}</h3>
        </div>
        <Gift className="h-4 w-4 shrink-0 text-slate-300" />
      </div>

      <div className="mt-2 text-base font-extrabold text-felt">{isPendingWelcome ? "Premier dépôt" : money(bonus.bonusAmount, bonus.promotion.currency)}</div>
      <div className="mt-1 text-[11px] font-semibold text-slate-500">{isPendingWelcome ? "Crédité au dépôt" : `Wager x${bonus.promotion.wageringMultiplier}`}</div>

      <div className="mt-3 h-1.5 overflow-hidden rounded-full bg-white/[0.12]">
        <div className="h-full rounded-full bg-felt" style={{ width: `${progress}%` }} />
      </div>
      <div className="mt-1 flex items-center justify-between gap-2 text-[10px] font-bold text-slate-500">
        <span>Wager</span>
        <span className="text-slate-300">
          {isPendingWelcome ? "après dépôt" : `${money(Math.min(wagerProgress, wagerRequired), bonus.promotion.currency)} / ${money(wagerRequired, bonus.promotion.currency)}`}
        </span>
      </div>
      <p className="mt-2 line-clamp-2 text-[11px] leading-4 text-slate-400">{bonus.promotion.terms}</p>

      {bonus.status === "OFFERED" ? (
        <div className="mt-3 grid gap-2">
          {!isPendingWelcome ? (
            <button onClick={onAccept} disabled={acting} className="grid h-8 place-items-center rounded-lg bg-felt text-xs font-extrabold text-ink-950 disabled:opacity-60">
              {acting ? <Loader2 className="h-4 w-4 animate-spin" /> : "Accepter"}
            </button>
          ) : null}
          <button onClick={onRefuse} disabled={acting} className="flex h-7 items-center justify-center gap-1 rounded-lg border border-white/10 bg-white/[0.04] text-[11px] font-bold text-slate-200 disabled:opacity-60">
            <XCircle className="h-3.5 w-3.5" />
            {isPendingWelcome ? "Refuser ce bonus" : "Refuser"}
          </button>
        </div>
      ) : null}
    </article>
  );
}

function TierMark({ tier, small = false }: { tier?: VipTier; small?: boolean }) {
  const classes = tierAccent(tier?.key ?? tier?.name ?? "vip");
  return (
    <span className={cn("grid shrink-0 place-items-center rounded-md", small ? "h-5 w-5" : "h-8 w-8", classes.bg)}>
      <Gem className={cn(small ? "h-3.5 w-3.5" : "h-4 w-4", classes.text)} />
    </span>
  );
}

function tierAccent(value: string) {
  const key = value.toLowerCase();
  if (key.includes("wood") || key.includes("bois")) return { bg: "bg-amber-400/10", text: "text-amber-300" };
  if (key.includes("bronze")) return { bg: "bg-orange-300/10", text: "text-orange-200" };
  if (key.includes("silver") || key.includes("argent")) return { bg: "bg-slate-200/10", text: "text-slate-200" };
  if (key.includes("gold") || key.includes("or")) return { bg: "bg-gold/10", text: "text-gold" };
  if (key.includes("platinum") || key.includes("platine")) return { bg: "bg-indigo-300/10", text: "text-indigo-200" };
  if (key.includes("jade")) return { bg: "bg-felt/10", text: "text-felt" };
  if (key.includes("sapphire") || key.includes("saphir")) return { bg: "bg-blue-300/10", text: "text-blue-300" };
  if (key.includes("ruby") || key.includes("rubis") || key.includes("black")) return { bg: "bg-ember/10", text: "text-ember" };
  return { bg: "bg-felt/10", text: "text-felt" };
}

function statusLabel(status: string) {
  const labels: Record<string, string> = {
    OFFERED: "À accepter",
    ACTIVE: "Actif",
    WAGERING_COMPLETE: "Complété",
    EXPIRED: "Expiré",
    CANCELLED: "Refusé"
  };
  return labels[status] ?? status;
}

function statusTone(status: string) {
  if (status === "OFFERED") return "bg-gold/10 text-gold";
  if (status === "ACTIVE" || status === "WAGERING_COMPLETE") return "bg-felt/10 text-felt";
  return "bg-ember/10 text-ember";
}

function money(value: string | number, currency: string) {
  return new Intl.NumberFormat("fr-FR", { style: "currency", currency }).format(Number(value));
}

function levelBonusAmount(perks: unknown) {
  const value = perkValue(perks, "levelBonusAmount");
  return typeof value === "number" || typeof value === "string" ? Number(value) : 0;
}

function perkValue(perks: unknown, key: string) {
  if (typeof perks === "object" && perks !== null && key in perks) {
    return (perks as Record<string, unknown>)[key];
  }
  return undefined;
}

function clamp(value: number, min: number, max: number) {
  return Math.min(max, Math.max(min, value));
}
