"use client";
import { useEffect, useRef, useState } from "react";
import { createPortal } from "react-dom";
import Link from "next/link";
import { CalendarClock, ChevronDown, LogIn, Settings, Shield, ShoppingBag, UserRound, Utensils, X } from "lucide-react";

type User = { id: number; name: string; email?: string | null; avatarUrl?: string | null; role: "user" | "admin" };
type Config = { enabled: boolean; providers: { vk: boolean; yandex: boolean }; telegram: { enabled: boolean; url: string | null }; max: { enabled: boolean; url: string | null } };

function LoginChoices({ config, onDone }: { config: Config | null; onDone: () => void }) {
  const [consent, setConsent] = useState(false);
  return <>
    <div className={`grid gap-3 transition ${!consent ? "pointer-events-none opacity-50" : ""}`} aria-disabled={!consent}>
      {config?.providers.vk !== false ? <a className="button button-primary" href="/api/auth/vk" aria-disabled={!consent}>Войти через VK</a> : null}
      {config?.providers.yandex !== false ? <a className="button button-secondary" href="/api/auth/yandex" aria-disabled={!consent}>Войти через Яндекс</a> : null}
      {config?.telegram.enabled ? <MessengerLogin messenger="telegram" label="Telegram" onDone={onDone} /> : null}
      {config?.max.enabled ? <MessengerLogin messenger="max" label="MAX" onDone={onDone} /> : null}
      <EmailLogin onDone={onDone} />
    </div>
    <label className="mt-5 flex items-start gap-3 text-xs leading-relaxed text-kiln-milk/70"><input className="mt-0.5 h-4 w-4 shrink-0" type="checkbox" checked={consent} onChange={(event) => setConsent(event.target.checked)} required aria-required="true" /><span>Продолжая, вы принимаете <Link className="text-kiln-flame underline" href="/offer">Пользовательское соглашение</Link> и соглашаетесь с <Link className="text-kiln-flame underline" href="/personal-data-consent">обработкой персональных данных</Link>.</span></label>
  </>;
}

export function AccountLoginPanel() {
  const [config, setConfig] = useState<Config | null>(null);
  useEffect(() => { fetch("/api/auth/config", { cache: "no-store" }).then((response) => response.json()).then(setConfig).catch(() => setConfig(null)); }, []);
  if (!config) return <div className="card p-6"><p className="muted">Загружаем способы входа…</p></div>;
  if (!config.enabled) return <div className="card p-6"><p className="muted">Вход в личный кабинет временно отключён.</p></div>;
  return <div className="card p-6"><p className="eyebrow">Авторизация</p><h2 className="mb-6 mt-1 text-3xl">Войти на сайт</h2><LoginChoices config={config} onDone={() => location.reload()} /></div>;
}

function MessengerLogin({ messenger, label, onDone }: { messenger: "telegram" | "max"; label: string; onDone: () => void }) {
  const [state, setState] = useState<"idle" | "waiting" | "error">("idle");
  const [command, setCommand] = useState("");
  const [url, setUrl] = useState<string | null>(null);
  const timer = useRef(0);

  useEffect(() => () => window.clearInterval(timer.current), []);

  async function start() {
    setState("waiting");
    try {
      const response = await fetch("/api/auth/messenger/start", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ messenger }) });
      const body = await response.json();
      if (!response.ok) throw new Error(body.error || "Не удалось начать вход");
      setCommand(body.command);
      setUrl(body.url);
      if (body.url) window.open(body.url, "_blank", "noopener");
      window.clearInterval(timer.current);
      timer.current = window.setInterval(async () => {
        try {
          const status = await fetch(`/api/auth/messenger/status?nonce=${encodeURIComponent(body.nonce)}`, { cache: "no-store" });
          const data = await status.json();
          if (data.status === "ok") { window.clearInterval(timer.current); onDone(); }
          if (data.status === "expired" || data.status === "unknown") { window.clearInterval(timer.current); setState("error"); }
        } catch { /* keep waiting */ }
      }, 2000);
    } catch {
      setState("error");
    }
  }

  return <div className="grid gap-2">
    <button type="button" className="button button-secondary" onClick={start} disabled={state === "waiting"}>{state === "waiting" ? `Ждём подтверждения в ${label}…` : `Войти через ${label}`}</button>
    {state === "waiting" ? <p className="text-xs leading-relaxed text-kiln-milk/70">Откройте бота и отправьте команду — вход произойдёт без подписки на уведомления.{url ? <> Не открылось? <a className="text-kiln-flame underline" href={url} target="_blank" rel="noreferrer">Открыть {label}</a>.</> : null}</p> : null}
    {state === "waiting" && command ? <label className="flex items-center gap-2 text-xs text-kiln-milk/70"><input className="input min-w-0 flex-1 text-xs" readOnly value={command} onFocus={(event) => event.currentTarget.select()} /><button type="button" className="button button-secondary" onClick={() => navigator.clipboard?.writeText(command)}>Копировать</button></label> : null}
    {state === "error" ? <p className="text-xs text-kiln-flame">Ссылка устарела — попробуйте ещё раз.</p> : null}
  </div>;
}

