/* screens-core.jsx — Login (account list), TopBar, CompanyChip/Sheet, Home (role-aware). */

const ROLE_ICON = { staff: "user", approver: "shield", company_admin: "shield", admin: "settings" };
const ROLE_DESC = { staff: "roleDescStaff", approver: "roleDescApprover", company_admin: "roleDescCompanyAdmin", admin: "roleDescAdmin" };
function companyShort(c) { return c ? c.name.split("·")[0].trim() : ""; }

/* ---------- top bar ---------- */
function TopBar({ title, sub, onBack, lang, onLang, right }) {
  return (
    <div className="topbar">
      {onBack
        ? <button className="icon-btn" onClick={onBack} aria-label="back"><Icon name="back" size={20} /></button>
        : <div className="tile-icon" style={{ width: 38, height: 38, borderRadius: 11 }}><Icon name="receipt" size={20} /></div>}
      <div className="grow" style={{ flex: 1, minWidth: 0 }}>
        {typeof title === "string" ? <div className="tb-title truncate">{title}</div> : title}
        {sub && <div className="tb-sub truncate">{sub}</div>}
      </div>
      {right}
      <button className="icon-btn" onClick={onLang} aria-label="language"><Icon name="globe" size={19} /></button>
    </div>
  );
}

/* ---------- company chip (header) ---------- */
function CompanyChip({ company, canSwitch, onClick }) {
  return (
    <button onClick={canSwitch ? onClick : undefined}
      style={{
        display: "flex", alignItems: "center", gap: 7, background: "transparent",
        border: 0, padding: 0, color: "var(--text)", cursor: canSwitch ? "pointer" : "default", maxWidth: "100%",
      }}>
      <span className="tb-title truncate" style={{ maxWidth: 200 }}>{companyShort(company)}</span>
      {canSwitch && <Icon name="chevDown" size={16} style={{ color: "var(--muted)", flex: "0 0 auto" }} />}
    </button>
  );
}

function CompanySheet({ data, session, lang, onPick, onClose, onAdd, onAddBranch }) {
  const list = data.companies.filter((c) => session.companyIds.includes(c.id));
  // group branches under their legal entity (shared code + tax ID), keeping first-seen order
  const groups = [];
  const byKey = {};
  list.forEach((c) => {
    const key = (c.code || "") + "|" + (c.taxId || "");
    let g = byKey[key];
    if (!g) { g = byKey[key] = { key, company: c, branches: [] }; groups.push(g); }
    g.branches.push(c);
  });
  groups.forEach((g) => g.branches.sort((a, b) => String(a.branchCode || "").localeCompare(String(b.branchCode || ""))));
  return (
    <Sheet onClose={onClose}>
      <div className="h2" style={{ marginBottom: 4 }}>{window.t(lang, "selectBranch")}</div>
      <div className="lang-list" style={{ marginTop: 14 }}>
        {groups.map((g) => (
          <React.Fragment key={g.key}>
            <div className="eyebrow" style={{ margin: "10px 2px 2px" }}>
              {companyShort(g.company)} <span className="mono" style={{ opacity: 0.6 }}>· {g.company.code}</span>
            </div>
            {g.branches.map((c) => (
              <button key={c.id} className={`lang-opt ${c.id === session.companyId ? "on" : ""}`} onClick={() => onPick(c.id)}>
                <span style={{ display: "flex", alignItems: "center", gap: 12, minWidth: 0 }}>
                  <span className="tile-icon" style={{ width: 38, height: 38, borderRadius: 11, flex: "0 0 auto" }}><Icon name="building" size={18} /></span>
                  <span style={{ minWidth: 0 }}>
                    <span style={{ fontWeight: 600, display: "block" }} className="truncate">{c.branch || companyShort(c)}</span>
                    <span className="en mono">{window.t(lang, "branch")} {c.branchCode || "—"}</span>
                  </span>
                </span>
                {c.id === session.companyId && <Icon name="check" size={18} style={{ color: "var(--accent)", flex: "0 0 auto" }} />}
              </button>
            ))}
          </React.Fragment>
        ))}
        {onAddBranch && (
          <button className="lang-opt" onClick={onAddBranch} style={{ borderStyle: "dashed", color: "var(--accent)", marginTop: 10 }}>
            <span style={{ display: "flex", alignItems: "center", gap: 12 }}>
              <span className="tile-icon" style={{ width: 38, height: 38, borderRadius: 11, flex: "0 0 auto" }}><Icon name="plus" size={18} /></span>
              <span style={{ fontWeight: 600 }}>{window.t(lang, "addBranch")}</span>
            </span>
          </button>
        )}
        {onAdd && (
          <button className="lang-opt" onClick={onAdd} style={{ borderStyle: "dashed", color: "var(--accent)" }}>
            <span style={{ display: "flex", alignItems: "center", gap: 12 }}>
              <span className="tile-icon" style={{ width: 38, height: 38, borderRadius: 11, flex: "0 0 auto" }}><Icon name="plus" size={18} /></span>
              <span style={{ fontWeight: 600 }}>{window.t(lang, "addCompany")}</span>
            </span>
          </button>
        )}
      </div>
    </Sheet>
  );
}

