/* global React, window, api, useAuth, humanError, useIsMobile */
const { useState: useS, useEffect: useE } = React;

/* =========================================================
   Shared form atoms
   ========================================================= */
function AuthShell({ kicker, title, children, footer }) {
  const m = useIsMobile();
  return (
    <div style={{ paddingTop: m ? 104 : 140, paddingBottom: m ? 80 : 120, minHeight: "70vh" }}>
      <div style={{ maxWidth: 480, margin: "0 auto", padding: m ? "0 20px" : "0 28px" }}>
        <div style={{
          fontFamily: "'Manrope', sans-serif", fontSize: 11, letterSpacing: "0.22em",
          textTransform: "uppercase", color: "rgba(0,0,0,0.55)",
        }}>{kicker}</div>
        <h1 style={{
          fontFamily: "'Cormorant Garamond', serif", fontWeight: 300, fontStyle: "italic",
          fontSize: "clamp(36px, 4vw, 56px)", lineHeight: 1.05,
          margin: "12px 0 32px", letterSpacing: "-0.005em",
        }}>{title}</h1>
        {children}
        {footer && <div style={{ marginTop: 28, fontFamily: "'Manrope', sans-serif", fontSize: 13, color: "rgba(0,0,0,0.6)" }}>{footer}</div>}
      </div>
    </div>
  );
}

function Field({ label, type = "text", value, onChange, autoComplete, autoFocus, disabled }) {
  return (
    <label style={{ display: "block", marginBottom: 20 }}>
      <div style={{
        fontFamily: "'Manrope', sans-serif", fontSize: 11, letterSpacing: "0.18em",
        textTransform: "uppercase", color: "rgba(0,0,0,0.55)", marginBottom: 8,
      }}>{label}</div>
      <input
        type={type}
        value={value}
        onChange={e => onChange(e.target.value)}
        autoComplete={autoComplete}
        autoFocus={autoFocus}
        disabled={disabled}
        style={{
          width: "100%",
          fontFamily: "'Manrope', sans-serif", fontSize: 15,
          padding: "12px 14px",
          background: "transparent",
          border: "1px solid rgba(0,0,0,0.18)",
          color: "var(--ink)",
          outline: "none",
        }}
        onFocus={e => e.target.style.borderColor = "var(--ink)"}
        onBlur={e => e.target.style.borderColor = "rgba(0,0,0,0.18)"}
      />
    </label>
  );
}

function PrimaryButton({ children, onClick, disabled, type = "button" }) {
  return (
    <button type={type} onClick={onClick} disabled={disabled} style={{
      all: "unset", cursor: disabled ? "not-allowed" : "pointer", display: "inline-block",
      fontFamily: "'Manrope', sans-serif", fontSize: 12, letterSpacing: "0.22em",
      textTransform: "uppercase",
      padding: "16px 26px",
      background: disabled ? "rgba(0,0,0,0.45)" : "var(--ink)",
      color: "var(--cream)",
      transition: "opacity 200ms ease",
      opacity: disabled ? 0.7 : 1,
    }}>{children}</button>
  );
}

function GhostBtn({ children, onClick, type = "button" }) {
  return (
    <button type={type} onClick={onClick} style={{
      all: "unset", cursor: "pointer",
      fontFamily: "'Manrope', sans-serif", fontSize: 12, letterSpacing: "0.22em",
      textTransform: "uppercase", color: "var(--ink)",
      padding: "16px 26px",
      border: "1px solid var(--ink)",
    }}>{children}</button>
  );
}

function InlineLink({ children, onClick }) {
  return (
    <button onClick={onClick} style={{
      all: "unset", cursor: "pointer",
      fontFamily: "'Manrope', sans-serif", fontSize: 13,
      color: "var(--ink)", borderBottom: "1px solid var(--ink)", paddingBottom: 2,
    }}>{children}</button>
  );
}

