"use client";

import Link from "next/link";
import { usePathname } from "next/navigation";
import { useEffect, useRef, useState } from "react";
import {
  BadgeHelp,
  CircleDollarSign,
  Dice5,
  Gift,
  Home,
  LifeBuoy,
  Plus,
  ShieldCheck,
  Trophy,
  UserRound
} from "lucide-react";
import { Brand } from "@/components/brand";
import { BetSlip } from "@/components/bet-slip";
import { LoginForm, RegisterForm } from "@/components/auth-forms";
import { MobileDock } from "@/components/mobile-dock";
import { PaymentFlow } from "@/components/payment-flow";
import { SiteFooter } from "@/components/site-footer";
import { SportGlyph } from "@/components/sport-glyph";
import { SupportLiveChatWidget } from "@/components/support-livechat-widget";
import { WALLET_UPDATED_EVENT, WALLET_VISUAL_ADJUSTMENT_EVENT } from "@/lib/client-events";
import { cn } from "@/lib/utils";

const sports = [
  ["football", "Football"],
  ["tennis", "Tennis"],
  ["basketball", "Basketball"],
  ["hockey", "Hockey"],
  ["mma", "MMA"],
  ["esports", "Esports"],
  ["baseball", "Baseball"],
  ["rugby", "Rugby"]
] as const;

const nav = [
  { href: "/", label: "Accueil", icon: Home },
  { href: "/sports", label: "Sports", icon: Trophy },
  { href: "/casino", label: "Casino", icon: Dice5 },
  { href: "/promotions", label: "Promos", icon: Gift },
  { href: "/vip", label: "VIP", icon: CircleDollarSign },
  { href: "/help", label: "Aide", icon: LifeBuoy }
];

