/* screens-backoffice.jsx — company-scoped admin: Settings · Ingredients · Expenses · Users.
   Company switched from a header chip (same pattern as creation). Edits commit live. */

const ROLE_ICONS = { staff: "user", company_admin: "shield", admin: "settings" };

function BackOffice({ data, session, route, lang, onLang, nav, onSignOut,
  boCompanyId, onSwitchCompany, onAddCompany, onAddBranch, patchCompany, deleteCompany,
  upsertListItem, deleteListItem, upsertUser, setMembership, setApprovers }) {

  const [tab, setTab] = useState("info");
  const [showCo, setShowCo] = useState(false);
  const [draft, setDraft] = useState(null);   // ingredient/expense item editor
  const [userDraft, setUserDraft] = useState(null); // user editor
  const [addExisting, setAddExisting] = useState(null); // "add existing user to this branch" picker

  // System Admin manages every company + creates companies/branches + appoints
  // admins. Company Admin manages only the companies they belong to, adds staff
  // only, and cannot create/delete companies or branches.
  const isSysAdmin = session.role === "admin";
  const company = data.companies.find((c) => c.id === boCompanyId) || data.companies[0];
  if (!company) return <div className="app" />;
  const members = data.users.filter((u) => u.companyIds.includes(company.id));

  /* ---- list item editor ---- */
  function openItem(kind, item) {
    setDraft(item ? { kind, ...item } : { kind, th: "", en: "", unit: kind === "ing" ? "กก. / kg" : "" });
  }
  function saveItem() {
    const key = draft.kind === "ing" ? "ingredients" : "expenses";
    const rec = draft.kind === "ing"
      ? { id: draft.id || "i" + Date.now(), th: draft.th, en: draft.en, unit: draft.unit }
      : { id: draft.id || "e" + Date.now(), th: draft.th, en: draft.en };
    upsertListItem(company.id, key, rec);
    setDraft(null);
  }

  return (
    <div className="app">
      <TopBar
        title={<CompanyChip company={company} canSwitch onClick={() => setShowCo(true)} />}
        sub={window.t(lang, "backOffice")}
        onBack={() => nav("home")} lang={lang} onLang={onLang}
        right={<button className="icon-btn" onClick={onSignOut} aria-label="sign out"><Icon name="logout" size={18} /></button>}
      />
      <div style={{ padding: "12px 16px 0" }}>
        <div className="seg-ctrl">
          <button className={tab === "info" ? "on" : ""} onClick={() => setTab("info")}>{window.t(lang, "settings")}</button>
          <button className={tab === "users" ? "on" : ""} onClick={() => setTab("users")}>{window.t(lang, "users")}</button>
          <button className={tab === "ing" ? "on" : ""} onClick={() => setTab("ing")}>{window.t(lang, "ingredientList")}</button>
          <button className={tab === "exp" ? "on" : ""} onClick={() => setTab("exp")}>{window.t(lang, "expenseList")}</button>
        </div>
      </div>

      <div className="scroll stack-lg">
        {tab === "info" && (
          <div className="stack-lg fade-in">
            <div className="eyebrow">{window.t(lang, "companyLegal")}</div>
            <Field label={window.t(lang, "companyCode")} hint={window.t(lang, "companyCodeHint")}>
              <input className="control mono" value={company.code} maxLength={5} placeholder="ABC"
                onChange={(e) => patchCompany(company.id, { code: e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, "") })} />
            </Field>
            <Field label={window.t(lang, "companyName")}>
              <input className="control" value={company.name} onChange={(e) => patchCompany(company.id, { name: e.target.value })} />
            </Field>
            <Field label={window.t(lang, "taxId")}>
              <input className="control mono" value={company.taxId} onChange={(e) => patchCompany(company.id, { taxId: e.target.value })} />
            </Field>
            <hr className="hr" />
            <div className="eyebrow">{window.t(lang, "branchDetails")}</div>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1.6fr", gap: 12 }}>
              <Field label={window.t(lang, "branchCode")} hint={window.t(lang, "branchCodeHint")}>
                <input className="control mono" value={company.branchCode || ""} maxLength={5} placeholder="00000"
                  onChange={(e) => patchCompany(company.id, { branchCode: e.target.value.replace(/[^0-9]/g, "").slice(0, 5) })} />
              </Field>
              <Field label={window.t(lang, "branchName")}>
                <input className="control" value={company.branch} onChange={(e) => patchCompany(company.id, { branch: e.target.value })} />
              </Field>
            </div>
            <Field label={window.t(lang, "address")}>
              <textarea className="control" value={company.address} onChange={(e) => patchCompany(company.id, { address: e.target.value })} />
            </Field>
            <hr className="hr" />
            <Field label={window.t(lang, "opexUpperBound")}>
              <div className="input-suffix">
                <input className="control mono" type="number" value={company.opexUpperBound}
                  onChange={(e) => patchCompany(company.id, { opexUpperBound: Number(e.target.value) })} style={{ paddingRight: 48 }} />
                <span className="suffix">฿</span>
              </div>
            </Field>
            <Field label={window.t(lang, "accountantEmail")} hint="documents are emailed here on approval">
              <input className="control" type="email" value={company.accountantEmail}
                onChange={(e) => patchCompany(company.id, { accountantEmail: e.target.value })} placeholder="accounts@company.co.th" />
            </Field>
            {isSysAdmin && (
              <button className="btn btn-danger" onClick={() => { if (data.companies.length > 1) deleteCompany(company.id); }}>
                <Icon name="trash" size={18} />{window.t(lang, "delete")}
              </button>
            )}
          </div>
        )}

        {tab === "users" && (
          <div className="stack fade-in">
            <div className="eyebrow">{window.t(lang, "users")} · {members.length}</div>
            <div style={{ display: "flex", gap: 8 }}>
              <button className="btn btn-ghost btn-sm" style={{ width: "auto" }}
                onClick={() => setUserDraft({ isNew: true, name: "", title: "", email: "", role: "staff", signature: "", companyIds: [company.id], _peer: "", _sup: "" })}>
                <Icon name="plus" size={16} />{window.t(lang, "addMember")}
              </button>
              <button className="btn btn-ghost btn-sm" style={{ width: "auto" }}
                onClick={() => setAddExisting({ userId: "", _peer: "", _sup: "" })}>
                <Icon name="user" size={16} />{window.t(lang, "addExistingUser")}
              </button>
            </div>
            <p className="hint" style={{ textWrap: "pretty", margin: "0 2px 4px" }}>{window.t(lang, "approverHint")}</p>
            {members.map((u) => {
              const a = (company.approvalMap && company.approvalMap[u.id]) || {};
              const peer = members.find((m) => m.id === a.peer);
              const sup = members.find((m) => m.id === a.sup || m.id === a.supervisor);
              const noApprover = !peer && !sup;
              return (
                <button key={u.id} className="row" style={{ textAlign: "left", alignItems: "flex-start" }}
                  onClick={() => setUserDraft({ ...u, _peer: a.peer || "", _sup: a.supervisor || "" })}>
                  <div className="tile-icon" style={{ width: 40, height: 40, borderRadius: 11, flex: "0 0 auto" }}><Icon name={u.icon || ROLE_ICONS[u.role]} size={18} /></div>
                  <div className="grow">
                    <div className="between" style={{ gap: 8 }}>
                      <span style={{ fontWeight: 600 }} className="truncate">{u.name}</span>
                      {u.role === "admin" && <span className="badge" style={{ flex: "0 0 auto" }}>{window.t(lang, "roleAdmin")}</span>}
                      {u.role === "company_admin" && <span className="badge" style={{ flex: "0 0 auto" }}>{window.t(lang, "roleCompanyAdmin")}</span>}
                    </div>
                    <div className="hint" style={{ marginTop: 1 }}>{u.title}</div>
                    <div className="stack gap-sm" style={{ marginTop: 8 }}>
                      {u.role === "admin"
                        ? <span className="hint" style={{ color: "var(--accent)" }}>{window.t(lang, "adminFallback")}</span>
                        : noApprover
                          ? <span className="hint" style={{ color: "var(--warn)" }}><Icon name="warn" size={13} style={{ verticalAlign: "-2px" }} /> {window.t(lang, "noApproverSet")}</span>
                          : (
                            <div style={{ display: "flex", flexWrap: "wrap", gap: 6 }}>
                              {peer && <span className="pill" style={{ padding: "5px 10px", fontSize: 12 }}><b style={{ color: "var(--text-2)", fontWeight: 600 }}>{window.t(lang, "peer")}:</b> {peer.name}</span>}
                              {sup && <span className="pill" style={{ padding: "5px 10px", fontSize: 12 }}><b style={{ color: "var(--text-2)", fontWeight: 600 }}>{window.t(lang, "supervisor")}:</b> {sup.name}</span>}
                            </div>
                          )}
                    </div>
                  </div>
                  <Icon name="edit" size={16} style={{ color: "var(--muted)", flex: "0 0 auto", marginTop: 2 }} />
                </button>
              );
            })}
          </div>
        )}

        {(tab === "ing" || tab === "exp") && (
          <div className="stack fade-in">
            <div className="between">
              <div className="eyebrow">{window.t(lang, tab === "ing" ? "ingredientList" : "expenseList")}</div>
              <button className="btn btn-ghost btn-sm" style={{ width: "auto" }} onClick={() => openItem(tab)}>
                <Icon name="plus" size={16} />{window.t(lang, "add")}
              </button>
            </div>
            {(tab === "ing" ? company.ingredients : company.expenses).map((it, i) => (
              <button key={it.id} className="row" style={{ textAlign: "left" }} onClick={() => openItem(tab, it)}>
                <span className="ix">{i + 1}</span>
                <div className="grow">
                  <div style={{ fontWeight: 600 }}>{it.th}</div>
                  <div className="hint">{it.en}{tab === "ing" ? ` · ${it.unit}` : ""}</div>
                </div>
                <Icon name="edit" size={17} style={{ color: "var(--muted)" }} />
              </button>
            ))}
            {(tab === "ing" ? company.ingredients : company.expenses).length === 0 &&
              <div className="card center muted" style={{ padding: 24 }}>{window.t(lang, "emptyItems")}</div>}
          </div>
        )}
      </div>

      {showCo && (
        <CompanySheet data={data}
          session={{ ...session, companyIds: isSysAdmin ? data.companies.map((c) => c.id) : session.companyIds, companyId: company.id }}
          lang={lang} onPick={(id) => { onSwitchCompany(id); setShowCo(false); }} onClose={() => setShowCo(false)}
          /* only System Admin can create companies / branches */
          onAdd={isSysAdmin ? () => { const id = onAddCompany(); onSwitchCompany(id); setShowCo(false); setTab("info"); } : undefined}
          onAddBranch={isSysAdmin ? () => { const id = onAddBranch(company.id); onSwitchCompany(id); setShowCo(false); setTab("info"); } : undefined} />
      )}

      {/* list item editor */}
      {draft && (
        <Sheet onClose={() => setDraft(null)}>
          <div className="h2" style={{ marginBottom: 16 }}>{window.t(lang, draft.kind === "ing" ? "addIngredient" : "addExpense")}</div>
          <div className="stack-lg">
            <Field label={window.t(lang, "nameTh")} required>
              <input className="control" value={draft.th} autoFocus onChange={(e) => setDraft({ ...draft, th: e.target.value })} />
            </Field>
            <Field label={window.t(lang, "nameEn")} required>
              <input className="control" value={draft.en} onChange={(e) => setDraft({ ...draft, en: e.target.value })} />
            </Field>
            {draft.kind === "ing" && (
              <Field label={window.t(lang, "unit")}>
                <input className="control" value={draft.unit} onChange={(e) => setDraft({ ...draft, unit: e.target.value })} placeholder="กก. / kg" />
              </Field>
            )}
            <div className="btn-row">
              {draft.id && <Button variant="danger" onClick={() => { deleteListItem(company.id, draft.kind === "ing" ? "ingredients" : "expenses", draft.id); setDraft(null); }} icon="trash">{window.t(lang, "delete")}</Button>}
              <Button onClick={saveItem} disabled={!draft.th.trim() || !draft.en.trim()}>{window.t(lang, "done")}</Button>
            </div>
          </div>
        </Sheet>
      )}

      {/* user editor */}
      {userDraft && (
        <UserEditSheet company={company} members={members} lang={lang} draft={userDraft}
          canSetAdminRoles={isSysAdmin}
          onChange={setUserDraft}
          onClose={() => setUserDraft(null)}
          onSave={() => {
            // a new member with an email that already exists would hit the UNIQUE(email)
            // constraint — that person should be added via "Add existing user" instead
            if (userDraft.isNew) {
              const dupe = data.users.find((x) => (x.email || "").toLowerCase() === (userDraft.email || "").trim().toLowerCase());
              if (dupe) { alert(window.t(lang, "userExists")); return; }
            }
            const u = {
              id: userDraft.id || "u" + Date.now(),
              name: userDraft.name, title: userDraft.title, email: userDraft.email,
              role: userDraft.role, signature: userDraft.signature || userDraft.name,
              icon: userDraft.icon || (userDraft._sup_role ? "shield" : ROLE_ICONS[userDraft.role]),
              companyIds: Array.from(new Set([...(userDraft.companyIds || []), company.id])),
            };
            upsertUser(u, !!userDraft.isNew);
            if (u.role !== "admin") setApprovers(company.id, u.id, { peer: userDraft._peer || null, supervisor: userDraft._sup || null });
            setUserDraft(null);
          }}
          onRemove={!userDraft.isNew && userDraft.role !== "admin" && (isSysAdmin || userDraft.role === "staff")
            ? () => { setMembership(company.id, userDraft.id, false); setUserDraft(null); } : null} />
      )}

      {/* add an existing user (incl. from another company) to this branch */}
      {addExisting && (
        <AddExistingUserSheet data={data} company={company} members={members} lang={lang}
          draft={addExisting} onChange={setAddExisting} onClose={() => setAddExisting(null)}
          onAdd={(userId, assignment, role) => {
            setMembership(company.id, userId, true);
            if (role !== "admin") setApprovers(company.id, userId, { peer: assignment.peer || null, supervisor: assignment.supervisor || null });
            setAddExisting(null);
          }} />
      )}
    </div>
  );
}