function Banner({ kind, children }) {
  const palette = {
    error:   { bg: "rgba(90, 31, 34, 0.08)",  bd: "rgba(90, 31, 34, 0.3)",  fg: "#5A1F22" },
    success: { bg: "rgba(44, 58, 46, 0.08)",  bd: "rgba(44, 58, 46, 0.3)",  fg: "#2C3A2E" },
    info:    { bg: "rgba(0,0,0,0.04)",        bd: "rgba(0,0,0,0.15)",       fg: "rgba(0,0,0,0.75)" },
  }[kind] || { bg: "rgba(0,0,0,0.04)", bd: "rgba(0,0,0,0.15)", fg: "rgba(0,0,0,0.75)" };
  return (
    <div style={{
      background: palette.bg, border: `1px solid ${palette.bd}`, color: palette.fg,
      padding: "12px 14px", marginBottom: 20,
      fontFamily: "'Manrope', sans-serif", fontSize: 13, lineHeight: 1.5,
    }}>{children}</div>
  );
}

function Divider({ label = "или" }) {
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 14, margin: "22px 0 6px" }}>
      <div style={{ flex: 1, height: 1, background: "rgba(0,0,0,0.14)" }} />
      <span style={{
        fontFamily: "'Manrope', sans-serif", fontSize: 11, letterSpacing: "0.18em",
        textTransform: "uppercase", color: "rgba(0,0,0,0.4)",
      }}>{label}</span>
      <div style={{ flex: 1, height: 1, background: "rgba(0,0,0,0.14)" }} />
    </div>
  );
}

/* Кнопка «Войти через Google» (Google Identity Services).
   Показывается только если в index.html задан window.GOOGLE_CLIENT_ID. */
function GoogleSignInButton({ onError }) {
  const auth = useAuth();
  const ref = React.useRef(null);
  const clientId = window.GOOGLE_CLIENT_ID;

  useE(() => {
    if (!clientId) return;
    let tries = 0;
    let stopped = false;
    const init = () => {
      if (stopped) return;
      const g = window.google;
      if (g && g.accounts && g.accounts.id && ref.current) {
        g.accounts.id.initialize({
          client_id: clientId,
          callback: async (resp) => {
            try { await auth.loginWithGoogle(resp.credential); }
            catch (err) { if (onError) onError(humanError(err)); }
          },
        });
        ref.current.innerHTML = "";
        g.accounts.id.renderButton(ref.current, {
          type: "standard", theme: "outline", size: "large",
          text: "continue_with", shape: "rectangular",
          logo_alignment: "left", width: 320,
        });
        return;
      }
      // GSI-скрипт грузится async - подождём, пока появится window.google
      if (tries++ < 50) setTimeout(init, 100);
    };
    init();
    return () => { stopped = true; };
  }, [clientId]);

  if (!clientId) return null;
  return (
    <div>
      <div ref={ref} style={{ display: "flex", justifyContent: "center", minHeight: 44 }} />
      <Divider />
    </div>
  );
}

/* =========================================================
   LOGIN
   ========================================================= */
function LoginPage({ setRoute }) {
  const auth = useAuth();
  const [email, setEmail] = useS("");
  const [password, setPassword] = useS("");
  const [busy, setBusy] = useS(false);
  const [error, setError] = useS(null);

  useE(() => { if (auth.isAuthed) setRoute("account"); }, [auth.isAuthed]);

  const submit = async (e) => {
    if (e && e.preventDefault) e.preventDefault();
    setError(null); setBusy(true);
    try {
      await auth.login({ email, password });
      setRoute("account");
    } catch (err) {
      setError(humanError(err));
    } finally { setBusy(false); }
  };

  return (
    <AuthShell
      kicker="Вход"
      title={<>Аккаунт<br/><em>в&nbsp;Royal&nbsp;Harmony.</em></>}
      footer={
        <div style={{ display: "flex", justifyContent: "space-between", flexWrap: "wrap", gap: 12 }}>
          <InlineLink onClick={() => setRoute("forgot")}>Забыли пароль?</InlineLink>
          <InlineLink onClick={() => setRoute("register")}>Создать аккаунт</InlineLink>
        </div>
      }
    >
      {error && <Banner kind="error">{error}</Banner>}
      <GoogleSignInButton onError={setError} />
      <form onSubmit={submit}>
        <Field label="Email" type="email" value={email} onChange={setEmail} autoComplete="email" autoFocus disabled={busy} />
        <Field label="Пароль" type="password" value={password} onChange={setPassword} autoComplete="current-password" disabled={busy} />
        <PrimaryButton type="submit" onClick={submit} disabled={busy || !email || !password}>
          {busy ? "Входим…" : "Войти"}
        </PrimaryButton>
      </form>
    </AuthShell>
  );
}

