/* blueyetutor — /login (+ /verify, /reset, /forgot anonymous routes)
 *
 * Modes (driven by route + local state):
 *   route="login"   → tab "login" or "signup"   (auth form)
 *   route="verify"  → consume ?token=… ; show verifying / success / failure
 *   route="reset"   → consume ?token=… ; new-password form
 *   route="forgot"  → email input → send reset link
 *
 *  Sign-up flow (when SMTP is configured):
 *     submit → server returns verification_required=true (no cookie set)
 *     UI switches to a "메일 확인하세요" screen with a resend button.
 *     User clicks link in their inbox → #/verify?token=… → auto-login.
 *
 * Backend (api/auth.py):
 *   POST /api/auth/login                  { email, password }
 *   POST /api/auth/signup                 { email, password, role }
 *   POST /api/auth/resend-verification    { email }
 *   GET  /api/auth/verify?token=…
 *   POST /api/auth/forgot-password        { email }
 *   POST /api/auth/reset-password         { token, new_password }
 */
const { useState: loginUseState, useEffect: loginUseEffect } = React;

function LoginPage({ route }) {
  // tab 은 가입/로그인 toggle. mode 는 화면 흐름.
  const initialTab = route === "signup" ? "signup" : "login";
  const [tab, setTab] = loginUseState(initialTab);
  const [mode, setMode] = loginUseState(
    route === "verify" ? "verifying"
    : route === "reset" ? "reset"
    : route === "forgot" ? "forgot"
    : "auth"
  );

  return (
    <div className="login-wrap">
      <section className="login-hero">
        <HeroParticles />
        <div className="login-hero-brand">
          <img src="src/components/logo-mark.png?v=12" className="dandelion-mark" alt="Blueye" />
          <div className="wordmark">Blueyetutor</div>
        </div>
        <div className="login-hero-body">
          <div className="greeting">선생님,</div>
          <h1>가르치는 일에만 집중하세요</h1>
          <p className="hero-sub">
            자료 정리, 문제집 제작, 오답노트 작성, 학생 관리 — 저희가 다 해드립니다.
          </p>
          <p className="hero-sub muted">
            AI 및 자체 엔진 기반 시스템으로 선생님의 시간을 아껴드립니다.
          </p>
        </div>
      </section>

      <section className="login-form">
        <div className="login-card">
          {mode === "verifying" && <VerifyConsumer />}
          {mode === "reset"     && <ResetForm onDone={() => setMode("auth")} />}
          {mode === "forgot"    && <ForgotForm onBack={() => setMode("auth")} />}
          {mode === "auth"      && <AuthForm tab={tab} setTab={setTab}
                                              onForgot={() => setMode("forgot")}
                                              onPending={() => setMode("pending-verify")} />}
          {mode === "pending-verify" && <PendingVerify onBack={() => setMode("auth")} />}
        </div>
      </section>
    </div>
  );
}