/* ---------- user editor sheet ---------- */
function UserEditSheet({ company, members, lang, draft, canSetAdminRoles, onChange, onSave, onClose, onRemove }) {
  const set = (k, v) => onChange({ ...draft, [k]: v });
  const others = members.filter((m) => m.id !== draft.id);
  const valid = draft.name.trim() && draft.email.trim();
  const isAdmin = draft.role === "admin";
  const roleLabel = (r) => window.t(lang, r === "admin" ? "roleAdmin" : r === "company_admin" ? "roleCompanyAdmin" : "roleStaff");

  return (
    <Sheet onClose={onClose}>
      <div className="h2" style={{ marginBottom: 16 }}>{window.t(lang, draft.isNew ? "addUser" : "editUser")}</div>
      <div className="stack-lg">
        <Field label={window.t(lang, "userName")} required>
          <input className="control" value={draft.name} autoFocus onChange={(e) => set("name", e.target.value)} placeholder="ชื่อ นามสกุล" />
        </Field>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
          <Field label={window.t(lang, "jobTitle")}>
            <input className="control" value={draft.title} onChange={(e) => set("title", e.target.value)} placeholder="พนักงานครัว" />
          </Field>
          <Field label={window.t(lang, "role")}>
            {canSetAdminRoles ? (
              <Select value={draft.role} onChange={(v) => set("role", v)}>
                <option value="staff">{window.t(lang, "roleStaff")}</option>
                <option value="company_admin">{window.t(lang, "roleCompanyAdmin")}</option>
                <option value="admin">{window.t(lang, "roleAdmin")}</option>
              </Select>
            ) : (
              // Company Admins can only add/manage Staff — role shown read-only
              <div className="control" style={{ display: "flex", alignItems: "center", color: "var(--muted)" }}>{roleLabel(draft.role)}</div>
            )}
          </Field>
        </div>
        <Field label={window.t(lang, "email")} required>
          <input className="control" type="email" value={draft.email} onChange={(e) => set("email", e.target.value)} placeholder="name@company.co.th" />
        </Field>

        {!isAdmin && (
          <React.Fragment>
            <hr className="hr" />
            <div>
              <div className="label" style={{ marginBottom: 4 }}>{window.t(lang, "assignApprovers")}</div>
              <p className="hint" style={{ textWrap: "pretty", margin: "0 0 12px" }}>{window.t(lang, "approverHint")}</p>
              <div className="stack">
                <Field label={window.t(lang, "peerApprover")}>
                  <Select value={draft._peer || ""} onChange={(v) => set("_peer", v)}>
                    <option value="">{window.t(lang, "none")}</option>
                    {others.map((m) => <option key={m.id} value={m.id}>{m.name}{m.title ? ` · ${m.title}` : ""}</option>)}
                  </Select>
                </Field>
                <Field label={window.t(lang, "supervisorApprover")}>
                  <Select value={draft._sup || ""} onChange={(v) => set("_sup", v)}>
                    <option value="">{window.t(lang, "none")}</option>
                    {others.map((m) => <option key={m.id} value={m.id}>{m.name}{m.title ? ` · ${m.title}` : ""}</option>)}
                  </Select>
                </Field>
              </div>
            </div>
          </React.Fragment>
        )}
        {isAdmin && (
          <div className="card" style={{ background: "var(--accent-soft)", borderColor: "var(--accent-line)", display: "flex", gap: 10, alignItems: "flex-start" }}>
            <Icon name="shield" size={18} style={{ color: "var(--accent)", flex: "0 0 auto", marginTop: 1 }} />
            <div className="hint" style={{ color: "var(--text-2)", textWrap: "pretty" }}>{window.t(lang, "adminFallback")} — {window.t(lang, "roleDescAdmin")}</div>
          </div>
        )}

        <div className="btn-row">
          {onRemove && <Button variant="danger" onClick={onRemove} icon="trash">{window.t(lang, "remove")}</Button>}
          <Button onClick={onSave} disabled={!valid} icon="check">{window.t(lang, "done")}</Button>
        </div>
      </div>
    </Sheet>
  );
}

