/* screen-projects.jsx — Project detail: team & rates, budget, invoices
 * → window.QScreens.ProjectDetail
 */
(function () {
  const { useState } = React;
  const Q = window.Q, LIB = window.LIB, Icons = window.Icons;
  const { Icon } = Icons;
  const { AppBar, Card, Money, MoneyDisplay, Kicker, Button, StatusPill, Avatar, EmptyState, IconButton, Sheet, Field, Input, Select, Segmented, Progress, EntityLink } = Q;
  const t = window.t;

  /* Project status → existing pill palette (no new colors). */
  const PILL = { active: "sent", wrap: "partial", done: "paid", onhold: "draft" };
  const STATUSES = ["active", "wrap", "done", "onhold"];

  /* A project rate's unit: hourly when the whole team bills hourly, else day
     (matches screen-clients.jsx; the rate itself has no stored unit). */
  function rateUnit(p) {
    const team = (p && p.team) || [];
    return team.length && team.every(m => (m.unit || "day") === "hour") ? "hour" : "day";
  }

  /* ── Team member row ─────────────────────────────────────────── */
  function MemberRow({ m, currency, last, onRemove }) {
    return (
      <div style={{ display: "flex", alignItems: "center", gap: 12, padding: "13px 16px", borderBottom: last ? "none" : "1px solid var(--color-border)" }}>
        <Avatar name={m.name} size={38} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 14, fontWeight: 600, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{m.name}</div>
          {m.role && <div style={{ fontSize: 12, color: "var(--color-text-3)", marginTop: 1 }}>{m.role}</div>}
        </div>
        <div style={{ textAlign: "right" }}>
          <Money amount={m.rate || 0} currency={currency} size={13.5} cents={false} />
          <div style={{ fontFamily: "var(--font-mono)", fontSize: 10, color: "var(--color-text-3)", marginTop: 1 }}>/ {LIB.unitLabel(m.unit || "day", 1)}</div>
        </div>
        <button onClick={onRemove} aria-label={t("g.remove")} style={{ border: "none", background: "transparent", color: "var(--color-text-3)", cursor: "pointer", padding: 5, display: "flex" }}>
          <Icon name="x" size={15} />
        </button>
      </div>
    );
  }

  /* ── Add team member sheet ───────────────────────────────────── */
  function MemberSheet({ onClose, onAdd, currency }) {
    const [name, setName] = useState("");
    const [role, setRole] = useState("");
    const [rate, setRate] = useState("");
    const [unit, setUnit] = useState("day");
    const sym = (window.CURRENCIES[currency] || {}).symbol;
    return (
      <Sheet open onClose={onClose} height="auto" title={t("proj.addmember")}
        footer={<Button variant="primary" size="lg" full icon="check" disabled={!name.trim()}
          onClick={() => onAdd({ id: LIB.newId("tm"), name: name.trim(), role: role.trim(), rate: Number(rate) || 0, unit })}>{t("g.add")}</Button>}>
        <div style={{ padding: "2px 16px 16px", display: "flex", flexDirection: "column", gap: 14 }}>
          <Field label={t("proj.member.name")}><Input value={name} onChange={e => setName(e.target.value)} placeholder={t("proj.member.ph")} autoFocus /></Field>
          <Field label={t("proj.member.role")}><Input value={role} onChange={e => setRole(e.target.value)} placeholder={t("proj.role.ph")} /></Field>
          <div style={{ display: "flex", gap: 12 }}>
            <Field label={t("proj.member.rate")} style={{ flex: 1.4 }}>
              <div style={{ position: "relative" }}>
                <span style={{ position: "absolute", left: 14, top: "50%", transform: "translateY(-50%)", fontFamily: "var(--font-mono)", fontSize: 15, color: "var(--color-text-3)" }}>{sym}</span>
                <Input value={rate} onChange={e => setRate(e.target.value.replace(/[^\d.]/g, ""))} mono inputMode="decimal" style={{ paddingLeft: 34 }} />
              </div>
            </Field>
            <Field label={t("proj.member.unit")} style={{ flex: 1 }}>
              <Select value={unit} onChange={e => setUnit(e.target.value)}
                options={[{ value: "day", label: LIB.unitLabel("day", 1) }, { value: "hour", label: LIB.unitLabel("hour", 1) }]} />
            </Field>
          </div>
        </div>
      </Sheet>
    );
  }

  /* ── Edit project sheet (name, status, basis, delete) ────────── */
  function EditProjectSheet({ project, currency, onClose, onSave, onDelete }) {
    const [name, setName] = useState(project.name);
    const [status, setStatus] = useState(project.status || "active");
    const [basis, setBasis] = useState(project.rate != null ? "rate" : project.budget != null ? "budget" : "none");
    const [amount, setAmount] = useState(project.rate != null ? String(project.rate) : project.budget != null ? String(project.budget) : "");
    const sym = (window.CURRENCIES[currency] || {}).symbol;
    const save = () => {
      const amt = Number(amount) || 0;
      onSave({
        name: name.trim(), status,
        rate: basis === "rate" ? amt : null,
        budget: basis === "budget" ? amt : null,
      });
    };
    return (
      <Sheet open onClose={onClose} height="auto" title={t("proj.edit")}
        footer={<Button variant="primary" size="lg" full icon="check" disabled={!name.trim()} onClick={save}>{t("g.save")}</Button>}>
        <div style={{ padding: "2px 16px 16px", display: "flex", flexDirection: "column", gap: 14 }}>
          <Field label={t("proj.name")}><Input value={name} onChange={e => setName(e.target.value)} placeholder={t("proj.name.ph")} /></Field>
          <div>
            <Segmented value={status} onChange={setStatus}
              options={STATUSES.map(s => ({ value: s, label: t("proj.status." + s) }))} />
          </div>
          <div>
            <Kicker style={{ marginBottom: 8 }}>{t("proj.basis")}</Kicker>
            <Segmented value={basis} onChange={setBasis}
              options={[{ value: "rate", label: t("proj.basis.rate") }, { value: "budget", label: t("proj.basis.budget") }, { value: "none", label: t("proj.basis.none") }]} />
          </div>
          {basis !== "none" && (
            <Field label={t("man.proj.amount")}>
              <div style={{ position: "relative" }}>
                <span style={{ position: "absolute", left: 14, top: "50%", transform: "translateY(-50%)", fontFamily: "var(--font-mono)", fontSize: 15, color: "var(--color-text-3)" }}>{sym}</span>
                <Input value={amount} onChange={e => setAmount(e.target.value.replace(/[^\d.]/g, ""))} mono inputMode="decimal" style={{ paddingLeft: 34 }} />
              </div>
            </Field>
          )}
          <Button variant="ghost" size="md" full icon="trash" style={{ color: "var(--color-error)", marginTop: 4 }} onClick={onDelete}>{t("proj.delete")}</Button>
        </div>
      </Sheet>
    );
  }

  /* ── Detail ──────────────────────────────────────────────────── */
  function ProjectDetail({ api, id }) {
    const { db, setDb, today } = api;
    const [edit, setEdit] = useState(false);
    const [addMember, setAddMember] = useState(false);
    const found = LIB.getProject(db, id);
    if (!found) return <div><AppBar title={t("proj.title")} onBack={() => api.back()} /><EmptyState icon="briefcase" title={t("g.notfound")} body={t("g.trysearch")} /></div>;
    const { client, project } = found;
    const cur = client.currency || db.COMPANY.currency;
    const team = project.team || [];
    const pb = LIB.projectBudget(db, project);
    const rate = LIB.projectRate(project);
    const over = pb && pb.remaining < 0;
    const invoices = db.INVOICES.filter(i => i.projectId === id).sort((a, b) => new Date(b.issued) - new Date(a.issued));
    const status = project.status || "active";
    /* Get-paid money moment for the project: what's still owed across its real
       invoices (sent/overdue/partial), same predicate as LIB.summary so it ties
       out with Home. One project → one client → one currency (cur). */
    const projOutstanding = LIB.round2(invoices.reduce((s, inv) => {
      if (inv.kind !== "invoice") return s;
      const eff = LIB.effectiveStatus(inv, today);
      if (eff === "draft" || eff === "paid") return s;
      return s + LIB.totals(inv).balance;
    }, 0));

    const patchProject = (fn) => setDb(d => ({
      ...d,
      CLIENTS: d.CLIENTS.map(c => c.id !== client.id ? c : { ...c, projects: (c.projects || []).map(p => p.id !== id ? p : fn(p)) }),
    }));

    const saveProject = (patch) => {
      patchProject(p => ({ ...p, name: patch.name, status: patch.status, rate: patch.rate, budget: patch.budget }));
      setEdit(false);
      Q.toast(t("toast.projectUpdated", { name: patch.name }), "check");
    };
    const deleteProject = () => {
      setEdit(false);
      api.back();
      setDb(d => ({ ...d, CLIENTS: d.CLIENTS.map(c => c.id !== client.id ? c : { ...c, projects: (c.projects || []).filter(p => p.id !== id) }) }));
      Q.toast(t("toast.projectDeleted", { name: project.name }), "trash");
    };
    const addTeamMember = (m) => {
      patchProject(p => ({ ...p, team: [...(p.team || []), m] }));
      setAddMember(false);
      Q.toast(t("toast.added", { name: m.name }), "check");
    };
    const removeTeamMember = (m) => {
      patchProject(p => ({ ...p, team: (p.team || []).filter(x => x.id !== m.id) }));
      Q.toast(t("toast.memberRemoved", { name: m.name }), "x");
    };

    return (
      <div style={{ paddingBottom: 4 }}>
        {/* AppBar carries a stable label (matches invoice/expense detail), not the
            project name — the serif title below owns the name, so the two no longer
            stack as a literal duplicate (detail-header-name-duplicated). */}
        <AppBar title={t("proj.title")} onBack={() => api.back()}
          right={<IconButton name="edit" label={t("proj.edit")} onClick={() => setEdit(true)} />} />
        <div style={{ padding: "4px 16px 0", display: "flex", flexDirection: "column", gap: 16 }}>

          {/* header */}
          <div style={{ display: "flex", alignItems: "center", gap: 14 }}>
            <div style={{ width: 56, height: 56, borderRadius: 16, background: "var(--color-surface-1)", border: "1.4px solid var(--color-border-strong)", display: "flex", alignItems: "center", justifyContent: "center", color: "var(--color-text-3)", flexShrink: 0 }}>
              <Icon name="briefcase" size={24} />
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontFamily: "var(--font-serif)", fontWeight: 600, fontSize: 23, letterSpacing: "-0.01em", lineHeight: 1.1 }}>{project.name}</div>
              <EntityLink kind="client" name={client.name} size={13} style={{ marginTop: 5 }}
                onClick={() => api.go("client", { id: client.id })} />
            </div>
            <StatusPill status={PILL[status] || "draft"} label={t("proj.status." + status)} />
          </div>

          {/* budget / rate */}
          {pb ? (
            <Card pad={18}>
              <Kicker>{t("proj.budget")}</Kicker>
              <div style={{ marginTop: 8 }}><MoneyDisplay amount={pb.budget} currency={cur} size={26} cents={false} animKey={project.id} /></div>
              <div style={{ marginTop: 14 }}><Progress value={pb.billed} max={pb.budget} tone={over ? "accent" : "gold"} /></div>
              <div style={{ display: "flex", justifyContent: "space-between", gap: 10, marginTop: 9 }}>
                <span style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, color: "var(--color-text-3)" }}>
                  {t("proj.budget.used", { billed: window.fmtMoney(pb.billed, cur, { cents: false }), budget: window.fmtMoney(pb.budget, cur, { cents: false }) })}
                </span>
                <span style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, fontWeight: 600, color: over ? "var(--color-accent)" : "var(--color-text-2)", whiteSpace: "nowrap" }}>
                  {over ? t("proj.budget.over", { amount: window.fmtMoney(-pb.remaining, cur, { cents: false }) })
                    : t("proj.budget.remaining", { amount: window.fmtMoney(pb.remaining, cur, { cents: false }) })}
                </span>
              </div>
            </Card>
          ) : rate != null && rate > 0 ? (
            <Card pad={18}>
              <Kicker>{rateUnit(project) === "hour" ? t("proj.member.rate") : t("proj.basis.rate")}</Kicker>
              <div style={{ marginTop: 8, fontFamily: "var(--font-mono)", fontSize: 22, fontWeight: 600, color: "var(--color-gold)", fontVariantNumeric: "tabular-nums" }}>
                {rateUnit(project) === "hour"
                  ? window.fmtMoney(rate, cur, { cents: false }) + "/" + t("unit.hour")
                  : t("cl.proj.rate", { rate: window.fmtMoney(rate, cur, { cents: false }) })}
              </div>
            </Card>
          ) : null}

          <Button variant="primary" size="lg" full icon="plus" onClick={() => api.openManual({ clientId: client.id, projectId: id })}>{t("proj.newinvoice")}</Button>

          {/* team & rates */}
          <div>
            <div style={{ display: "flex", alignItems: "center", marginBottom: 10 }}>
              <div style={{ flex: 1, display: "flex", alignItems: "baseline", gap: 7 }}>
                <Kicker>{t("proj.team")}</Kicker>
                {team.length > 0 && <span style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--color-text-3)", fontVariantNumeric: "tabular-nums" }}>{team.length}</span>}
              </div>
              <button onClick={() => setAddMember(true)} style={{ display: "flex", alignItems: "center", gap: 5, background: "none", border: "none", color: "var(--color-primary)", fontSize: 13, fontWeight: 600, cursor: "pointer", padding: 0 }}>
                <Icon name="userPlus" size={15} />{t("proj.addmember")}
              </button>
            </div>
            {team.length === 0 ? (
              <Card dashed pad={18} style={{ textAlign: "center" }}>
                <div style={{ fontSize: 14, fontWeight: 600 }}>{t("proj.team.empty")}</div>
                <div style={{ fontSize: 12.5, color: "var(--color-text-3)", lineHeight: 1.5, marginTop: 4 }}>{t("proj.team.note")}</div>
              </Card>
            ) : (
              <>
                <Card pad={0}>
                  {team.map((m, i) => (
                    <MemberRow key={m.id} m={m} currency={cur} last={i === team.length - 1} onRemove={() => removeTeamMember(m)} />
                  ))}
                </Card>
                <div style={{ fontSize: 12, color: "var(--color-text-3)", lineHeight: 1.5, marginTop: 8 }}>{t("proj.team.note")}</div>
              </>
            )}
          </div>

          {/* billing history (invoices, quotes and credit notes share this list,
              so the heading uses the same mixed-kind label as client detail) */}
          <div>
            <div style={{ display: "flex", alignItems: "baseline", gap: 7, marginBottom: 10 }}>
              <Kicker>{t("cl.history")}</Kicker>
              {invoices.length > 0 && <span style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--color-text-3)", fontVariantNumeric: "tabular-nums" }}>{invoices.length}</span>}
              {/* Get-paid signal: what this project still owes, gold like the
                 client-detail balance so "what's unpaid" pops while scanning. */}
              {projOutstanding > 0 && (
                <span style={{ marginLeft: "auto", display: "inline-flex", alignItems: "baseline", gap: 6 }}>
                  <span style={{ fontFamily: "var(--font-mono)", fontSize: 10, fontWeight: 600, letterSpacing: "0.10em", textTransform: "uppercase", color: "var(--color-text-3)" }}>{t("home.outstanding")}</span>
                  <Money amount={projOutstanding} currency={cur} size={14} cents={false} color="var(--color-gold)" />
                </span>
              )}
            </div>
            {invoices.length === 0 ? (
              <Card pad={20}><div style={{ textAlign: "center", color: "var(--color-text-3)", fontSize: 13.5 }}>{t("cl.never")}</div></Card>
            ) : (
              <Card pad={0}>
                {invoices.map((inv, i) => {
                  const tot = LIB.totals(inv);
                  const eff = LIB.effectiveStatus(inv, today);
                  return (
                    <Q.Row key={inv.id} onClick={() => api.go("invoice", { id: inv.id })} last={i === invoices.length - 1}>
                      <div style={{ flex: 1 }}>
                        <div style={{ fontFamily: "var(--font-mono)", fontSize: 13, fontWeight: 600 }}>{inv.id}</div>
                        <div style={{ fontSize: 12, color: "var(--color-text-3)", marginTop: 1 }}>{window.fmtDate(inv.issued, "short")}</div>
                      </div>
                      <div style={{ textAlign: "right", display: "flex", flexDirection: "column", alignItems: "flex-end", gap: 5 }}>
                        <Money amount={LIB.docSign(inv) * tot.total} currency={inv.currency} size={14} cents={false} />
                        <StatusPill status={eff} solid />
                      </div>
                    </Q.Row>
                  );
                })}
              </Card>
            )}
          </div>
        </div>

        {edit && <EditProjectSheet project={project} currency={cur} onClose={() => setEdit(false)} onSave={saveProject} onDelete={deleteProject} />}
        {addMember && <MemberSheet currency={cur} onClose={() => setAddMember(false)} onAdd={addTeamMember} />}
      </div>
    );
  }

  window.QScreens = Object.assign(window.QScreens || {}, { ProjectDetail });
})();