export function AppShell({ children }: { children: React.ReactNode }) {
  const pathname = usePathname();
  const isAdmin = pathname?.startsWith("/admin") ?? false;
  const isAffiliation = pathname?.startsWith("/affiliation") ?? false;
  const isAuthPage = pathname === "/login" || pathname === "/register";
  const isSportsbookPage = pathname?.startsWith("/sports") || pathname?.startsWith("/events");
  const useBettingLayout = !isAdmin && Boolean(isSportsbookPage);
  const [session, setSession] = useState<SessionState>({ status: "loading" });
  const [modalIntent, setModalIntent] = useState<ModalIntent>(null);
  const sessionRef = useRef<SessionState>({ status: "loading" });
  const walletVisualHoldUntilRef = useRef(0);
  const visibleNav = session.status === "authenticated" ? nav : nav.filter((item) => item.href !== "/vip");

  useEffect(() => {
    sessionRef.current = session;
  }, [session]);

  useEffect(() => {
    let mounted = true;

    async function loadSession(options: { force?: boolean } = {}) {
      if (!options.force && sessionRef.current.status === "authenticated" && Date.now() < walletVisualHoldUntilRef.current) {
        return;
      }

      try {
        const authResponse = await fetch("/api/auth/me", { cache: "no-store" });
        const authPayload = await authResponse.json();

        if (!mounted) return;

        if (!authResponse.ok || !authPayload.ok) {
          setSession({ status: "guest" });
          return;
        }

        const walletResponse = await fetch("/api/wallet/me", { cache: "no-store" });
        const walletPayload = await walletResponse.json();
        const playableBalance = walletPayload.ok
          ? walletPayload.data.accounts
              .filter((account: { type: string }) => account.type === "AVAILABLE" || account.type === "BONUS")
              .reduce((total: number, account: { balance: string }) => total + Number(account.balance), 0)
              .toString()
          : "0";

        setSession({
          status: "authenticated",
          user: authPayload.data,
          balance: playableBalance,
          currency: walletPayload.ok ? walletPayload.data.currency : authPayload.data.profile?.currency ?? "EUR"
        });
      } catch {
        if (mounted) {
          setSession({ status: "guest" });
        }
      }
    }

    function refreshWallet(event: Event) {
      const force = (event as CustomEvent<{ force?: boolean }>).detail?.force;
      void loadSession({ force });
    }

    function applyWalletVisualAdjustment(event: Event) {
      const detail = (event as CustomEvent<{ delta?: string | number; holdMs?: number }>).detail;
      const delta = Number(detail?.delta);
      if (!Number.isFinite(delta) || delta === 0) return;

      walletVisualHoldUntilRef.current = Math.max(walletVisualHoldUntilRef.current, Date.now() + (detail?.holdMs ?? 8000));
      setSession((current) => {
        if (current.status !== "authenticated") return current;
        return {
          ...current,
          balance: String(Math.max(0, Number(current.balance) + delta))
        };
      });
    }

    void loadSession();

    window.addEventListener(WALLET_UPDATED_EVENT, refreshWallet);
    window.addEventListener(WALLET_VISUAL_ADJUSTMENT_EVENT, applyWalletVisualAdjustment);
    const interval = window.setInterval(loadSession, 15000);
    const refreshWhenVisible = () => {
      if (!document.hidden) {
        void loadSession();
      }
    };
    document.addEventListener("visibilitychange", refreshWhenVisible);

    return () => {
      mounted = false;
      window.removeEventListener(WALLET_UPDATED_EVENT, refreshWallet);
      window.removeEventListener(WALLET_VISUAL_ADJUSTMENT_EVENT, applyWalletVisualAdjustment);
      window.clearInterval(interval);
      document.removeEventListener("visibilitychange", refreshWhenVisible);
    };
  }, [pathname]);

  useEffect(() => {
    function interceptModalLinks(event: MouseEvent) {
      if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;

      const target = event.target;
      if (!(target instanceof Element)) return;
      const anchor = target.closest("a[href]") as HTMLAnchorElement | null;
      if (!anchor || anchor.target === "_blank" || anchor.hasAttribute("download")) return;

      const url = new URL(anchor.href, window.location.href);
      if (url.origin !== window.location.origin) return;

      const nextIntent = modalIntentFromPath(url.pathname);
      if (!nextIntent) return;

      event.preventDefault();
      setModalIntent(nextIntent);
    }

    document.addEventListener("click", interceptModalLinks, true);
    return () => document.removeEventListener("click", interceptModalLinks, true);
  }, []);

  useEffect(() => {
    if (!modalIntent) return;

    const previousOverflow = document.body.style.overflow;
    document.body.style.overflow = "hidden";

    function closeOnEscape(event: KeyboardEvent) {
      if (event.key === "Escape") setModalIntent(null);
    }

    window.addEventListener("keydown", closeOnEscape);
    return () => {
      document.body.style.overflow = previousOverflow;
      window.removeEventListener("keydown", closeOnEscape);
    };
  }, [modalIntent]);

  async function logout() {
    await fetch("/api/auth/logout", { method: "POST" });
    setSession({ status: "guest" });
    window.location.href = "/";
  }

  if (isAffiliation) {
    return <div className="min-h-screen">{children}</div>;
  }

  return (
    <div className={cn("min-h-screen", !isAuthPage && "pb-36 lg:pb-0")}>
      {!isAuthPage ? (
      <header className="sticky top-0 z-40 border-b border-white/10 bg-ink-950/92 backdrop-blur">
        <div className="mx-auto hidden h-16 max-w-[1680px] items-center justify-between gap-3 px-3 sm:px-5 lg:flex">
          <Brand />
          {!isAdmin ? (
            <nav className="hidden items-center gap-1 lg:flex" aria-label="Navigation principale">
              {visibleNav.map((item) => (
                <Link
                  key={item.href}
                  href={item.href}
                  className="flex h-10 items-center gap-2 rounded-lg px-3 text-sm font-semibold text-slate-300 transition hover:bg-white/[0.07] hover:text-white"
                >
                  <item.icon className="h-4 w-4" />
                  {item.label}
                </Link>
              ))}
            </nav>
          ) : (
            <div className="hidden items-center gap-2 lg:flex">
              <span className="rounded-lg border border-felt/25 bg-felt/10 px-3 py-2 text-xs font-black uppercase text-felt">Back-office</span>
              <Link href="/" className="rounded-lg border border-white/10 bg-white/[0.04] px-3 py-2 text-sm font-bold text-slate-200 transition hover:bg-white/[0.07]">
                Retour sportsbook
              </Link>
            </div>
          )}
          <div className="flex items-center gap-2">
            {isAdmin ? (
              <span className="hidden h-10 items-center rounded-lg bg-white/[0.05] px-3 text-sm font-black text-white sm:flex">Session admin</span>
            ) : session.status === "authenticated" ? (
              <AuthenticatedHeaderActions session={session} />
            ) : session.status === "loading" ? (
              <span className="hidden h-10 w-32 animate-pulse rounded-lg bg-white/[0.05] sm:flex" />
            ) : (
              <>
                <Link
                  href="/login"
                  className="hidden h-10 items-center rounded-lg border border-white/10 px-3 text-sm font-semibold text-slate-200 transition hover:bg-white/[0.07] sm:flex"
                >
                  Connexion
                </Link>
                <Link
                  href="/register"
                  className="h-10 rounded-lg bg-felt px-4 text-sm font-black text-ink-950 shadow-lg shadow-felt/20 transition hover:bg-emerald-300"
                >
                  Inscription
                </Link>
              </>
            )}
          </div>
        </div>

        <div className="mx-auto flex h-[60px] max-w-[1680px] items-center justify-between gap-3 px-4 lg:hidden">
          <Brand />
          {isAdmin ? (
            <Link href="/" className="rounded-lg border border-felt/25 bg-felt/10 px-3 py-2 text-xs font-black uppercase text-felt">
              Back-office
            </Link>
          ) : session.status === "authenticated" ? (
            <AuthenticatedHeaderActions session={session} compact />
          ) : session.status === "loading" ? (
            <span className="h-10 w-28 animate-pulse rounded-full bg-white/[0.05]" />
          ) : (
            <GuestHeaderActions compact />
          )}
        </div>
      </header>
      ) : null}

      <div
        className={cn(
          "mx-auto grid max-w-[1680px] grid-cols-1 gap-4 px-5 py-3 sm:px-5 sm:py-4",
          isAdmin ? "lg:grid-cols-1" : useBettingLayout ? "lg:grid-cols-[230px_minmax(0,1fr)_340px]" : "lg:grid-cols-1"
        )}
      >
        {useBettingLayout ? (
        <aside className="hidden lg:block">
          <div className="sticky top-20 space-y-3">
            <section className="surface rounded-lg p-3">
              <div className="mb-3 flex items-center justify-between text-xs font-black uppercase text-slate-400">
                Sports
                <ShieldCheck className="h-4 w-4 text-felt" />
              </div>
              <div className="space-y-1">
                {sports.map(([slug, label]) => (
                  <Link
                    href={`/sports/${slug}`}
                    key={slug}
                    className="flex h-10 items-center justify-between rounded-lg px-3 text-sm font-semibold text-slate-200 transition hover:bg-white/[0.07] hover:text-white"
                  >
                    <span className="flex min-w-0 items-center gap-2">
                      <SportGlyph slug={slug} label={label} className="h-4 w-4 text-slate-400" />
                      <span className="truncate">{label}</span>
                    </span>
                    <span className="text-xs text-felt">●</span>
                  </Link>
                ))}
                <Link
                  href="/casino"
                  className="mt-2 flex h-10 items-center justify-between rounded-lg border border-felt/15 bg-felt/10 px-3 text-sm font-semibold text-slate-100 transition hover:bg-felt/15 hover:text-white"
                >
                  <span className="flex min-w-0 items-center gap-2">
                    <Dice5 className="h-4 w-4 text-felt" />
                    <span className="truncate">Casino</span>
                  </span>
                  <span className="text-xs text-felt">●</span>
                </Link>
              </div>
            </section>
            <section className="surface rounded-lg p-3">
              <div className="mb-2 flex items-center gap-2 text-sm font-black text-white">
                <BadgeHelp className="h-4 w-4 text-gold" />
                Jeu responsable
              </div>
              <p className="text-xs leading-5 text-slate-400">
                18+ uniquement. Limites, pauses et auto-exclusion disponibles depuis le profil.
              </p>
              <Link href="/responsible-gaming" className="mt-3 inline-flex text-xs font-bold text-felt">
                Voir les outils
              </Link>
            </section>
          </div>
        </aside>
        ) : null}

        <main className={cn("min-w-0", isAdmin ? "mx-auto w-full max-w-[1280px]" : !useBettingLayout ? "mx-auto w-full max-w-[1120px]" : "")}>
          {children}
          {!isAdmin && !isAuthPage ? <SiteFooter /> : null}
        </main>

        {useBettingLayout ? (
        <aside className="hidden lg:block">
          <div className="sticky top-20">
            <BetSlip isAuthenticated={session.status === "authenticated"} />
          </div>
        </aside>
        ) : null}
      </div>

      {!isAdmin && !isAuthPage ? <MobileDock isAuthenticated={session.status === "authenticated"} onLogout={logout} /> : null}
      {!isAdmin && !isAuthPage ? <SupportLiveChatWidget sessionStatus={session.status} /> : null}
      <ModalHost intent={modalIntent} sessionStatus={session.status} onClose={() => setModalIntent(null)} />
    </div>
  );
}