/* =========================================================
   REGISTER (двухшаговая: email → код + пароль)
   ========================================================= */
function RegisterPage({ setRoute }) {
  const auth = useAuth();
  const [step, setStep] = useS(1);           // 1: email, 2: код+пароль
  const [email, setEmail] = useS("");
  const [code, setCode] = useS("");
  const [name, setName] = useS("");
  const [password, setPassword] = useS("");
  const [busy, setBusy] = useS(false);
  const [error, setError] = useS(null);
  const [resendIn, setResendIn] = useS(0);   // секунд до возможности запросить код снова

  useE(() => { if (auth.isAuthed) setRoute("account"); }, [auth.isAuthed]);

  // обратный отсчёт для повторной отправки кода
  useE(() => {
    if (resendIn <= 0) return;
    const id = setTimeout(() => setResendIn(resendIn - 1), 1000);
    return () => clearTimeout(id);
  }, [resendIn]);

  const requestCode = async (e) => {
    if (e && e.preventDefault) e.preventDefault();
    setError(null); setBusy(true);
    try {
      await api.requestCode(email);
      setStep(2);
      setResendIn(60);
    } catch (err) { setError(humanError(err)); }
    finally { setBusy(false); }
  };

  const completeRegister = async (e) => {
    if (e && e.preventDefault) e.preventDefault();
    setError(null); setBusy(true);
    try {
      await auth.register({ email, password, code, name: name || undefined });
      setRoute("account");
    } catch (err) { setError(humanError(err)); }
    finally { setBusy(false); }
  };

  if (step === 1) {
    return (
      <AuthShell
        kicker="Регистрация"
        title={<>Новый<br/><em>аккаунт.</em></>}
        footer={<>Уже есть аккаунт? <InlineLink onClick={() => setRoute("login")}>Войти</InlineLink></>}
      >
        {error && <Banner kind="error">{error}</Banner>}
        <GoogleSignInButton onError={setError} />
        <p style={{ fontFamily: "'Manrope', sans-serif", fontSize: 14, lineHeight: 1.65, color: "rgba(0,0,0,0.7)", marginBottom: 24 }}>
          Введите email - мы пришлём 6-значный код для&nbsp;подтверждения.
        </p>
        <form onSubmit={requestCode}>
          <Field label="Email" type="email" value={email} onChange={setEmail} autoComplete="email" autoFocus disabled={busy} />
          <PrimaryButton type="submit" onClick={requestCode} disabled={busy || !email}>
            {busy ? "Отправляем…" : "Прислать код"}
          </PrimaryButton>
        </form>
      </AuthShell>
    );
  }

  return (
    <AuthShell
      kicker="Регистрация · шаг 2"
      title={<>Введите<br/><em>код из&nbsp;письма.</em></>}
      footer={
        <div style={{ display: "flex", justifyContent: "space-between", flexWrap: "wrap", gap: 12 }}>
          <InlineLink onClick={() => { setStep(1); setCode(""); setError(null); }}>← Изменить email</InlineLink>
          {resendIn > 0
            ? <span style={{ opacity: 0.5 }}>Прислать снова через {resendIn} с</span>
            : <InlineLink onClick={requestCode}>Прислать код снова</InlineLink>}
        </div>
      }
    >
      {error && <Banner kind="error">{error}</Banner>}
      <p style={{ fontFamily: "'Manrope', sans-serif", fontSize: 14, lineHeight: 1.65, color: "rgba(0,0,0,0.7)", marginBottom: 24 }}>
        Код отправлен на&nbsp;<strong>{email}</strong>. Код действует 15 минут.
      </p>
      <form onSubmit={completeRegister}>
        <Field
          label="6-значный код"
          value={code}
          onChange={v => setCode(v.replace(/\D/g, "").slice(0, 6))}
          autoComplete="one-time-code"
          autoFocus
          disabled={busy}
        />
        <Field label="Имя (необязательно)" value={name} onChange={setName} autoComplete="name" disabled={busy} />
        <Field label="Придумайте пароль (минимум 8)" type="password" value={password} onChange={setPassword} autoComplete="new-password" disabled={busy} />
        <PrimaryButton type="submit" onClick={completeRegister} disabled={busy || code.length !== 6 || password.length < 8}>
          {busy ? "Создаём…" : "Создать аккаунт"}
        </PrimaryButton>
      </form>
    </AuthShell>
  );
}

