/* eslint-disable @next/next/no-img-element */
"use client";

import { useEffect, useState } from "react";
import { Loader2, ShieldCheck } from "lucide-react";
import { Brand } from "@/components/ark/brand";
import { loginErrorMessage } from "@/lib/login-messages";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import {
  sendCodeAction,
  verifyCodeAction,
  pollRelayResultAction,
  getOAuthAuthorizeUrlAction,
} from "./actions";

const PROVIDERS = (process.env.NEXT_PUBLIC_AUTH_PROVIDERS ?? "")
  .split(",")
  .map((s) => s.trim())
  .filter(Boolean);

const HAS_EMAIL_OTP = PROVIDERS.includes("email-otp");
const HAS_GOOGLE = PROVIDERS.includes("google");
const HAS_TEABLE = PROVIDERS.includes("teable");

function getIsEmbedded(): boolean {
  try { return window.self !== window.top; } catch { return true; }
}

const ERROR_MESSAGES: Record<string, string> = {
  access_denied: "Este e-mail não tem permissão para acessar o painel. Use uma conta autorizada.",
  google_failed: "Não foi possível entrar com o Google. Tente novamente.",
  teable_failed: "Não foi possível entrar com a Teable. Tente novamente.",
};

export default function LoginPage() {
  const [email, setEmail] = useState("");
  const [code, setCode] = useState("");
  const [step, setStep] = useState<"email" | "code">("email");
  const [error, setError] = useState("");
  const [emailLoading, setEmailLoading] = useState(false);
  const [oauthLoadingProvider, setOauthLoadingProvider] = useState<"teable" | "google" | null>(null);
  const [countdown, setCountdown] = useState(0);
  const [embedded, setEmbedded] = useState(false);

  useEffect(() => {
    setEmbedded(getIsEmbedded());
    const params = new URLSearchParams(window.location.search);
    const errorCode = params.get("error");
    if (errorCode) {
      setError(params.get("message") || ERROR_MESSAGES[errorCode] || "Não foi possível entrar. Tente novamente.");
    }
  }, []);

  // Poll relay result with nonce after popup opens. Enterprise SSO (IdP login
  // + MFA + first-time consent) routinely takes minutes, so the budget must be
  // generous. popup.closed is deliberately NOT used to stop early: a
  // COOP-induced browsing-context-group switch (e.g. an IdP that sends
  // COOP: same-origin) flips it to true while the user is still signing in.
  // The user can bail out any time via the cancel link rendered while waiting.
  const [relaySession, setRelaySession] = useState<{ nonce: string; popup: Window } | null>(null);
  useEffect(() => {
    if (!relaySession) return;
    const { nonce } = relaySession;
    let cancelled = false;
    const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
    const stop = (message?: string) => {
      if (cancelled) return;
      if (message) setError(message);
      setOauthLoadingProvider(null);
      setRelaySession(null);
    };
    const check = async (): Promise<boolean> => {
      const result = await pollRelayResultAction(nonce);
      if (cancelled) return true;
      if (result.success) {
        const from = new URLSearchParams(window.location.search).get("from") ?? undefined;
        const target = from && from.startsWith("/") && !from.startsWith("//") ? from : "/";
        window.location.href = target;
        return true;
      }
      if (result.error) {
        stop(result.error);
        return true;
      }
      return false;
    };
    const poll = async () => {
      // 600s matches the server-side OAuth state TTL and relay TTL: as long as
      // the callback can still accept the sign-in, this page keeps listening
      // for its result. A shorter budget would discard sign-ins that complete
      // late but within the state lifetime.
      for (let i = 0; i < 600 && !cancelled; i++) {
        await sleep(1000);
        if (cancelled) return;
        if (await check()) return;
      }
      stop("A entrada não foi concluída. Tente novamente.");
    };
    poll();
    return () => { cancelled = true; };
  }, [relaySession]);

  function cancelOAuthSignIn() {
    try { relaySession?.popup.close(); } catch { /* severed handle */ }
    setOauthLoadingProvider(null);
    setRelaySession(null);
  }

  function startCountdown(seconds: number) {
    setCountdown(seconds);
    const timer = setInterval(() => {
      setCountdown((prev) => {
        if (prev <= 1) {
          clearInterval(timer);
          return 0;
        }
        return prev - 1;
      });
    }, 1000);
  }

  async function handleSendCode(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    setError("");
    setEmailLoading(true);
    const result = await sendCodeAction(email);
    setEmailLoading(false);
    if (result.error) {
      setError(result.error);
    } else {
      setStep("code");
      startCountdown(60);
    }
  }

  async function handleVerifyCode(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    setError("");
    setEmailLoading(true);
    const from = new URLSearchParams(window.location.search).get("from") ?? undefined;
    const result = await verifyCodeAction(email, code, from, embedded);
    if (result?.error) {
      setError(result.error);
      setEmailLoading(false);
    }
  }

  async function handleResend() {
    setError("");
    setEmailLoading(true);
    const result = await sendCodeAction(email);
    setEmailLoading(false);
    if (result.error) {
      setError(result.error);
    } else {
      startCountdown(60);
    }
  }

  function handleOAuthSignIn(provider: "teable" | "google") {
    setError("");
    setOauthLoadingProvider(provider);
    const from = new URLSearchParams(window.location.search).get("from") ?? undefined;
    // Use the native popup/relay flow: its callback remains on the published Teable app.
    if (true) {
      // Open a blank popup synchronously in the click gesture (popup blockers
      // only allow that), then fetch a FRESH authorize URL and navigate it.
      // The server-side OAuth state starts its TTL now — at the click — so the
      // whole 600s state/relay/polling window is measured from one instant.
      // (A URL pre-fetched at page load would carry a state that could already
      // be minutes old, or expired, by the time the user clicks.)
      const nonce = crypto.randomUUID().replace(/-/g, "").slice(0, 16);
      const popup = window.open("", provider + "-auth", "width=500,height=600,popup=yes");
      if (!popup) {
        setError("A janela de login foi bloqueada. Permita pop-ups para este site e tente novamente.");
        setOauthLoadingProvider(null);
        return;
      }
      getOAuthAuthorizeUrlAction(provider, from, true, nonce)
        .then((result) => {
          if (popup.closed) {
            setOauthLoadingProvider(null);
            return;
          }
          if (result.url) {
            popup.location.href = result.url;
            setRelaySession({ nonce, popup });
          } else {
            try { popup.close(); } catch { /* already closed */ }
            setError(result.error || "Não foi possível iniciar o login. Tente novamente.");
            setOauthLoadingProvider(null);
          }
        })
        .catch(() => {
          try { popup.close(); } catch { /* already closed */ }
          setError("Não foi possível iniciar o login. Tente novamente.");
          setOauthLoadingProvider(null);
        });
    } else {
      getOAuthAuthorizeUrlAction(provider, from).then((result) => {
        if (result.error) { setError(result.error); setOauthLoadingProvider(null); }
        else if (result.url) { window.location.href = result.url; }
      });
    }
  }

  return (
    <main className="flex min-h-dvh flex-col bg-background text-foreground">
      <header className="flex items-center justify-between border-b border-white/[0.06] px-6 py-6 sm:px-12">
        <Brand badge={false} />
        <span className="rounded-full border border-white/10 px-3 py-1.5 text-[10px] font-medium tracking-[0.18em] text-zinc-500">PAINEL VSL</span>
      </header>
      <div className="flex flex-1 items-center justify-center px-5 py-12 sm:py-16">
      <div className="w-full max-w-md">
      <p className="mb-6 text-center text-[10px] font-medium uppercase tracking-[0.22em] text-lime-300/80">Seu conteúdo. Em play.</p>
      <Card className="w-full rounded-2xl border-white/10 bg-card py-7 shadow-2xl shadow-black/10">
        <CardHeader className="px-7 text-center">
          <CardTitle className="text-2xl font-semibold tracking-tight"><h1>{step === "email" ? "Entre no ArkVideo" : "Confira seu e-mail"}</h1></CardTitle>
          <CardDescription className="mt-2 text-sm leading-6">
            {step === "email"
              ? "Acesse seu painel para gerenciar vídeos e acompanhar seus resultados."
              : `Digite o código de verificação enviado para ${email}`}
          </CardDescription>
        </CardHeader>
        <CardContent className="px-7">
          {error && (
            <div role="alert" className="mb-5 rounded-lg border border-red-400/20 bg-red-400/5 p-3 text-sm leading-relaxed text-red-300">
              {loginErrorMessage(error)}
            </div>
          )}

          {step === "email" ? (
            <div className="space-y-4">
              {HAS_EMAIL_OTP && (
                <form onSubmit={handleSendCode} className="space-y-4">
                  <div className="space-y-2">
                    <Label htmlFor="email">E-mail autorizado</Label>
                    <Input
                      id="email"
                      type="email"
                      placeholder="Seu e-mail cadastrado"
                      required
                      autoComplete="email"
                      value={email}
                      onChange={(e) => setEmail(e.target.value)}
                    />
                  </div>
                  <Button type="submit" className="w-full" disabled={emailLoading || Boolean(oauthLoadingProvider)}>
                    {emailLoading ? "Enviando…" : "Receber código por e-mail"}
                  </Button>
                </form>
              )}

              {HAS_EMAIL_OTP && (HAS_TEABLE || HAS_GOOGLE) && (
                <div className="my-4 flex items-center gap-3">
                  <div className="h-px flex-1 bg-border" />
                  <span className="text-xs text-muted-foreground">ou entre com sua conta</span>
                  <div className="h-px flex-1 bg-border" />
                </div>
              )}

              {(HAS_TEABLE || HAS_GOOGLE) && (
                <div className="space-y-2">
                  {HAS_TEABLE && (
                    <Button
                      type="button"
                      variant="outline"
                      className="w-full gap-2"
                      disabled={Boolean(oauthLoadingProvider) || emailLoading}
                      onClick={() => handleOAuthSignIn("teable")}
                    >
                      {oauthLoadingProvider === "teable" ? (
                        <Loader2 className="size-4 animate-spin" aria-hidden="true" />
                      ) : (
                        <img src="/icons/teable.svg" alt="" className="size-4" aria-hidden="true" />
                      )}
                      Entrar com a Teable
                    </Button>
                  )}

                  {HAS_GOOGLE && (
                    <Button
                      type="button"
                      variant="outline"
                      className="w-full gap-2"
                      disabled={Boolean(oauthLoadingProvider) || emailLoading}
                      onClick={() => handleOAuthSignIn("google")}
                    >
                      {oauthLoadingProvider === "google" ? (
                        <Loader2 className="size-4 animate-spin" aria-hidden="true" />
                      ) : (
                        <img src="/icons/google.svg" alt="" className="size-4" aria-hidden="true" />
                      )}
                      Continuar com o Google
                    </Button>
                  )}

                  {relaySession && (
                    <div className="text-center">
                      <button
                        type="button"
                        className="text-sm text-muted-foreground hover:text-primary"
                        onClick={cancelOAuthSignIn}
                      >
                        Aguardando a entrada na janela… Cancelar
                      </button>
                    </div>
                  )}
                </div>
              )}
            </div>
          ) : (
            <form onSubmit={handleVerifyCode} className="space-y-4">
              <div className="space-y-2">
                <Label htmlFor="code">Código de verificação</Label>
                <Input
                  id="code"
                  type="text"
                  inputMode="numeric"
                  pattern="[0-9]*"
                  maxLength={6}
                  placeholder="000000"
                  required
                  autoComplete="one-time-code"
                  value={code}
                  onChange={(e) => setCode(e.target.value.replace(/\D/g, ""))}
                />
              </div>
              <Button type="submit" className="w-full" disabled={emailLoading || code.length !== 6}>
                {emailLoading ? "Verificando…" : "Entrar no painel"}
              </Button>
              <div className="text-center">
                <button
                  type="button"
                  className="text-sm text-muted-foreground hover:text-primary disabled:opacity-50"
                  disabled={countdown > 0 || emailLoading}
                  onClick={handleResend}
                >
                  {countdown > 0 ? `Reenviar código em ${countdown}s` : "Reenviar código"}
                </button>
              </div>
              <div className="text-center">
                <button
                  type="button"
                  className="text-sm text-muted-foreground hover:text-primary"
                  onClick={() => {
                    setStep("email");
                    setCode("");
                    setError("");
                  }}
                >
                  Usar outro e-mail
                </button>
              </div>
            </form>
          )}
        </CardContent>
      </Card>
      <p className="mt-6 flex items-start justify-center gap-2 text-center text-xs leading-5 text-muted-foreground"><ShieldCheck className="mt-0.5 size-4 shrink-0 text-lime-300/70" aria-hidden="true" /><span>Acesso exclusivo a e-mails autorizados.<br />Use a mesma conta cadastrada no painel.</span></p>
      </div>
      </div>
      <footer className="mx-6 flex flex-wrap items-center justify-between gap-3 border-t border-white/[0.06] py-6 text-[10px] tracking-wide text-zinc-600 sm:mx-12"><span>ArkVideo VSL</span><span>Seus vídeos. Sua estrutura.</span></footer>
    </main>
  );
}
