"use client";
import { ApiError } from "@sheikbras/api-client";
import Link from "next/link";
import { useRouter, useSearchParams } from "next/navigation";
import { useEffect, useRef, useState, type FormEvent, type ReactNode } from "react";
import { hasErrors, passwordStrength, validateLogin, validateRegister } from "@sheikbras/domain";
import { LogoMark } from "@sheikbras/ui-web";
import { api, apiEnabled, safeNext, useAuth } from "../lib/auth";
import { useStore } from "../lib/store";

type Errs = Record<string, string | undefined>;
const Shell = ({ title, sub, children }: { title: string; sub?: string; children: ReactNode }) => (
  <main className="wrap"><div className="au"><div style={{ textAlign: "center" }}><LogoMark size={56} tile /><h1 className="vt" style={{ marginTop: 12, fontSize: 24 }}>{title}</h1>{sub ? <p className="ms" style={{ margin: "6px 0 0" }}>{sub}</p> : null}</div>{children}</div></main>
);
function Field({ id, label, value, onChange, error, type = "text", hint, autoComplete, inputMode }: { id: string; label: string; value: string; onChange: (v: string) => void; error?: string; type?: string; hint?: string; autoComplete?: string; inputMode?: "numeric" | "email" }) {
  const [show, setShow] = useState(false);
  return (
    <div className="fd"><label htmlFor={id}>{label}</label>
      <div style={{ position: "relative" }}><input id={id} type={type === "password" && show ? "text" : type} value={value} onChange={(e) => onChange(e.target.value)} aria-invalid={error ? true : undefined} aria-describedby={error || hint ? id + "-d" : undefined} autoComplete={autoComplete} inputMode={inputMode} style={{ width: "100%" }} />
        {type === "password" ? <button type="button" onClick={() => setShow(!show)} style={{ position: "absolute", right: 12, top: 0, height: 44, border: 0, background: "none", color: "var(--primary)", fontWeight: 600, fontSize: 13 }} aria-label={show ? "Ocultar senha" : "Mostrar senha"}>{show ? "Ocultar" : "Mostrar"}</button> : null}</div>
      {error ? <span id={id + "-d"} className="er" role="alert">{error}</span> : hint ? <span id={id + "-d"} className="hint" style={{ fontSize: 12, color: "var(--muted)" }}>{hint}</span> : null}</div>
  );
}
const DemoNote = () => (!apiEnabled ? <p className="notice" style={{ margin: 0 }}>Modo demonstração: as contas ficam só neste navegador. Para contas reais, conecte a API (<code>NEXT_PUBLIC_API_URL</code>).</p> : null);
const fromApi = (e: unknown): { general?: string; fields: Errs } => e instanceof ApiError ? { general: e.code === "VALIDATION" ? undefined : e.code === "EMAIL_TAKEN" ? undefined : e.message, fields: { ...(e.details ?? {}), ...(e.code === "EMAIL_TAKEN" ? { email: e.message } : {}), ...(e.code === "VALIDATION" && !e.details ? {} : {}) } } : { general: "Algo deu errado. Tente novamente.", fields: {} };