/* =========================================================
   FORGOT
   ========================================================= */
function ForgotPasswordPage({ setRoute }) {
  const [email, setEmail] = useS("");
  const [busy, setBusy] = useS(false);
  const [sent, setSent] = useS(false);
  const [error, setError] = useS(null);

  const submit = async (e) => {
    if (e && e.preventDefault) e.preventDefault();
    setError(null); setBusy(true);
    try { await api.forgotPassword(email); setSent(true); }
    catch (err) { setError(humanError(err)); }
    finally { setBusy(false); }
  };

  return (
    <AuthShell
      kicker="Восстановление"
      title={<>Сброс<br/><em>пароля.</em></>}
      footer={<InlineLink onClick={() => setRoute("login")}>← Назад ко входу</InlineLink>}
    >
      {sent ? (
        <Banner kind="success">
          Если email есть в&nbsp;нашей базе - на&nbsp;него отправлено письмо со&nbsp;ссылкой.
          Ссылка действует 30 минут.
        </Banner>
      ) : (
        <>
          {error && <Banner kind="error">{error}</Banner>}
          <p style={{ fontFamily: "'Manrope', sans-serif", fontSize: 14, lineHeight: 1.65, color: "rgba(0,0,0,0.7)", marginBottom: 24 }}>
            Введите email - мы отправим письмо со&nbsp;ссылкой для&nbsp;установки нового пароля.
          </p>
          <form onSubmit={submit}>
            <Field label="Email" type="email" value={email} onChange={setEmail} autoComplete="email" autoFocus disabled={busy} />
            <PrimaryButton type="submit" onClick={submit} disabled={busy || !email}>
              {busy ? "Отправляем…" : "Отправить ссылку"}
            </PrimaryButton>
          </form>
        </>
      )}
    </AuthShell>
  );
}

/* =========================================================
   RESET (по ссылке из письма)
   ========================================================= */