function EmailLogin({ onDone }: { onDone: () => void }) {
  const [open, setOpen] = useState(false);
  const [email, setEmail] = useState("");
  const [code, setCode] = useState("");
  const [codeSent, setCodeSent] = useState(false);
  const [cooldown, setCooldown] = useState(0);
  const [busy, setBusy] = useState(false);
  const [message, setMessage] = useState("");

  useEffect(() => {
    if (cooldown <= 0) return;
    const timer = window.setTimeout(() => setCooldown((value) => value - 1), 1000);
    return () => window.clearTimeout(timer);
  }, [cooldown]);

  async function request(event: React.FormEvent) {
    event.preventDefault();
    if (busy || cooldown > 0) return;
    setBusy(true); setMessage("");
    try {
      const response = await fetch("/api/account/email/request", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email }) });
      const body = await response.json();
      if (!response.ok) throw new Error(body.message || "Не удалось отправить код.");
      setCodeSent(true); setCooldown(60); setMessage("Код отправлен на почту.");
    } catch (error) { setMessage(error instanceof Error ? error.message : "Не удалось отправить код."); }
    finally { setBusy(false); }
  }

  async function verify(event: React.FormEvent) {
    event.preventDefault();
    if (busy) return;
    setBusy(true); setMessage("");
    try {
      const response = await fetch("/api/account/email/verify", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email, code }) });
      const body = await response.json();
      if (!response.ok) throw new Error(body.message || "Не удалось проверить код.");
      onDone();
    } catch (error) { setMessage(error instanceof Error ? error.message : "Не удалось проверить код."); }
    finally { setBusy(false); }
  }

  if (!open) return <button type="button" className="button button-secondary" onClick={() => setOpen(true)}>Войти по почте</button>;
  return <div className="grid gap-2">
    <form className="grid gap-2 sm:grid-cols-[1fr_auto]" onSubmit={request}>
      <input className="input" type="email" placeholder="email@example.ru" value={email} onChange={(event) => setEmail(event.target.value)} required />
      <button className="button button-secondary" disabled={busy || cooldown > 0 || email.length < 5}>{cooldown > 0 ? `Повтор через ${cooldown} с` : codeSent ? "Отправить ещё раз" : "Отправить код"}</button>
    </form>
    {codeSent ? (
      <form className="grid gap-2 sm:grid-cols-[1fr_auto]" onSubmit={verify}>
        <input className="input" inputMode="numeric" placeholder="Код из письма" value={code} onChange={(event) => setCode(event.target.value)} required minLength={4} maxLength={10} />
        <button className="button button-primary" disabled={busy || code.length < 4}>Войти</button>
      </form>
    ) : null}
    {message ? <p className="text-xs text-kiln-flame">{message}</p> : null}
  </div>;
}