// ---- core auth (login + signup tab) ------------------------------------
function AuthForm({ tab, setTab, onForgot, onPending }) {
  const [role, setRole] = loginUseState("teacher");
  const [email, setEmail] = loginUseState("");
  const [pw, setPw] = loginUseState("");
  const [pw2, setPw2] = loginUseState("");
  const [busy, setBusy] = loginUseState(false);
  const [err, setErr] = loginUseState("");
  const [notVerified, setNotVerified] = loginUseState(null);   // email if 403 not_verified

  const validEmail = /\S+@\S+\.\S+/.test(email);

  const submit = async e => {
    e.preventDefault(); setErr(""); setNotVerified(null);
    if (!validEmail) { setErr("이메일 형식이 올바르지 않습니다."); return; }
    if (tab === "signup") {
      if (pw.length < 8) { setErr("비밀번호는 최소 8자 이상이어야 합니다."); return; }
      if (pw !== pw2)   { setErr("비밀번호가 일치하지 않습니다."); return; }
    } else {
      if (pw.length < 1) { setErr("비밀번호를 입력하세요."); return; }
    }
    setBusy(true);
    const cleanEmail = email.trim().toLowerCase();
    const res = tab === "signup"
      ? await window.storeActions.signup(cleanEmail, pw, role)
      : await window.storeActions.login(cleanEmail, pw);
    setBusy(false);
    if (!res || !res.ok) {
      if (res && res.error === "not_verified") {
        setNotVerified(cleanEmail);
        return;
      }
      setErr((res && res.message) || "로그인에 실패했습니다. 다시 시도해 주세요.");
      return;
    }
    // signup flow: 메일 인증 필요면 pending 화면, 아니면 store.user 셋팅 후 자동 redirect.
    if (tab === "signup" && res.verification_required) {
      window.__pendingEmail = cleanEmail;
      onPending();
    }
  };

  const resend = async () => {
    if (!notVerified) return;
    await window.storeActions.resendVerification(notVerified);
    setErr("인증 메일을 다시 보냈어요. 받은편지함을 확인하세요.");
  };

  return (
    <>
      <h2>{tab === "signup" ? "가입하기" : "다시 만나서 반가워요"}</h2>
      <p className="sub">학원 계정으로 계속 진행합니다.</p>

      <Tabs
        tabs={[{ value: "login", label: "로그인" }, { value: "signup", label: "가입" }]}
        value={tab} onChange={v => { setTab(v); setErr(""); setNotVerified(null); }}
      />

      <form onSubmit={submit} className="col" style={{ gap: 14 }}>
        {tab === "signup" && (
          <Field label="계정 유형" help={role === "student" ? "선생님이 초대한 이메일만 학생 가입이 가능합니다." : undefined}>
            <Segmented
              options={[{ value: "teacher", label: "선생님" }, { value: "student", label: "학생" }]}
              value={role} onChange={setRole}
            />
          </Field>
        )}
        <Field label="이메일">
          <input className="input" type="email" autoComplete="email"
                 value={email} onChange={e => setEmail(e.target.value)} placeholder="you@academy.com" />
        </Field>
        <Field label="비밀번호" help={tab === "signup" ? "최소 8자" : undefined}>
          <input className="input" type="password"
                 autoComplete={tab === "signup" ? "new-password" : "current-password"}
                 value={pw} onChange={e => setPw(e.target.value)} placeholder="••••••••" />
        </Field>
        {tab === "signup" && (
          <Field label="비밀번호 확인">
            <input className="input" type="password" autoComplete="new-password"
                   value={pw2} onChange={e => setPw2(e.target.value)} placeholder="••••••••" />
          </Field>
        )}

        {err && <Banner kind="error">{err}</Banner>}
        {notVerified && (
          <Banner kind="warn" title="이메일 인증이 필요해요">
            받은편지함의 인증 링크를 클릭한 뒤 다시 로그인하세요.&nbsp;
            <a href="#" onClick={e => { e.preventDefault(); resend(); }}>
              인증 메일 재발송
            </a>
          </Banner>
        )}

        <Button type="submit" variant="primary" block size="lg" disabled={busy}>
          {busy ? "확인 중…" : tab === "signup" ? "가입" : "로그인"}
        </Button>
        {tab === "login" && (
          <div style={{ textAlign: "center", marginTop: 4 }}>
            <a href="#" className="muted small" onClick={e => { e.preventDefault(); onForgot(); }}>
              비밀번호를 잊으셨나요?
            </a>
          </div>
        )}
      </form>

      <div style={{ margin: "20px 0", display: "flex", alignItems: "center", gap: 12, color: "var(--text-3)" }}>
        <div style={{ flex: 1, height: 1, background: "var(--border)" }} />
        <span className="small">또는</span>
        <div style={{ flex: 1, height: 1, background: "var(--border)" }} />
      </div>

      <Button block disabled title="Google OIDC — 백엔드 준비 후 활성화">
        Google 계정으로 로그인
        <Badge style={{ marginLeft: 6 }}>준비 중</Badge>
      </Button>

      <div className="muted small" style={{ marginTop: 20, textAlign: "center" }}>
        가입은 운영자 allowlist 등록 후 가능합니다.
      </div>
    </>
  );
}

// ---- mode: "pending-verify" — sent the mail, waiting on the user's click
function PendingVerify({ onBack }) {
  const email = window.__pendingEmail || "";
  const [msg, setMsg] = loginUseState(null);
  const [busy, setBusy] = loginUseState(false);
  const resend = async () => {
    if (!email) return;
    setBusy(true);
    const r = await window.storeActions.resendVerification(email);
    setBusy(false);
    setMsg(r && r.ok ? { ok: true, text: "다시 보냈습니다. 받은편지함 / 스팸함 확인하세요." }
                     : { ok: false, text: (r && r.message) || "재발송 실패" });
  };
  return (
    <>
      <h2>메일 확인하세요</h2>
      <p className="sub">
        <strong className="mono">{email}</strong> 으로 인증 링크를 보냈습니다.
        링크를 클릭하면 가입이 완료됩니다.
      </p>
      <Banner kind="info">
        링크가 안 오면 스팸함 / 프로모션 폴더를 확인하세요. 24시간 안에 클릭해야 합니다.
      </Banner>
      <div className="col" style={{ gap: 10, marginTop: 16 }}>
        <Button block disabled={busy} onClick={resend}>{busy ? "보내는 중…" : "인증 메일 다시 보내기"}</Button>
        <Button variant="ghost" block onClick={onBack}>로그인 화면으로 돌아가기</Button>
      </div>
      {msg && <Banner kind={msg.ok ? "ok" : "error"} >{msg.text}</Banner>}
    </>
  );
}