function ResetPasswordPage({ token, setRoute }) {
  const [password, setPassword] = useS("");
  const [confirm, setConfirm] = useS("");
  const [busy, setBusy] = useS(false);
  const [done, setDone] = useS(false);
  const [error, setError] = useS(null);

  const submit = async (e) => {
    if (e && e.preventDefault) e.preventDefault();
    if (password !== confirm) { setError("Пароли не совпадают."); return; }
    setError(null); setBusy(true);
    try {
      await api.resetPassword({ token, newPassword: password });
      setDone(true);
    } catch (err) { setError(humanError(err)); }
    finally { setBusy(false); }
  };

  if (!token) {
    return (
      <AuthShell kicker="Восстановление" title={<>Ссылка<br/><em>не&nbsp;распознана.</em></>}>
        <Banner kind="error">Открой ссылку из&nbsp;письма целиком - в&nbsp;адресе должен быть токен после <code>#reset/</code>.</Banner>
        <PrimaryButton onClick={() => setRoute("forgot")}>Запросить новую</PrimaryButton>
      </AuthShell>
    );
  }

  if (done) {
    return (
      <AuthShell kicker="Готово" title={<>Пароль<br/><em>обновлён.</em></>}>
        <Banner kind="success">Теперь войдите с&nbsp;новым паролем.</Banner>
        <PrimaryButton onClick={() => setRoute("login")}>К&nbsp;входу</PrimaryButton>
      </AuthShell>
    );
  }

  return (
    <AuthShell kicker="Новый пароль" title={<>Установите<br/><em>новый&nbsp;пароль.</em></>}>
      {error && <Banner kind="error">{error}</Banner>}
      <form onSubmit={submit}>
        <Field label="Новый пароль" type="password" value={password} onChange={setPassword} autoComplete="new-password" autoFocus disabled={busy} />
        <Field label="Повторите пароль" type="password" value={confirm} onChange={setConfirm} autoComplete="new-password" disabled={busy} />
        <PrimaryButton type="submit" onClick={submit} disabled={busy || password.length < 8 || !confirm}>
          {busy ? "Сохраняем…" : "Сохранить"}
        </PrimaryButton>
      </form>
    </AuthShell>
  );
}

/* =========================================================
   ACCOUNT (Личный кабинет)
   ========================================================= */