export function LoginForm({ preview }: { preview?: { email?: string; senha?: string; err?: Errs; general?: string; needCode?: boolean } } = {}) {
  const { login } = useAuth(); const router = useRouter(); const next = safeNext(useSearchParams()?.get("next")); const { notify } = useStore();
  const [email, setEmail] = useState(preview?.email ?? ""), [senha, setSenha] = useState(preview?.senha ?? ""), [codigo, setCodigo] = useState(""), [needCode, setNeedCode] = useState(!!preview?.needCode), [err, setErr] = useState<Errs>(preview?.err ?? {}), [general, setGeneral] = useState(preview?.general ?? ""), [busy, setBusy] = useState(false);
  const submit = async (e: FormEvent) => {
    e.preventDefault(); const v = validateLogin({ email, senha }); setErr(v); setGeneral(""); if (hasErrors(v)) return;
    setBusy(true);
    try { await login(email, senha, needCode ? codigo : undefined); notify("Bem-vinda de volta!"); router.replace(next); }
    catch (x) { if (x instanceof ApiError && x.code === "MFA_REQUIRED") { setNeedCode(true); setGeneral("Informe o código do seu aplicativo autenticador."); } else if (x instanceof ApiError && x.code === "MFA_INVALID") { setErr({ codigo: x.message }); } else setGeneral(fromApi(x).general ?? "Não foi possível entrar."); }
    finally { setBusy(false); }
  };
  return (
    <Shell title="Entrar na SheikBras" sub="Acompanhe pedidos, salve favoritos e compre mais rápido.">
      <form className="sec2" onSubmit={submit} noValidate>
        {general ? <div className="notice" role="alert" style={needCode ? undefined : { background: "#FDECEF", borderColor: "#F3C5CC", color: "var(--err, #C9243B)" }}>{general}</div> : null}
        <Field id="l-email" label="E-mail" value={email} onChange={setEmail} error={err.email} type="email" autoComplete="email" inputMode="email" />
        <Field id="l-senha" label="Senha" value={senha} onChange={setSenha} error={err.senha} type="password" autoComplete="current-password" />
        {needCode ? <Field id="l-cod" label="Código de verificação (6 dígitos)" value={codigo} onChange={setCodigo} error={err.codigo} inputMode="numeric" autoComplete="one-time-code" hint="Ou use um código de recuperação." /> : null}
        <button className="btn b-p lg" type="submit" disabled={busy}>{busy ? "Aguarde..." : "Entrar"}</button>
        <Link href="/recuperar-senha" style={{ textAlign: "right", fontWeight: 600, color: "var(--primary)", fontSize: 13 }}>Esqueci minha senha</Link>
        <DemoNote />
      </form>
      <p style={{ textAlign: "center" }} className="pi">Ainda não tem conta? <Link href={`/cadastro${next !== "/" ? `?next=${encodeURIComponent(next)}` : ""}`} style={{ fontWeight: 700, color: "var(--primary)" }}>Criar conta</Link></p>
    </Shell>
  );
}
const STRENGTH = ["#C9243B", "#C9243B", "#F59E0B", "#0E7D3E", "#0E7D3E"];
export function RegisterForm({ preview }: { preview?: { v?: Partial<{ nome: string; email: string; senha: string; confirmar: string; aceite: boolean }>; err?: Errs } } = {}) {
  const { register } = useAuth(); const router = useRouter(); const next = safeNext(useSearchParams()?.get("next")); const { notify } = useStore();
  const [v, setV] = useState({ nome: "", email: "", senha: "", confirmar: "", aceite: false, ...preview?.v }), [err, setErr] = useState<Errs>(preview?.err ?? {}), [general, setGeneral] = useState(""), [busy, setBusy] = useState(false);
  const st = passwordStrength(v.senha); const set = <K extends keyof typeof v>(k: K) => (x: (typeof v)[K]) => setV((o) => ({ ...o, [k]: x }));
  const submit = async (e: FormEvent) => {
    e.preventDefault(); const er = validateRegister(v); setErr(er); setGeneral(""); if (hasErrors(er)) return; setBusy(true);
    try { await register({ nome: v.nome, email: v.email, senha: v.senha, aceite: v.aceite }); notify("Conta criada. Bem-vinda à SheikBras!"); router.replace(next); }
    catch (x) { const r = fromApi(x); setErr(r.fields); setGeneral(r.general ?? ""); } finally { setBusy(false); }
  };
  return (
    <Shell title="Criar sua conta" sub="Leva menos de um minuto.">
      <form className="sec2" onSubmit={submit} noValidate>
        {general ? <div className="notice" role="alert">{general}</div> : null}
        <Field id="r-nome" label="Nome completo" value={v.nome} onChange={set("nome")} error={err.nome} autoComplete="name" />
        <Field id="r-email" label="E-mail" value={v.email} onChange={set("email")} error={err.email} type="email" autoComplete="email" inputMode="email" />
        <div><Field id="r-senha" label="Senha" value={v.senha} onChange={set("senha")} error={err.senha} type="password" autoComplete="new-password" hint="Mínimo de 8 caracteres." />
          {v.senha ? <div aria-live="polite" style={{ marginTop: 8 }}><div style={{ display: "flex", gap: 4 }}>{[0, 1, 2, 3].map((i) => <span key={i} style={{ flex: 1, height: 4, borderRadius: 2, background: i < st.score ? STRENGTH[st.score] : "var(--line)" }} />)}</div><small className="pi">Senha {st.label.toLowerCase()}</small></div> : null}</div>
        <Field id="r-conf" label="Confirmar senha" value={v.confirmar} onChange={set("confirmar")} error={err.confirmar} type="password" autoComplete="new-password" />
        <div className="fd"><label style={{ display: "flex", gap: 10, alignItems: "flex-start", fontWeight: 400 }}><input type="checkbox" checked={v.aceite} onChange={(e) => set("aceite")(e.target.checked)} style={{ marginTop: 3, accentColor: "var(--primary)", width: 18, height: 18 }} aria-invalid={err.aceite ? true : undefined} /><span>Li e aceito os <b style={{ color: "var(--primary)" }}>Termos de Uso</b> e a <b style={{ color: "var(--primary)" }}>Política de Privacidade</b>, conforme a LGPD.</span></label>{err.aceite ? <span className="er" role="alert">{err.aceite}</span> : null}</div>
        <button className="btn b-p lg" type="submit" disabled={busy}>{busy ? "Aguarde..." : "Criar conta"}</button><DemoNote />
      </form>
      <p style={{ textAlign: "center" }} className="pi">Já tem conta? <Link href={`/entrar${next !== "/" ? `?next=${encodeURIComponent(next)}` : ""}`} style={{ fontWeight: 700, color: "var(--primary)" }}>Entrar</Link></p>
    </Shell>
  );
}
export function ForgotForm() {
  const { forgotPassword } = useAuth(); const [email, setEmail] = useState(""), [err, setErr] = useState(""), [done, setDone] = useState(false), [busy, setBusy] = useState(false);
  const submit = async (e: FormEvent) => {
    e.preventDefault(); const v = validateLogin({ email, senha: "x" }); if (v.email) { setErr(v.email); return; } setErr(""); setBusy(true);
    try { await forgotPassword(email); setDone(true); } catch (x) { if (x instanceof ApiError && x.code === "RATE_LIMITED") setErr(x.message); else setDone(true); } finally { setBusy(false); }
  };
  return (
    <Shell title="Recuperar senha" sub="Informe seu e-mail e enviaremos as instruções.">
      {done ? <div className="sec2" role="status"><b>Pedido recebido</b><p className="pi" style={{ margin: 0 }}>Se o e-mail estiver cadastrado, você receberá as instruções em instantes. O link vale por 1 hora.</p><Link className="btn b-o lg" href="/entrar">Voltar para entrar</Link></div> : (
        <form className="sec2" onSubmit={submit} noValidate><Field id="f-email" label="E-mail" value={email} onChange={setEmail} error={err} type="email" autoComplete="email" inputMode="email" /><button className="btn b-p lg" type="submit" disabled={busy}>{busy ? "Aguarde..." : "Enviar instruções"}</button><DemoNote /></form>)}
    </Shell>
  );
}
export function ResetForm() {
  const token = useSearchParams()?.get("token") ?? ""; const router = useRouter(); const { notify } = useStore();
  const [senha, setSenha] = useState(""), [conf, setConf] = useState(""), [err, setErr] = useState<Errs>({}), [general, setGeneral] = useState(""), [busy, setBusy] = useState(false); const st = passwordStrength(senha);
  const submit = async (e: FormEvent) => {
    e.preventDefault(); const er: Errs = {}; if (!st.ok) er.senha = "Use pelo menos 8 caracteres, com letras maiúsculas e minúsculas ou números."; if (conf !== senha) er.conf = "As senhas não são iguais."; setErr(er); setGeneral(""); if (hasErrors(er)) return;
    setBusy(true); try { await api.auth.resetPassword(token, senha); notify("Senha alterada. Entre com a nova senha."); router.replace("/entrar"); } catch (x) { const r = fromApi(x); setGeneral(r.fields.token ?? r.general ?? "Não foi possível redefinir."); setErr({ senha: r.fields.senha }); } finally { setBusy(false); }
  };
  if (!token) return <Shell title="Link inválido"><div className="sec2"><p className="pi" style={{ margin: 0 }}>O link de redefinição está incompleto. Peça um novo.</p><Link className="btn b-p lg" href="/recuperar-senha">Pedir novo link</Link></div></Shell>;
  return (
    <Shell title="Nova senha" sub="Escolha uma senha forte. Você sairá de todos os aparelhos.">
      <form className="sec2" onSubmit={submit} noValidate>{general ? <div className="notice" role="alert">{general}</div> : null}
        <Field id="n-senha" label="Nova senha" value={senha} onChange={setSenha} error={err.senha} type="password" autoComplete="new-password" hint="Mínimo de 8 caracteres." /><Field id="n-conf" label="Confirmar nova senha" value={conf} onChange={setConf} error={err.conf} type="password" autoComplete="new-password" />
        <button className="btn b-p lg" type="submit" disabled={busy}>{busy ? "Aguarde..." : "Salvar nova senha"}</button></form>
    </Shell>
  );
}
export function VerifyEmail() {
  const token = useSearchParams()?.get("token") ?? ""; const [state, setState] = useState<"wait" | "ok" | "bad" | "off">(token ? "wait" : "bad"); const ran = useRef(false);
  useEffect(() => { if (!token || ran.current) return; ran.current = true; if (!apiEnabled) { setState("off"); return; } api.auth.verifyEmail(token).then(() => setState("ok")).catch(() => setState("bad")); }, [token]);
  const msg = { wait: "Confirmando seu e-mail…", ok: "E-mail confirmado! Agora você pode usar todos os recursos da conta.", bad: "Este link é inválido ou expirou. Peça um novo na sua conta.", off: "Disponível quando a API estiver conectada." }[state];
  return <Shell title="Confirmação de e-mail"><div className="sec2" role="status" aria-live="polite"><p style={{ margin: 0 }}>{msg}</p><Link className="btn b-p lg" href={state === "ok" ? "/" : "/entrar"}>{state === "ok" ? "Ir para a loja" : "Entrar"}</Link></div></Shell>;
}