// ---- mode: "verifying" — eat the ?token=… on page load and route into the app
function VerifyConsumer() {
  const [state, setState] = loginUseState("checking"); // checking | ok | fail
  const [msg, setMsg] = loginUseState("");
  loginUseEffect(() => {
    const tok = (typeof hashQueryParam === "function" && hashQueryParam("token")) || "";
    if (!tok) { setState("fail"); setMsg("인증 토큰이 없습니다."); return; }
    (async () => {
      const r = await window.storeActions.verifyEmailToken(tok);
      if (r && r.ok) {
        setState("ok");
        // 잠시 보여주고 home 으로
        setTimeout(() => { location.hash = "#/upload"; }, 1200);
      } else {
        setState("fail");
        setMsg((r && r.message) || "인증에 실패했습니다.");
      }
    })();
  }, []);
  return (
    <>
      <h2>이메일 인증</h2>
      {state === "checking" && <Banner kind="info">인증 확인 중…</Banner>}
      {state === "ok"       && <Banner kind="ok">인증 완료! 잠시 후 화면이 이동합니다.</Banner>}
      {state === "fail"     && <>
        <Banner kind="error">{msg}</Banner>
        <Button block onClick={() => { location.hash = "#/login"; }}>로그인 화면으로</Button>
      </>}
    </>
  );
}

// ---- mode: "forgot" — email input + send reset link
function ForgotForm({ onBack }) {
  const [email, setEmail] = loginUseState("");
  const [busy, setBusy] = loginUseState(false);
  const [msg, setMsg] = loginUseState(null);
  const validEmail = /\S+@\S+\.\S+/.test(email);
  const submit = async e => {
    e.preventDefault();
    if (!validEmail) { setMsg({ ok: false, text: "이메일 형식이 올바르지 않습니다." }); return; }
    setBusy(true); setMsg(null);
    const r = await window.storeActions.forgotPassword(email.trim().toLowerCase());
    setBusy(false);
    if (r && r.ok) {
      setMsg({ ok: true, text: r.smtp_configured
        ? "재설정 메일을 보냈습니다. 받은편지함 / 스팸함을 확인하세요. (1시간 유효)"
        : "메일 서버가 설정되지 않았습니다. 운영자에게 문의하세요." });
    } else {
      setMsg({ ok: false, text: (r && r.message) || "요청 실패" });
    }
  };
  return (
    <form onSubmit={submit} className="col" style={{ gap: 14 }}>
      <h2>비밀번호 재설정</h2>
      <p className="sub">가입한 이메일로 재설정 링크를 보내드려요.</p>
      <Field label="이메일">
        <input className="input" type="email" autoComplete="email" autoFocus
               value={email} onChange={e => setEmail(e.target.value)} placeholder="you@academy.com" />
      </Field>
      {msg && <Banner kind={msg.ok ? "ok" : "error"}>{msg.text}</Banner>}
      <Button type="submit" variant="primary" block size="lg" disabled={busy}>
        {busy ? "보내는 중…" : "재설정 메일 보내기"}
      </Button>
      <Button variant="ghost" block onClick={onBack} type="button">로그인 화면으로</Button>
    </form>
  );
}

// ---- mode: "reset" — got here via email link → set a new password
function ResetForm({ onDone }) {
  const [pw, setPw] = loginUseState("");
  const [pw2, setPw2] = loginUseState("");
  const [busy, setBusy] = loginUseState(false);
  const [msg, setMsg] = loginUseState(null);
  const tok = (typeof hashQueryParam === "function" && hashQueryParam("token")) || "";

  const submit = async e => {
    e.preventDefault();
    if (!tok) { setMsg({ ok: false, text: "재설정 토큰이 없습니다." }); return; }
    if (pw.length < 8) { setMsg({ ok: false, text: "비밀번호는 최소 8자 이상이어야 합니다." }); return; }
    if (pw !== pw2)   { setMsg({ ok: false, text: "비밀번호가 일치하지 않습니다." }); return; }
    setBusy(true); setMsg(null);
    const r = await window.storeActions.resetPassword(tok, pw);
    setBusy(false);
    if (r && r.ok) {
      setMsg({ ok: true, text: "비밀번호가 변경됐어요. 잠시 후 자동 로그인됩니다." });
      setTimeout(() => { location.hash = "#/upload"; }, 1200);
    } else {
      setMsg({ ok: false, text: (r && r.message) || "재설정 실패. 링크가 만료됐을 수 있습니다." });
    }
  };

  return (
    <form onSubmit={submit} className="col" style={{ gap: 14 }}>
      <h2>새 비밀번호 설정</h2>
      <p className="sub">아래에 새 비밀번호를 입력해 주세요. (8자 이상)</p>
      <Field label="새 비밀번호">
        <input className="input" type="password" autoComplete="new-password" autoFocus
               value={pw} onChange={e => setPw(e.target.value)} />
      </Field>
      <Field label="새 비밀번호 확인">
        <input className="input" type="password" autoComplete="new-password"
               value={pw2} onChange={e => setPw2(e.target.value)} />
      </Field>
      {msg && <Banner kind={msg.ok ? "ok" : "error"}>{msg.text}</Banner>}
      <Button type="submit" variant="primary" block size="lg" disabled={busy || !tok}>
        {busy ? "변경 중…" : "비밀번호 변경"}
      </Button>
      <Button variant="ghost" block type="button" onClick={onDone}>로그인 화면으로</Button>
    </form>
  );
}

Object.assign(window, { LoginPage });