function AccountPage({ setRoute }) {
  const auth = useAuth();
  const m = useIsMobile();
  const [name, setName] = useS("");
  const [phone, setPhone] = useS("");
  const [profileBusy, setProfileBusy] = useS(false);
  const [profileMsg, setProfileMsg] = useS(null);

  const [curPass, setCurPass] = useS("");
  const [newPass, setNewPass] = useS("");
  const [passBusy, setPassBusy] = useS(false);
  const [passMsg, setPassMsg] = useS(null);

  useE(() => {
    if (auth.isLoading) return;
    if (!auth.isAuthed) { setRoute("login"); return; }
    setName(auth.user.name || "");
    setPhone(auth.user.phone || "");
  }, [auth.isLoading, auth.isAuthed, auth.user?.id]);

  if (auth.isLoading) {
    return (
      <div style={{ paddingTop: 200, textAlign: "center", fontFamily: "'Manrope', sans-serif", fontSize: 13, color: "rgba(0,0,0,0.5)", letterSpacing: "0.1em", textTransform: "uppercase" }}>
        Загружаем…
      </div>
    );
  }
  if (!auth.isAuthed) return null;

  const saveProfile = async (e) => {
    if (e && e.preventDefault) e.preventDefault();
    setProfileMsg(null); setProfileBusy(true);
    try {
      await auth.refresh();
      const payload = {};
      if (name !== (auth.user.name || "")) payload.name = name;
      if (phone !== (auth.user.phone || "")) payload.phone = phone;
      if (Object.keys(payload).length === 0) {
        setProfileMsg({ kind: "info", text: "Нет изменений." });
      } else {
        await api.updateMe(payload);
        await auth.refresh();
        setProfileMsg({ kind: "success", text: "Сохранено." });
      }
    } catch (err) { setProfileMsg({ kind: "error", text: humanError(err) }); }
    finally { setProfileBusy(false); }
  };

  const changePassword = async (e) => {
    if (e && e.preventDefault) e.preventDefault();
    setPassMsg(null); setPassBusy(true);
    try {
      await api.changePassword({ currentPassword: curPass, newPassword: newPass });
      setPassMsg({ kind: "success", text: "Пароль обновлён. Войдите заново." });
      setCurPass(""); setNewPass("");
      setTimeout(async () => { await auth.logout(); setRoute("login"); }, 1200);
    } catch (err) { setPassMsg({ kind: "error", text: humanError(err) }); }
    finally { setPassBusy(false); }
  };

  const logout = async () => { await auth.logout(); setRoute("home"); };

  return (
    <div style={{ paddingTop: m ? 96 : 140, paddingBottom: m ? 80 : 120 }}>
      <div style={{ maxWidth: 1100, margin: "0 auto", padding: m ? "0 20px" : "0 40px" }}>
        <div style={{
          fontFamily: "'Manrope', sans-serif", fontSize: 11, letterSpacing: "0.22em",
          textTransform: "uppercase", color: "rgba(0,0,0,0.55)",
        }}>Личный кабинет</div>
        <h1 style={{
          fontFamily: "'Cormorant Garamond', serif", fontWeight: 300, fontStyle: "italic",
          fontSize: "clamp(40px, 4.6vw, 64px)", lineHeight: 1.02,
          margin: "12px 0 8px", letterSpacing: "-0.005em",
        }}>{auth.user.name ? auth.user.name : auth.user.email}</h1>
        <div style={{ fontFamily: "'JetBrains Mono', ui-monospace, monospace", fontSize: 12, color: "rgba(0,0,0,0.55)", letterSpacing: "0.06em" }}>
          {auth.user.email}
        </div>

        <div style={{ display: "grid", gridTemplateColumns: m ? "1fr" : "1fr 1fr", gap: m ? 48 : 64, marginTop: m ? 40 : 56 }}>
          {/* Профиль */}
          <section>
            <h2 style={{
              fontFamily: "'Cormorant Garamond', serif", fontWeight: 300, fontStyle: "italic",
              fontSize: 28, margin: "0 0 24px",
            }}>Профиль</h2>
            {profileMsg && <Banner kind={profileMsg.kind}>{profileMsg.text}</Banner>}
            <form onSubmit={saveProfile}>
              <Field label="Имя" value={name} onChange={setName} autoComplete="name" disabled={profileBusy} />
              <Field label="Телефон" value={phone} onChange={setPhone} autoComplete="tel" disabled={profileBusy} />
              <PrimaryButton type="submit" onClick={saveProfile} disabled={profileBusy}>
                {profileBusy ? "Сохраняем…" : "Сохранить"}
              </PrimaryButton>
            </form>
          </section>

          {/* Пароль */}
          <section>
            <h2 style={{
              fontFamily: "'Cormorant Garamond', serif", fontWeight: 300, fontStyle: "italic",
              fontSize: 28, margin: "0 0 24px",
            }}>Сменить пароль</h2>
            {auth.user.hasPassword ? (
              <>
                {passMsg && <Banner kind={passMsg.kind}>{passMsg.text}</Banner>}
                <form onSubmit={changePassword}>
                  <Field label="Текущий пароль" type="password" value={curPass} onChange={setCurPass} autoComplete="current-password" disabled={passBusy} />
                  <Field label="Новый пароль (минимум 8)" type="password" value={newPass} onChange={setNewPass} autoComplete="new-password" disabled={passBusy} />
                  <PrimaryButton type="submit" onClick={changePassword} disabled={passBusy || !curPass || newPass.length < 8}>
                    {passBusy ? "Обновляем…" : "Обновить пароль"}
                  </PrimaryButton>
                </form>
              </>
            ) : (
              <Banner kind="info">
                Вы вошли через&nbsp;Google, пароль не&nbsp;задан. Чтобы установить пароль,
                воспользуйтесь ссылкой «Забыли пароль?» на&nbsp;странице входа.
              </Banner>
            )}
          </section>
        </div>

        <div style={{
          marginTop: 80, paddingTop: 32, borderTop: "1px solid rgba(0,0,0,0.12)",
          display: "flex", justifyContent: "space-between", alignItems: "center", flexWrap: "wrap", gap: 16,
        }}>
          <div style={{ fontFamily: "'Manrope', sans-serif", fontSize: 12, color: "rgba(0,0,0,0.5)" }}>
            Аккаунт создан: <span style={{ fontFamily: "'JetBrains Mono', ui-monospace, monospace" }}>{auth.user.createdAt}</span>
          </div>
          <GhostBtn onClick={logout}>Выйти из аккаунта</GhostBtn>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { LoginPage, RegisterPage, ForgotPasswordPage, ResetPasswordPage, AccountPage });