/* ---------- login (pick an account) ---------- */
function Login({ lang, onLang, onSignIn, onSignUp, onForgot, authError }) {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [mode, setMode] = useState("signin"); // signin | signup
  const [busy, setBusy] = useState(false);
  const [notice, setNotice] = useState(null);  // "reset link sent" confirmation
  const valid = email.trim() && password.length >= 6;

  async function submit() {
    if (!valid || busy) return;
    setNotice(null); setBusy(true);
    try {
      if (mode === "signup") {
        const res = await onSignUp(email, password);
        if (res === "confirm") { setNotice(window.t(lang, "confirmEmailSent")); setMode("signin"); }
      } else {
        await onSignIn(email, password);
      }
    } finally { setBusy(false); }
  }
  async function forgot() {
    if (busy) return;
    setNotice(null); setBusy(true);
    try { if (await onForgot(email)) setNotice(window.t(lang, "resetEmailSent")); }
    finally { setBusy(false); }
  }

  return (
    <div className="app">
      <div className="topbar" style={{ justifyContent: "flex-end", borderBottom: "none" }}>
        <button className="pill" onClick={onLang}><Icon name="globe" size={16} />{window.LANGS.find((l) => l.code === lang).label}</button>
      </div>
      <div className="scroll" style={{ display: "flex", flexDirection: "column" }}>
        <div style={{ flex: "0 0 auto", paddingTop: 24, paddingBottom: 24 }}>
          <div className="tile-icon" style={{ width: 58, height: 58, borderRadius: 18, marginBottom: 20 }}><Icon name="receipt" size={27} /></div>
          <h1 className="h1" style={{ fontSize: 27 }}>{window.t(lang, "appName")}</h1>
          <p className="lead" style={{ marginTop: 8, textWrap: "pretty" }}>{window.t(lang, "tagline")}</p>
        </div>

        <div className="stack-lg" style={{ flex: 1 }}>
          <Field label={window.t(lang, "email")}>
            <input className="control" type="email" autoComplete="email" value={email} placeholder="name@company.co.th"
              onChange={(e) => setEmail(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") submit(); }} />
          </Field>
          <Field label={window.t(lang, "password")} hint={mode === "signup" ? "อย่างน้อย 6 ตัวอักษร · at least 6 characters" : null}>
            <input className="control" type="password" autoComplete={mode === "signup" ? "new-password" : "current-password"} value={password}
              onChange={(e) => setPassword(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") submit(); }} />
          </Field>

          {authError && (
            <div className="card" style={{ borderColor: "rgba(248,113,113,0.4)", background: "rgba(248,113,113,0.08)", color: "var(--danger)", fontSize: 13, textWrap: "pretty" }}>
              {authError}
            </div>
          )}
          {notice && (
            <div className="card" style={{ borderColor: "var(--accent-line)", background: "var(--accent-soft)", color: "var(--text-2)", fontSize: 13, textWrap: "pretty" }}>
              {notice}
            </div>
          )}

          <button className="lang-opt" style={{ justifyContent: "center", textAlign: "center" }}
            onClick={() => setMode(mode === "signup" ? "signin" : "signup")}>
            {mode === "signup"
              ? "มีบัญชีแล้ว? เข้าสู่ระบบ · Have an account? Sign in"
              : "ครั้งแรก? ตั้งรหัสผ่าน · First time? Create your password"}
          </button>
          {mode === "signin" && (
            <button className="lang-opt" style={{ justifyContent: "center", textAlign: "center" }} onClick={forgot} disabled={busy}>
              {window.t(lang, "forgotPassword")}
            </button>
          )}
        </div>
      </div>
      <div className="action-bar">
        <Button onClick={submit} disabled={!valid || busy} icon="fwd">
          {busy ? "…" : (mode === "signup" ? "ตั้งรหัสผ่าน · Create password" : window.t(lang, "signIn"))}
        </Button>
      </div>
    </div>
  );
}

/* ---------- set a new password (arrived via a reset link) ---------- */
function ResetPassword({ lang, onLang, onReset, authError }) {
  const [pw, setPw] = useState("");
  const [pw2, setPw2] = useState("");
  const [busy, setBusy] = useState(false);
  const match = pw.length >= 6 && pw === pw2;
  async function submit() {
    if (!match || busy) return;
    setBusy(true);
    try { await onReset(pw); } finally { setBusy(false); }
  }
  return (
    <div className="app">
      <div className="topbar" style={{ justifyContent: "flex-end", borderBottom: "none" }}>
        <button className="pill" onClick={onLang}><Icon name="globe" size={16} />{window.LANGS.find((l) => l.code === lang).label}</button>
      </div>
      <div className="scroll" style={{ display: "flex", flexDirection: "column" }}>
        <div style={{ flex: "0 0 auto", paddingTop: 24, paddingBottom: 24 }}>
          <div className="tile-icon" style={{ width: 58, height: 58, borderRadius: 18, marginBottom: 20 }}><Icon name="lock" size={26} /></div>
          <h1 className="h1" style={{ fontSize: 27 }}>{window.t(lang, "resetTitle")}</h1>
          <p className="lead" style={{ marginTop: 8, textWrap: "pretty" }}>{window.t(lang, "resetHint")}</p>
        </div>
        <div className="stack-lg" style={{ flex: 1 }}>
          <Field label={window.t(lang, "newPassword")} hint="อย่างน้อย 6 ตัวอักษร · at least 6 characters">
            <input className="control" type="password" autoComplete="new-password" value={pw}
              onChange={(e) => setPw(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") submit(); }} />
          </Field>
          <Field label={window.t(lang, "confirmPassword")}>
            <input className="control" type="password" autoComplete="new-password" value={pw2}
              onChange={(e) => setPw2(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") submit(); }} />
          </Field>
          {pw2 && pw !== pw2 && <div className="hint" style={{ color: "var(--warn)" }}>{window.t(lang, "passwordsNoMatch")}</div>}
          {authError && (
            <div className="card" style={{ borderColor: "rgba(248,113,113,0.4)", background: "rgba(248,113,113,0.08)", color: "var(--danger)", fontSize: 13, textWrap: "pretty" }}>{authError}</div>
          )}
        </div>
      </div>
      <div className="action-bar">
        <Button onClick={submit} disabled={!match || busy} icon="check">{busy ? "…" : window.t(lang, "savePassword")}</Button>
      </div>
    </div>
  );
}

/* ---------- home / dashboard ---------- */
function Home({ data, session, lang, onLang, nav, onSignOut, onSwitchCompany, onLock, onSetPin }) {
  const [showCo, setShowCo] = useState(false);
  const company = data.companies.find((c) => c.id === session.companyId);
  const user = data.users.find((u) => u.id === session.userId);
  const isAdmin = session.role === "admin";
  // who can open Back office: System Admin (all companies) or Company Admin (their own)
  const canManage = isAdmin || session.role === "company_admin";
  const canSwitch = session.companyIds.length > 1;

  const myDocs = data.documents
    .filter((d) => d.companyId === session.companyId)
    .slice().sort((a, b) => (a.date < b.date ? 1 : -1));
  // cross-company approval inbox — assignment-based (peer/supervisor) + peer review (exclude own)
  const toApprove = data.documents.filter((d) => {
    if (d.status !== "pending" || !session.companyIds.includes(d.companyId)) return false;
    const co = data.companies.find((c) => c.id === d.companyId);
    return co && window.canApprove(data, co, d, session.userId);
  });
  // is this user ever an approver (assigned to anyone, or admin)?
  const isApprover = isAdmin || data.companies.some((co) =>
    session.companyIds.includes(co.id) && co.approvalMap &&
    Object.values(co.approvalMap).some((m) => m.peer === user.id || m.supervisor === user.id));

  return (
    <div className="app">
      <TopBar
        title={<CompanyChip company={company} canSwitch={canSwitch} onClick={() => setShowCo(true)} />}
        sub={`${user.name} · ${window.t(lang, ROLE_DESC[session.role])}`}
        lang={lang} onLang={onLang}
        right={<React.Fragment>
          <button className="icon-btn" aria-label="lock"
            onClick={() => (window.hasPin(user.email) ? onLock && onLock() : onSetPin && onSetPin())}><Icon name="lock" size={18} /></button>
          <button className="icon-btn" onClick={onSignOut} aria-label="sign out"><Icon name="logout" size={18} /></button>
        </React.Fragment>}
      />
      <div className="scroll stack-lg">
        <div>
          <div className="eyebrow" style={{ marginBottom: 6 }}>{window.t(lang, "greeting")}, {user.name.split(" ")[0]}</div>
          <h1 className="h1">{window.t(lang, "chooseDocType")}</h1>
        </div>

        <div className="stack">
          <button className="tap-card" onClick={() => nav("create-grn")}>
            <div className="tile-icon"><Icon name="basket" size={24} /></div>
            <div className="grow" style={{ flex: 1 }}>
              <div style={{ fontWeight: 600, fontSize: 16 }}>{window.t(lang, "ingredientTitle")}</div>
              <div className="hint" style={{ marginTop: 3, textWrap: "pretty" }}>{window.t(lang, "ingredientDesc")}</div>
            </div>
            <Icon name="fwd" size={20} style={{ color: "var(--muted)", flex: "0 0 auto" }} />
          </button>
          <button className="tap-card" onClick={() => nav("create-opex")}>
            <div className="tile-icon"><Icon name="receipt" size={24} /></div>
            <div className="grow" style={{ flex: 1 }}>
              <div style={{ fontWeight: 600, fontSize: 16 }}>{window.t(lang, "opexTitle")}</div>
              <div className="hint" style={{ marginTop: 3, textWrap: "pretty" }}>{window.t(lang, "opexDesc")}</div>
            </div>
            <Icon name="fwd" size={20} style={{ color: "var(--muted)", flex: "0 0 auto" }} />
          </button>
        </div>

        {isApprover && (
          <button className="tap-card" style={{ borderColor: "var(--accent-line)", background: "var(--accent-soft)" }} onClick={() => nav("approval-queue")}>
            <div className="tile-icon"><Icon name="shield" size={22} /></div>
            <div className="grow" style={{ flex: 1 }}>
              <div style={{ fontWeight: 600 }}>{window.t(lang, "awaitingApproval")}</div>
              <div className="hint" style={{ marginTop: 2 }}>{toApprove.length} {window.t(lang, "pending")}</div>
            </div>
            {toApprove.length > 0 && <span className="badge is-pending"><i className="dot"></i>{toApprove.length}</span>}
          </button>
        )}

        {canManage && (
          <button className="tap-card" onClick={() => nav("backoffice")}>
            <div className="tile-icon" style={{ background: "var(--surface-2)", borderColor: "var(--line)", color: "var(--text-2)" }}><Icon name="settings" size={22} /></div>
            <div className="grow" style={{ flex: 1 }}>
              <div style={{ fontWeight: 600 }}>{window.t(lang, "backOffice")}</div>
              <div className="hint" style={{ marginTop: 2 }}>{(isAdmin ? data.companies.length : session.companyIds.length)} {window.t(lang, "companies")}</div>
            </div>
            <Icon name="fwd" size={20} style={{ color: "var(--muted)", flex: "0 0 auto" }} />
          </button>
        )}

        <div>
          <div className="between" style={{ marginBottom: 10 }}>
            <div className="eyebrow">{window.t(lang, "recentDocs")}</div>
          </div>
          <div className="stack">
            {myDocs.length === 0 && <div className="card center muted" style={{ padding: 28 }}>{window.t(lang, "noDocs")}</div>}
            {myDocs.map((d) => (
              <button key={d.id} className="row" style={{ textAlign: "left" }} onClick={() => nav("doc-view", { docId: d.id })}>
                <div className="tile-icon" style={{ width: 40, height: 40, borderRadius: 11 }}>
                  <Icon name={d.type === "FGR" ? "basket" : "receipt"} size={18} />
                </div>
                <div className="grow">
                  <div className="mono" style={{ fontSize: 13, fontWeight: 600 }}>{d.no}</div>
                  <div className="hint" style={{ marginTop: 2 }}>{window.fmtDate(d.date)} · ฿{window.fmtMoney(d.total)}</div>
                </div>
                <StatusBadge status={d.status} lang={lang} />
              </button>
            ))}
          </div>
        </div>
      </div>

      {showCo && <CompanySheet data={data} session={session} lang={lang}
        onPick={(id) => { onSwitchCompany(id); setShowCo(false); }} onClose={() => setShowCo(false)} />}
    </div>
  );
}

/* ---------- PIN quick-unlock ---------- */
function PinUnlock({ lang, onUnlock, onUsePassword, error, busy }) {
  const [pin, setPin] = useState("");
  const valid = pin.length >= 4;
  function submit() { if (valid && !busy) onUnlock(pin); }
  return (
    <div className="app">
      <div className="scroll" style={{ display: "flex", flexDirection: "column", justifyContent: "center" }}>
        <div className="center">
          <div className="tile-icon" style={{ width: 58, height: 58, borderRadius: 18, margin: "0 auto 20px" }}><Icon name="lock" size={26} /></div>
          <h1 className="h1" style={{ fontSize: 24 }}>ใส่ PIN · Enter your PIN</h1>
          <p className="lead" style={{ marginTop: 8 }}>เข้าใช้งานด่วน · Quick unlock</p>
        </div>
        <div className="stack-lg" style={{ marginTop: 24 }}>
          <input className="control" inputMode="numeric" type="password" autoFocus value={pin} maxLength={6}
            onChange={(e) => setPin(e.target.value.replace(/\D/g, ""))}
            onKeyDown={(e) => { if (e.key === "Enter") submit(); }}
            style={{ textAlign: "center", letterSpacing: "0.5em", fontSize: 24 }} />
          {error && <div className="card" style={{ borderColor: "rgba(248,113,113,0.4)", background: "rgba(248,113,113,0.08)", color: "var(--danger)", fontSize: 13, textAlign: "center" }}>{error}</div>}
        </div>
      </div>
      <div className="action-bar">
        <Button onClick={submit} disabled={!valid || busy} icon="fwd">{busy ? "…" : "ปลดล็อก · Unlock"}</Button>
        <button className="lang-opt" style={{ justifyContent: "center", textAlign: "center" }} onClick={onUsePassword}>ใช้อีเมล &amp; รหัสผ่าน · Use email &amp; password</button>
      </div>
    </div>
  );
}

function SetPinSheet({ lang, requirePassword, onSave, onClose }) {
  const [password, setPassword] = useState("");
  const [pin, setPin] = useState(""); const [confirm, setConfirm] = useState("");
  const [step, setStep] = useState(requirePassword ? "pw" : "pin");
  const [err, setErr] = useState(null);
  const titles = { pw: "ยืนยันรหัสผ่าน · Confirm your password", pin: "ตั้ง PIN · Set a quick PIN", confirm: "ยืนยัน PIN · Confirm PIN" };
  function next() {
    setErr(null);
    if (step === "pw") { if (password.length < 6) { setErr("รหัสผ่านอย่างน้อย 6 ตัว · password 6+ chars"); return; } setStep("pin"); return; }
    if (step === "pin") { if (pin.length < 4) return; setStep("confirm"); return; }
    if (pin !== confirm) { setErr("PIN ไม่ตรงกัน · PINs don't match"); setStep("pin"); setPin(""); setConfirm(""); return; }
    onSave(pin, password);
  }
  const isPw = step === "pw";
  const val = isPw ? password : (step === "pin" ? pin : confirm);
  const setVal = isPw ? setPassword : (step === "pin" ? setPin : setConfirm);
  const ok = isPw ? password.length >= 6 : (val.length >= 4 && val.length <= 6);
  return (
    <Sheet onClose={onClose}>
      <div className="h2" style={{ marginBottom: 6 }}>{titles[step]}</div>
      <p className="hint" style={{ marginBottom: 16, textWrap: "pretty" }}>
        {isPw ? "พิมพ์รหัสผ่านของคุณ เพื่อให้ PIN เข้าระบบแทนได้ · enter your password so the PIN can sign you in."
              : "4–6 หลัก สำหรับเข้าใช้งานด่วนบนเครื่องนี้ · 4–6 digits for fast login on this device."}
      </p>
      <div className="stack-lg">
        <input className="control" type="password" autoFocus key={step}
          inputMode={isPw ? "text" : "numeric"} value={val} maxLength={isPw ? 64 : 6}
          onChange={(e) => setVal(isPw ? e.target.value : e.target.value.replace(/\D/g, ""))}
          onKeyDown={(e) => { if (e.key === "Enter" && ok) next(); }}
          style={isPw ? null : { textAlign: "center", letterSpacing: "0.5em", fontSize: 24 }} />
        {err && <div className="hint" style={{ color: "var(--danger)" }}>{err}</div>}
        <div className="btn-row">
          <Button variant="ghost" onClick={onClose}>ยกเลิก · Cancel</Button>
          <Button onClick={next} disabled={!ok} icon={step === "confirm" ? "check" : "fwd"}>{step === "confirm" ? "บันทึก · Save" : "ถัดไป · Next"}</Button>
        </div>
      </div>
    </Sheet>
  );
}

Object.assign(window, { TopBar, LangSheet, Login, ResetPassword, Home, CompanyChip, CompanySheet, PinUnlock, SetPinSheet });

/* ---------- language sheet (kept here) ---------- */
function LangSheet({ lang, theme, onPick, onPickTheme, onClose }) {
  return (
    <Sheet onClose={onClose}>
      <div className="h2" style={{ marginBottom: 4 }}>{window.t(lang, "selectLanguage")}</div>
      <div className="lang-list" style={{ marginTop: 14 }}>
        {window.LANGS.map((L) => (
          <button key={L.code} className={`lang-opt ${L.code === lang ? "on" : ""}`} onClick={() => onPick(L.code)}>
            <span style={{ fontWeight: 600 }}>{L.label}</span>
            <span className="en">{L.code === lang ? <Icon name="check" size={18} style={{ color: "var(--accent)" }} /> : L.en}</span>
          </button>
        ))}
      </div>
      {onPickTheme && (
        <React.Fragment>
          <div className="eyebrow" style={{ margin: "18px 2px 8px" }}>{window.t(lang, "theme")}</div>
          <div className="seg-ctrl">
            <button className={theme === "system" ? "on" : ""} onClick={() => onPickTheme("system")}>{window.t(lang, "themeSystem")}</button>
            <button className={theme === "light" ? "on" : ""} onClick={() => onPickTheme("light")}>{window.t(lang, "themeLight")}</button>
            <button className={theme === "dark" ? "on" : ""} onClick={() => onPickTheme("dark")}>{window.t(lang, "themeDark")}</button>
          </div>
        </React.Fragment>
      )}
    </Sheet>
  );
}
Object.assign(window, { LangSheet });
