import { useCallback, useEffect, useState } from "react";
import { subscribeAuthenticationRequired } from "../../app/api.js";
import { StartupScreen } from "../../app/StartupScreen.jsx";
import { platformRuntime } from "../../platform/runtime.js";
import { useI18n } from "../../shared/I18nProvider.jsx";
import { scanDevicePairingQr } from "../connection/qr-scanner.js";
import { currentApiOrigin, loadAuthenticationSession, loadAuthenticationStatus, pairDevice } from "./auth-api.js";
import { scheduleAuthenticationStartup } from "./authentication-startup.js";
import { useReviewDemo } from "../review-demo/ReviewDemo.jsx";

export function AuthenticationGate({ children }) {
  const { language, setLanguage, t } = useI18n();
  const { startReviewDemo } = useReviewDemo();
  const [state, setState] = useState("checking");
  const [authentication, setAuthentication] = useState(null);
  const [code, setCode] = useState("");
  const [pending, setPending] = useState(false);
  const [error, setError] = useState("");
  const [showStartup, setShowStartup] = useState(false);

  const showPairing = useCallback(async () => {
    try {
      const status = await loadAuthenticationStatus();
      if (status.required === false) {
        await loadAuthenticationSession();
        setAuthentication(status);
        setState("ready");
        setError("");
        return;
      }
      setAuthentication(status);
      setState("pairing");
      setError("");
    } catch {
      setState("unreachable");
      setError("pc_unreachable");
    }
  }, []);

  useEffect(() => {
    let active = true;
    let initialCheckComplete = false;
    const unsubscribe = subscribeAuthenticationRequired(() => {
      if (active && initialCheckComplete) void showPairing();
    });
    loadAuthenticationSession()
      .then(() => { if (active) setState("ready"); })
      .catch((authError) => {
        if (!active) return;
        if (authError.message === "authentication_required") void showPairing();
        else {
          setState("unreachable");
          setError(authError.message);
        }
      })
      .finally(() => { initialCheckComplete = true; });
    return () => { active = false; unsubscribe(); };
  }, [showPairing]);

  useEffect(() => {
    if (state !== "checking") return undefined;
    return scheduleAuthenticationStartup(() => setShowStartup(true));
  }, [state]);

  async function complete(input) {
    setPending(true);
    setError("");
    try {
      await pairDevice({ ...input, label: platformRuntime.isNative ? "Mobile app" : "Web browser" });
      await loadAuthenticationSession();
      setCode("");
      setState("ready");
    } catch (pairingError) {
      await showPairing();
      setError(pairingError.message);
    } finally {
      setPending(false);
    }
  }

  function submitCode(event) {
    event.preventDefault();
    if (!authentication?.pairingAttemptId || !code.trim()) return;
    void complete({ attemptId: authentication.pairingAttemptId, code });
  }

  async function scanQr() {
    setPending(true);
    setError("");
    try {
      const pairing = await scanDevicePairingQr(undefined, {
        instructions: t("pairing.scanInstructions"),
        cancel: t("settings.back")
      });
      if (pairing.origin !== currentApiOrigin()) throw new Error("invalid_pairing_payload");
      await complete({ attemptId: pairing.attemptId, qrSecret: pairing.secret });
    } catch (scanError) {
      setError(scanError.message);
      setPending(false);
    }
  }

  async function continueDevelopment() {
    setShowStartup(false);
    setState("checking");
    setError("");
    try {
      await loadAuthenticationStatus();
      setState("ready");
    } catch {
      setState("unreachable");
      setError("pc_unreachable");
    }
  }

  if (state === "ready") return children;
  if (state === "checking") return showStartup ? <StartupScreen /> : null;

  const pairingAvailable = Boolean(authentication?.pairingAvailable && authentication?.pairingAttemptId);
  return <main className="connection-page">
    <div className="connection-language" aria-label={t("settings.language")}>
      <button type="button" className={language === "ko" ? "active" : ""} aria-pressed={language === "ko"} onClick={() => setLanguage("ko")}>{t("settings.korean")}</button>
      <button type="button" className={language === "en" ? "active" : ""} aria-pressed={language === "en"} onClick={() => setLanguage("en")}>English</button>
    </div>
    <form className="connection-card" onSubmit={submitCode}>
      <p className="connection-kicker">Code Remote Manager</p>
      <h1>{t(state === "checking" ? "pairing.checking" : "pairing.title")}</h1>
      {state === "checking" && <p>{t("pairing.checkingDescription")}</p>}
      {state !== "checking" && <>
        <p>{t(pairingAvailable ? "pairing.description" : "pairing.startOnPc")}</p>
        {platformRuntime.isNative && <button className="connection-scan" type="button" disabled={pending} onClick={scanQr}>{t("pairing.scanQr")}</button>}
        {pairingAvailable && <>
          {platformRuntime.isNative && <p className="connection-divider"><span>{t("pairing.orEnterCode")}</span></p>}
          <label htmlFor="pairing-code">{t("pairing.code")}</label>
          <input id="pairing-code" inputMode="text" autoComplete="off" autoCapitalize="characters" spellCheck="false" maxLength={14} value={code} onChange={(event) => setCode(event.target.value)} disabled={pending} />
          <button type="submit" disabled={pending || !code.trim()}>{pending ? t("pairing.connecting") : t("pairing.connect")}</button>
        </>}
        {!pairingAvailable && <button type="button" disabled={pending} onClick={showPairing}>{t("pairing.refresh")}</button>}
      </>}
      {error && state !== "checking" && <p className="connection-error" role="alert">{t(error === "pc_unreachable" ? "pairing.unreachable" : "pairing.failed")}</p>}
      <p className="connection-note">{t("pairing.note")}</p>
      <button className="connection-review-demo" type="button" disabled={state === "checking"} onClick={startReviewDemo}>{t("reviewDemo.start")}</button>
      {import.meta.env.DEV && <button className="connection-dev-bypass" type="button" disabled={state === "checking"} onClick={continueDevelopment}>{language === "ko" ? "개발자 모드로 계속" : "Continue in developer mode"}</button>}
    </form>
  </main>;
}