export function AuthTrigger() {
  const [open, setOpen] = useState(false);
  const [user, setUser] = useState<User | null>(null);
  const [enabled, setEnabled] = useState(false);
  const [config, setConfig] = useState<Config | null>(null);
  const menuRef = useRef<HTMLDivElement>(null);
  useEffect(() => { Promise.all([fetch("/api/auth/me"), fetch("/api/auth/config")]).then(async ([me, authConfig]) => { const meData = await me.json(); const configData = await authConfig.json(); setUser(meData.user); setEnabled(configData.enabled); setConfig(configData); }); }, []);
  useEffect(() => {
    if (!open || !user) return;
    const close = (event: MouseEvent) => { if (!menuRef.current?.contains(event.target as Node)) setOpen(false); };
    const escape = (event: KeyboardEvent) => { if (event.key === "Escape") setOpen(false); };
    document.addEventListener("mousedown", close);
    document.addEventListener("keydown", escape);
    return () => { document.removeEventListener("mousedown", close); document.removeEventListener("keydown", escape); };
  }, [open, user]);
  async function logout() { await fetch("/api/auth/logout", { method: "POST" }); setUser(null); setOpen(false); }
  const done = () => location.reload();
  if (user) return <div className="relative" ref={menuRef}>
    <button type="button" className="icon-button gap-1" aria-label="Меню профиля" aria-haspopup="menu" aria-expanded={open} data-tooltip="Профиль" onClick={() => setOpen((value) => !value)}>
      {user.avatarUrl ? <>
        {/* eslint-disable-next-line @next/next/no-img-element */}
        <img src={user.avatarUrl} alt="" className="h-7 w-7 rounded-full object-cover" />
      </> : <UserRound size={20} />}
      <ChevronDown size={13} />
    </button>
    {open ? <div className="absolute right-0 top-full z-50 mt-2 w-64 rounded-xl border border-white/10 bg-kiln-black p-2 shadow-2xl" role="menu">
      <div className="border-b border-white/10 px-3 py-2"><strong className="block truncate">{user.name}</strong>{user.email ? <small className="block truncate text-kiln-milk/60">{user.email}</small> : null}</div>
      <div className="py-2">
        <Link href="/account" className="flex items-center gap-2 rounded-lg px-3 py-2 hover:bg-white/10" role="menuitem" onClick={() => setOpen(false)}><Settings size={17} /> Настройки</Link>
        <Link href="/account/orders" className="flex items-center gap-2 rounded-lg px-3 py-2 hover:bg-white/10" role="menuitem" onClick={() => setOpen(false)}><ShoppingBag size={17} /> Мои заказы</Link>
        <Link href="/account/bookings" className="flex items-center gap-2 rounded-lg px-3 py-2 hover:bg-white/10" role="menuitem" onClick={() => setOpen(false)}><CalendarClock size={17} /> Мои бронирования</Link>
        {user.role === "admin" ? <><p className="flex items-center gap-2 px-3 pb-1 pt-3 text-xs uppercase tracking-wider text-kiln-flame"><Shield size={14} /> Администратор</p><Link href="/admin/menu" className="flex items-center gap-2 rounded-lg px-3 py-2 hover:bg-white/10" role="menuitem" onClick={() => setOpen(false)}><Utensils size={17} /> Управление меню</Link><Link href="/admin/settings" className="flex items-center gap-2 rounded-lg px-3 py-2 hover:bg-white/10" role="menuitem" onClick={() => setOpen(false)}><Settings size={17} /> Настройки сайта</Link></> : null}
      </div>
      <button type="button" className="w-full border-t border-white/10 px-3 py-2 text-left hover:bg-white/10" role="menuitem" onClick={logout}>Выйти</button>
    </div> : null}
  </div>;

  if (!enabled) return null;
  return <><button type="button" className="icon-button" aria-label="Открыть авторизацию" data-tooltip="Войти" onClick={() => setOpen(true)}><LogIn size={20} /></button>{open && typeof document !== "undefined" ? createPortal(<div className="auth-modal-backdrop" role="presentation" onMouseDown={(event) => event.target === event.currentTarget && setOpen(false)}><section className="card max-h-[90dvh] w-full max-w-md overflow-y-auto p-6" role="dialog" aria-modal="true" aria-labelledby="auth-title"><div className="flex items-start justify-between gap-4"><div><p className="eyebrow">Авторизация</p><h2 id="auth-title" className="mt-1 text-3xl">Войти на сайт</h2></div><button type="button" className="icon-button shrink-0" onClick={() => setOpen(false)} aria-label="Закрыть"><X size={18} /></button></div><div className="mt-6"><LoginChoices config={config} onDone={done} /></div></section></div>, document.body) : null}</>;
}