type ModalIntent = "login" | "register" | "wallet-overview" | "wallet-deposit" | "wallet-withdraw" | null;

type SessionUser = {
  id: string;
  email: string;
  username: string;
  roles: string[];
  profile?: { currency?: string } | null;
};

type SessionState =
  | { status: "loading" }
  | { status: "guest" }
  | {
      status: "authenticated";
      user: SessionUser;
      balance: string;
      currency: string;
    };

function modalIntentFromPath(pathname: string): ModalIntent {
  if (pathname === "/login") return "login";
  if (pathname === "/register") return "register";
  if (pathname === "/wallet") return "wallet-overview";
  if (pathname === "/wallet/deposit") return "wallet-deposit";
  if (pathname === "/wallet/withdraw") return "wallet-withdraw";
  return null;
}

function ModalHost({ intent, sessionStatus, onClose }: { intent: ModalIntent; sessionStatus: SessionState["status"]; onClose: () => void }) {
  if (!intent) return null;

  const isWalletIntent = intent === "wallet-overview" || intent === "wallet-deposit" || intent === "wallet-withdraw";
  const walletTab = intent === "wallet-deposit" ? "deposit" : intent === "wallet-withdraw" ? "withdraw" : "overview";
  const content =
    intent === "login" ? (
      <LoginForm onClose={onClose} />
    ) : intent === "register" || (isWalletIntent && sessionStatus !== "authenticated") ? (
      <RegisterForm onClose={onClose} />
    ) : (
      <PaymentFlow initialTab={walletTab} onClose={onClose} />
    );

  return (
    <div className="fixed inset-0 z-[90] overflow-y-auto bg-black/72 px-3 py-4 backdrop-blur-md sm:py-7" role="dialog" aria-modal="true" onClick={onClose}>
      <div className="flex min-h-full items-start justify-center" onClick={(event) => event.stopPropagation()}>
        {content}
      </div>
    </div>
  );
}