/* ---------- add an existing user to the current branch (incl. cross-company) ---------- */
function AddExistingUserSheet({ data, company, members, lang, draft, onChange, onClose, onAdd }) {
  const candidates = data.users.filter((u) => !u.companyIds.includes(company.id));
  const picked = draft.userId ? data.users.find((u) => u.id === draft.userId) : null;
  const set = (k, v) => onChange({ ...draft, [k]: v });

  // short note of where this person already works (first branch + "+N")
  function worksIn(u) {
    const cos = data.companies.filter((c) => u.companyIds.includes(c.id));
    if (!cos.length) return "";
    const first = cos[0];
    const txt = first.code + (first.branch ? " · " + first.branch.split("·")[0].trim() : "");
    return cos.length > 1 ? txt + " +" + (cos.length - 1) : txt;
  }

  return (
    <Sheet onClose={onClose}>
      <div className="h2" style={{ marginBottom: 16 }}>{window.t(lang, "addExistingUser")}</div>
      {!picked ? (
        <div className="stack">
          <p className="hint" style={{ margin: "0 2px 4px", textWrap: "pretty" }}>{window.t(lang, "addExistingHint")}</p>
          {candidates.length === 0 && <div className="card center muted" style={{ padding: 24 }}>{window.t(lang, "noOtherUsers")}</div>}
          {candidates.map((u) => (
            <button key={u.id} className="row" style={{ textAlign: "left" }} onClick={() => onChange({ ...draft, userId: u.id, _peer: "", _sup: "" })}>
              <div className="tile-icon" style={{ width: 40, height: 40, borderRadius: 11, flex: "0 0 auto" }}><Icon name={u.icon || ROLE_ICONS[u.role]} size={18} /></div>
              <div className="grow">
                <div style={{ fontWeight: 600 }} className="truncate">{u.name}</div>
                <div className="hint truncate">{u.title ? u.title + " · " : ""}{worksIn(u)}</div>
              </div>
              <Icon name="plus" size={16} style={{ color: "var(--muted)", flex: "0 0 auto" }} />
            </button>
          ))}
        </div>
      ) : (
        <div className="stack-lg">
          <div className="row" style={{ alignItems: "center" }}>
            <div className="tile-icon" style={{ width: 40, height: 40, borderRadius: 11, flex: "0 0 auto" }}><Icon name={picked.icon || ROLE_ICONS[picked.role]} size={18} /></div>
            <div className="grow">
              <div style={{ fontWeight: 600 }} className="truncate">{picked.name}</div>
              <div className="hint truncate">{picked.email}</div>
            </div>
            <button className="btn btn-ghost btn-sm" style={{ width: "auto" }} onClick={() => onChange({ ...draft, userId: "" })}>{window.t(lang, "change")}</button>
          </div>

          {picked.role !== "admin" ? (
            <React.Fragment>
              <p className="hint" style={{ textWrap: "pretty", margin: 0 }}>{window.t(lang, "approverHint")}</p>
              <Field label={window.t(lang, "peerApprover")}>
                <Select value={draft._peer || ""} onChange={(v) => set("_peer", v)}>
                  <option value="">{window.t(lang, "none")}</option>
                  {members.map((m) => <option key={m.id} value={m.id}>{m.name}{m.title ? ` · ${m.title}` : ""}</option>)}
                </Select>
              </Field>
              <Field label={window.t(lang, "supervisorApprover")}>
                <Select value={draft._sup || ""} onChange={(v) => set("_sup", v)}>
                  <option value="">{window.t(lang, "none")}</option>
                  {members.map((m) => <option key={m.id} value={m.id}>{m.name}{m.title ? ` · ${m.title}` : ""}</option>)}
                </Select>
              </Field>
            </React.Fragment>
          ) : (
            <div className="card" style={{ background: "var(--accent-soft)", borderColor: "var(--accent-line)", display: "flex", gap: 10, alignItems: "flex-start" }}>
              <Icon name="shield" size={18} style={{ color: "var(--accent)", flex: "0 0 auto", marginTop: 1 }} />
              <div className="hint" style={{ color: "var(--text-2)", textWrap: "pretty" }}>{window.t(lang, "adminFallback")}</div>
            </div>
          )}

          <Button onClick={() => onAdd(picked.id, { peer: draft._peer, supervisor: draft._sup }, picked.role)} icon="check">{window.t(lang, "addToBranch")}</Button>
        </div>
      )}
    </Sheet>
  );
}

Object.assign(window, { BackOffice, UserEditSheet, AddExistingUserSheet });