function AuthenticatedHeaderActions({ session, compact = false }: { session: Extract<SessionState, { status: "authenticated" }>; compact?: boolean }) {
  return (
    <div className="flex items-center gap-2.5">
      <Link
        href="/wallet/deposit"
        className={cn("flex items-center rounded-full bg-[#171d2d] shadow-panel", compact ? "h-10 gap-2.5 pl-3.5 pr-1" : "h-10 gap-3 pl-4 pr-1")}
        aria-label="Solde et dépôt"
      >
        <span className={cn("font-black text-felt", compact ? "text-sm" : "text-base")}>{formatBalance(session.balance, session.currency)}</span>
        <span className="grid h-8 w-8 place-items-center rounded-full bg-felt text-ink-950">
          <Plus className="h-4 w-4" />
        </span>
      </Link>
      <Link href="/profile" className="grid h-10 w-10 place-items-center rounded-full bg-[#252c3e] text-slate-300" aria-label="Profil">
        <UserRound className="h-5 w-5" />
      </Link>
    </div>
  );
}

function GuestHeaderActions({ compact = false }: { compact?: boolean }) {
  return (
    <div className="flex items-center gap-2">
      <Link
        href="/login"
        className={cn(
          "grid place-items-center rounded-lg border border-white/10 bg-white/[0.04] font-black text-slate-100",
          compact ? "h-9 px-3 text-xs" : "h-10 px-4 text-sm"
        )}
      >
        Connexion
      </Link>
      <Link href="/register" className={cn("grid place-items-center rounded-lg bg-felt font-black text-ink-950", compact ? "h-9 px-3 text-xs" : "h-10 px-4 text-sm")}>
        Inscription
      </Link>
    </div>
  );
}

function formatBalance(balance: string, currency: string) {
  return new Intl.NumberFormat("fr-FR", { style: "currency", currency }).format(Number(balance));
}
