// inquiries.jsx — lodge / list / rate (customer) + manage / respond / performance (CE). Loaded by both apps.
const { useState: useStateInq, useMemo: useMemoInq } = React;

function InquiryStatusPill({ status }) {
  const m = window.FX.INQUIRY_STATUS[status] || { label: status, tone: "neutral", dot: "var(--fg-faint)" };
  return <Badge tone={m.tone}><StatusDot color={m.dot} pulse={status === "in-progress"} /> {m.label}</Badge>;
}

function StarRating({ value, onRate, size = 18, readOnly }) {
  const [hover, setHover] = useStateInq(0);
  return (
    <span style={{ display: "inline-flex", gap: 2 }}>
      {[1, 2, 3, 4, 5].map(n => {
        const on = (hover || value || 0) >= n;
        return <button key={n} disabled={readOnly} onMouseEnter={() => !readOnly && setHover(n)} onMouseLeave={() => !readOnly && setHover(0)} onClick={() => !readOnly && onRate && onRate(n)} style={{ background: "none", border: "none", padding: 0, cursor: readOnly ? "default" : "pointer", lineHeight: 0, color: on ? "var(--accent)" : "var(--border-strong)" }}><Icon name="star" size={size} /></button>;
      })}
    </span>
  );
}

/* Customer lodges an inquiry against one shipment (item 5–6). */
function LodgeInquiryModal({ open, onClose, shipment, onLodge }) {
  const [type, setType] = useStateInq(window.FX.INQUIRY_TYPES[0]);
  const [message, setMessage] = useStateInq("");
  React.useEffect(() => { if (open) { setType(window.FX.INQUIRY_TYPES[0]); setMessage(""); } }, [open]);
  return (
    <Modal open={open} onClose={onClose} title="Lodge an inquiry" width={520}>
      <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
        {shipment && (
          <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "11px 13px", background: "var(--bg-mist)", borderRadius: "var(--r-md)" }}>
            <Icon name="package" size={16} color="var(--brand)" />
            <div style={{ minWidth: 0 }}>
              <div style={{ fontFamily: "var(--font-mono)", fontSize: 12.5, fontWeight: 600, color: "var(--brand)" }}>{shipment.id}</div>
              <div style={{ fontSize: 12, color: "var(--fg-mute)" }}>{shipment.from} → {shipment.to}</div>
            </div>
          </div>
        )}
        <Field label="Query type"><Select value={type} onChange={setType} options={window.FX.INQUIRY_TYPES} /></Field>
        <Field label="Describe the issue"><textarea value={message} onChange={e => setMessage(e.target.value)} rows={4} placeholder="Tell us what's happening…" style={{ ...inputStyle, resize: "vertical", fontSize: 13.5, lineHeight: 1.5 }} /></Field>
        <div style={{ fontSize: 12, color: "var(--fg-body)", display: "flex", gap: 8, alignItems: "flex-start", background: "var(--brand-soft)", padding: "10px 12px", borderRadius: "var(--r-sm)" }}>
          <Icon name="info" size={14} color="var(--brand)" style={{ flex: "none", marginTop: 1 }} /> We'll send this to Customer Service, generate a reference number, and email you each update.
        </div>
        <div style={{ display: "flex", justifyContent: "flex-end", gap: 10 }}>
          <Button variant="ghost" onClick={onClose}>Cancel</Button>
          <Button variant="primary" icon="send" disabled={!message.trim()} onClick={() => onLodge({ type, message: message.trim(), shipment })}>Lodge inquiry</Button>
        </div>
      </div>
    </Modal>
  );
}

function InquiryThread({ inq }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
      <div style={{ display: "flex", gap: 10 }}>
        <span style={{ width: 30, height: 30, borderRadius: "50%", flex: "none", background: "var(--bg-mist-2)", color: "var(--fg-mute)", display: "inline-flex", alignItems: "center", justifyContent: "center", fontWeight: 700, fontSize: 11 }}>{(inq.customerName || "C").slice(0, 2).toUpperCase()}</span>
        <div style={{ flex: 1, background: "var(--bg-mist)", borderRadius: "var(--r-md)", padding: "10px 13px" }}>
          <div style={{ display: "flex", justifyContent: "space-between", gap: 8 }}><span style={{ fontSize: 12.5, fontWeight: 700, color: "var(--fg-strong)" }}>{inq.customerName}</span><span style={{ fontSize: 11, color: "var(--fg-faint)", fontFamily: "var(--font-mono)" }}>{new Date(inq.createdAt).toLocaleDateString("en-AU", { day: "numeric", month: "short" })}</span></div>
          <div style={{ fontSize: 11.5, color: "var(--accent-700)", fontWeight: 600, margin: "2px 0 4px" }}>{inq.type}</div>
          <div style={{ fontSize: 13.5, color: "var(--fg-body)", lineHeight: 1.5 }}>{inq.message}</div>
        </div>
      </div>
      {(inq.comments || []).map((c, i) => (
        <div key={i} style={{ display: "flex", gap: 10, flexDirection: c.role === "agent" ? "row-reverse" : "row" }}>
          <span style={{ width: 30, height: 30, borderRadius: "50%", flex: "none", background: c.role === "agent" ? "var(--brand)" : "var(--bg-mist-2)", color: c.role === "agent" ? "#fff" : "var(--fg-mute)", display: "inline-flex", alignItems: "center", justifyContent: "center", fontWeight: 700, fontSize: 11 }}>{(c.author || "A").split(/\s+/).map(w => w[0]).slice(0, 2).join("").toUpperCase()}</span>
          <div style={{ flex: 1, background: c.role === "agent" ? "var(--brand-soft)" : "var(--bg-mist)", borderRadius: "var(--r-md)", padding: "10px 13px" }}>
            <div style={{ display: "flex", justifyContent: "space-between", gap: 8 }}><span style={{ fontSize: 12.5, fontWeight: 700, color: "var(--fg-strong)" }}>{c.author} <span style={{ fontWeight: 400, color: "var(--fg-mute)" }}>· Customer Service</span></span><span style={{ fontSize: 11, color: "var(--fg-faint)", fontFamily: "var(--font-mono)" }}>{new Date(c.at).toLocaleDateString("en-AU", { day: "numeric", month: "short" })}</span></div>
            <div style={{ fontSize: 13.5, color: "var(--fg-body)", lineHeight: 1.5, marginTop: 4 }}>{c.body}</div>
          </div>
        </div>
      ))}
    </div>
  );
}

/* ---------------- Customer: my inquiries ---------------- */
function CustomerInquiries({ inquiries, onRate, nav }) {
  const [open, setOpen] = useStateInq(null);
  const list = inquiries || [];
  return (
    <div className="fade-up">
      <PageHeader eyebrow="Support" title="My inquiries" sub="Track the inquiries you've lodged and their status. We email you each time we respond." />
      {list.length === 0 ? (
        <Card pad={44} style={{ textAlign: "center", borderStyle: "dashed", background: "var(--bg-mist)" }}>
          <div style={{ width: 54, height: 54, borderRadius: "50%", background: "var(--surface)", display: "inline-flex", alignItems: "center", justifyContent: "center", margin: "0 auto 12px", color: "var(--fg-faint)" }}><Icon name="headset" size={24} /></div>
          <div style={{ fontSize: 15, fontWeight: 600, color: "var(--fg-strong)" }}>No inquiries yet</div>
          <div style={{ fontSize: 13.5, color: "var(--fg-mute)", marginTop: 5 }}>Lodge one from any shipment in your delivery history.</div>
          <Button variant="secondary" size="sm" icon="history" onClick={() => nav("history")} style={{ marginTop: 14 }}>Go to history</Button>
        </Card>
      ) : (
        <Card pad={0} style={{ overflow: "hidden" }}>
          {list.map((inq, i) => (
            <div key={inq.ref} onClick={() => setOpen(inq)} style={{ display: "flex", alignItems: "center", gap: 14, padding: "15px 22px", borderTop: i ? "1px solid var(--border)" : "none", cursor: "pointer" }}
              onMouseEnter={e => e.currentTarget.style.background = "var(--bg-mist)"} onMouseLeave={e => e.currentTarget.style.background = "transparent"}>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                  <span style={{ fontFamily: "var(--font-mono)", fontSize: 12.5, fontWeight: 700, color: "var(--brand)" }}>{inq.ref}</span>
                  <span style={{ fontSize: 13.5, fontWeight: 600, color: "var(--fg-strong)" }}>{inq.type}</span>
                </div>
                <div style={{ fontSize: 12, color: "var(--fg-mute)", marginTop: 2 }}><span style={{ fontFamily: "var(--font-mono)" }}>{inq.tracking}</span> · lodged {new Date(inq.createdAt).toLocaleDateString("en-AU", { day: "numeric", month: "short" })}{inq.comments && inq.comments.length ? " · " + inq.comments.length + " reply" + (inq.comments.length === 1 ? "" : "s") : ""}</div>
              </div>
              {inq.status === "resolved" && (inq.rating ? <span style={{ display: "flex", alignItems: "center", gap: 4 }}><StarRating value={inq.rating} readOnly size={14} /></span> : <Badge tone="accent">Rate it</Badge>)}
              <InquiryStatusPill status={inq.status} />
              <Icon name="chevron-right" size={16} color="var(--fg-faint)" />
            </div>
          ))}
        </Card>
      )}

      <Modal open={!!open} onClose={() => setOpen(null)} title={open ? "Inquiry " + open.ref : ""} width={560}>
        {open && (
          <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
            <div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
              <InquiryStatusPill status={open.status} />
              <span style={{ fontSize: 12.5, color: "var(--fg-mute)", fontFamily: "var(--font-mono)" }}>{open.tracking}</span>
            </div>
            <InquiryThread inq={open} />
            {open.status === "resolved" && (
              <div style={{ padding: "14px 16px", background: "var(--bg-mist)", borderRadius: "var(--r-md)", textAlign: "center" }}>
                <div style={{ fontSize: 13.5, fontWeight: 600, color: "var(--fg-strong)", marginBottom: 8 }}>{open.rating ? "Thanks for rating this inquiry" : "How was this inquiry handled?"}</div>
                <StarRating value={open.rating} size={26} readOnly={!!open.rating} onRate={n => { onRate(open.ref, n); setOpen({ ...open, rating: n }); }} />
              </div>
            )}
          </div>
        )}
      </Modal>
    </div>
  );
}

/* ---------------- CE: inquiries management + performance ---------------- */
function rangeBounds(r, from, to) {
  const now = new Date();
  if (r === "this") return [new Date(now.getFullYear(), now.getMonth(), 1), new Date(now.getFullYear(), now.getMonth() + 1, 1)];
  if (r === "last") return [new Date(now.getFullYear(), now.getMonth() - 1, 1), new Date(now.getFullYear(), now.getMonth(), 1)];
  if (r === "30") { const s = new Date(now); s.setDate(s.getDate() - 30); return [s, new Date(now.getTime() + 864e5)]; }
  if (r === "custom") return [from ? new Date(from) : new Date(0), to ? new Date(new Date(to).getTime() + 864e5) : new Date(now.getTime() + 864e5)];
  return [new Date(0), new Date(now.getTime() + 864e5)];
}

function CsrInquiries({ inquiries, users = [], currentUser = {}, customers = [], bookings = [], onCreate, onRespond, onSetStatus, onAssign, onNotify }) {
  const [view, setView] = useStateInq("list");   // list | perf
  const [newOpen, setNewOpen] = useStateInq(false);
  const [filter, setFilter] = useStateInq("all");
  const [custQuery, setCustQuery] = useStateInq("");
  const [userFilter, setUserFilter] = useStateInq("all");
  const [range, setRange] = useStateInq("this");
  const [rFrom, setRFrom] = useStateInq("");
  const [rTo, setRTo] = useStateInq("");
  const [open, setOpen] = useStateInq(null);
  const [reply, setReply] = useStateInq("");

  const canViewPerf = ["admin", "finance"].includes(currentUser.roleId);
  const activeUsers = users.filter(u => u.active);
  const openCount = inquiries.filter(i => i.status === "in-progress").length;
  const resolvedCount = inquiries.filter(i => i.status === "resolved").length;
  const rated = inquiries.filter(i => i.rating);
  const avg = rated.length ? (rated.reduce((s, i) => s + i.rating, 0) / rated.length) : 0;

  const filtered = inquiries.filter(i => {
    if (filter !== "all" && i.status !== filter) return false;
    if (userFilter === "unassigned" && i.assignedTo) return false;
    if (userFilter !== "all" && userFilter !== "unassigned" && i.assignedTo !== userFilter) return false;
    if (custQuery.trim()) { const q = custQuery.trim().toLowerCase(); if (!((i.customerName || "").toLowerCase().includes(q) || (i.tracking || "").toLowerCase().includes(q))) return false; }
    return true;
  });

  const openInq = open ? inquiries.find(i => i.ref === open) : null;

  function sendReply() {
    if (!reply.trim() || !openInq) return;
    onRespond(openInq.ref, reply.trim());
    onNotify && onNotify(`Reply emailed to ${openInq.customerName}`);
    setReply("");
  }

  // performance by agent, within the selected date range
  const [rStart, rEnd] = rangeBounds(range, rFrom, rTo);
  const ratedInRange = rated.filter(i => { const d = new Date(i.updatedAt || i.createdAt); return d >= rStart && d < rEnd; });
  const avgRange = ratedInRange.length ? ratedInRange.reduce((s, i) => s + i.rating, 0) / ratedInRange.length : 0;
  const resolvedInRange = inquiries.filter(i => { if (i.status !== "resolved") return false; const d = new Date(i.updatedAt || i.createdAt); return d >= rStart && d < rEnd; }).length;
  const byAgent = useMemoInq(() => {
    const m = {};
    ratedInRange.forEach(i => { const a = i.agent || i.assignedName || "—"; (m[a] = m[a] || []).push(i.rating); });
    return Object.keys(m).map(a => ({ agent: a, n: m[a].length, avg: m[a].reduce((s, x) => s + x, 0) / m[a].length })).sort((x, y) => y.avg - x.avg);
  }, [inquiries, range, rFrom, rTo]);

  const rangeLabel = { this: "This month", last: "Last month", "30": "Last 30 days", all: "All time", custom: "Custom range" }[range];

  return (
    <div className="fade-up">
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", gap: 16, marginBottom: 18, flexWrap: "wrap" }}>
        <div>
          <Eyebrow>Customer service</Eyebrow>
          <h1 style={{ margin: "9px 0 0", fontSize: 25, fontWeight: 700, letterSpacing: "-0.6px", color: "var(--fg-strong)" }}>Inquiries</h1>
          <p style={{ margin: "7px 0 0", fontSize: 14.5, color: "var(--fg-mute)" }}>Every inquiry lodged by customers, with status, owner and responses.</p>
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
          <Button variant="primary" icon="plus" onClick={() => setNewOpen(true)}>New inquiry</Button>
          <div style={{ display: "inline-flex", gap: 6, background: "var(--bg-mist)", padding: 4, borderRadius: "var(--r-pill)" }}>
            {[["list", "Inbox"], ["perf", "Performance"]].map(([k, l]) => (
              <button key={k} onClick={() => setView(k)} style={{ display: "inline-flex", alignItems: "center", gap: 6, padding: "7px 14px", borderRadius: "var(--r-pill)", border: "none", fontSize: 13, fontWeight: 600, background: view === k ? "var(--surface)" : "transparent", color: view === k ? "var(--brand)" : "var(--fg-mute)", boxShadow: view === k ? "var(--shadow-xs)" : "none" }}>{k === "perf" && !canViewPerf && <Icon name="shield" size={13} />}{l}</button>
            ))}
          </div>
        </div>
      </div>

      {/* mini dashboard */}
      <div style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 14, marginBottom: 18 }}>
        <Card pad={18}><div style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, letterSpacing: "0.8px", textTransform: "uppercase", color: "var(--fg-mute)" }}>Open</div><div style={{ fontSize: 30, fontWeight: 900, color: "var(--warn)", marginTop: 6 }}>{openCount}</div></Card>
        <Card pad={18}><div style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, letterSpacing: "0.8px", textTransform: "uppercase", color: "var(--fg-mute)" }}>Resolved</div><div style={{ fontSize: 30, fontWeight: 900, color: "var(--success, #1f8a5b)", marginTop: 6 }}>{resolvedCount}</div></Card>
        <Card pad={18} hover={canViewPerf} onClick={canViewPerf ? () => setView("perf") : undefined}><div style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, letterSpacing: "0.8px", textTransform: "uppercase", color: "var(--fg-mute)" }}>Avg rating</div><div style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 6 }}><div style={{ fontSize: 30, fontWeight: 900, color: "var(--fg-strong)" }}>{avg ? avg.toFixed(1) : "—"}</div><StarRating value={Math.round(avg)} readOnly size={15} /></div></Card>
      </div>

      {view === "list" ? (
        <React.Fragment>
          <div style={{ display: "flex", gap: 10, marginBottom: 12, flexWrap: "wrap", alignItems: "center" }}>
            <div style={{ display: "flex", gap: 6 }}>
              {[["all", "All"], ["in-progress", "In progress"], ["resolved", "Resolved"]].map(([k, l]) => (
                <button key={k} onClick={() => setFilter(k)} style={{ padding: "7px 14px", borderRadius: "var(--r-pill)", fontSize: 12.5, fontWeight: 500, border: "1px solid " + (filter === k ? "var(--brand)" : "var(--border)"), background: filter === k ? "var(--brand-soft)" : "var(--surface)", color: filter === k ? "var(--brand)" : "var(--fg-mute)" }}>{l}</button>
              ))}
            </div>
            <div style={{ position: "relative", flex: "1 1 220px", minWidth: 180 }}>
              <span style={{ position: "absolute", left: 11, top: "50%", transform: "translateY(-50%)", color: "var(--fg-mute)" }}><Icon name="search" size={14} /></span>
              <input value={custQuery} onChange={e => setCustQuery(e.target.value)} placeholder="Search customer or tracking…" style={{ ...inputStyle, paddingLeft: 34, paddingTop: 8, paddingBottom: 8, fontSize: 13 }} />
            </div>
            <div style={{ minWidth: 170 }}>
              <Select value={userFilter} onChange={setUserFilter} style={{ paddingTop: 8, paddingBottom: 8, fontSize: 13 }} options={[{ value: "all", label: "All owners" }, { value: "unassigned", label: "Unassigned" }, ...activeUsers.map(u => ({ value: u.id, label: u.name }))]} />
            </div>
          </div>
          <Card pad={0} style={{ overflow: "hidden" }}>
            {filtered.map((inq, i) => (
              <div key={inq.ref} onClick={() => { setOpen(inq.ref); setReply(""); }} style={{ display: "flex", alignItems: "center", gap: 14, padding: "14px 20px", borderTop: i ? "1px solid var(--border)" : "none", cursor: "pointer" }}
                onMouseEnter={e => e.currentTarget.style.background = "var(--bg-mist)"} onMouseLeave={e => e.currentTarget.style.background = "transparent"}>
                <span style={{ fontFamily: "var(--font-mono)", fontSize: 12.5, fontWeight: 700, color: "var(--brand)", width: 96, flex: "none" }}>{inq.ref}</span>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 13.5, fontWeight: 600, color: "var(--fg-strong)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{inq.customerName} · {inq.type}</div>
                  <div style={{ fontSize: 12, color: "var(--fg-mute)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}><span style={{ fontFamily: "var(--font-mono)" }}>{inq.tracking}</span> · {inq.message}</div>
                </div>
                {inq.assignedName
                  ? <span title={"Assigned to " + inq.assignedName} style={{ display: "inline-flex", alignItems: "center", gap: 6, flex: "none", background: "var(--brand-soft)", borderRadius: "var(--r-pill)", padding: "3px 10px 3px 4px" }}><span style={{ width: 20, height: 20, borderRadius: "50%", background: "var(--brand)", color: "#fff", display: "inline-flex", alignItems: "center", justifyContent: "center", fontWeight: 700, fontSize: 9 }}>{inq.assignedName.split(/\s+/).map(w => w[0]).slice(0, 2).join("").toUpperCase()}</span><span style={{ fontSize: 11.5, fontWeight: 600, color: "var(--brand)" }}>{inq.assignedName.split(/\s+/)[0]}</span></span>
                  : <Badge tone="neutral">Unassigned</Badge>}
                {inq.rating && <StarRating value={inq.rating} readOnly size={13} />}
                <InquiryStatusPill status={inq.status} />
              </div>
            ))}
            {filtered.length === 0 && <div style={{ padding: 36, textAlign: "center", fontSize: 13.5, color: "var(--fg-mute)" }}>No inquiries match these filters.</div>}
          </Card>
        </React.Fragment>
      ) : !canViewPerf ? (
        <Card pad={48} style={{ textAlign: "center", borderStyle: "dashed", background: "var(--bg-mist)" }}>
          <div style={{ width: 56, height: 56, borderRadius: "50%", background: "var(--surface)", display: "inline-flex", alignItems: "center", justifyContent: "center", margin: "0 auto 14px", color: "var(--fg-faint)" }}><Icon name="shield" size={26} /></div>
          <div style={{ fontSize: 15.5, fontWeight: 600, color: "var(--fg-strong)" }}>Performance is restricted</div>
          <div style={{ fontSize: 13.5, color: "var(--fg-mute)", marginTop: 5, maxWidth: 420, marginInline: "auto" }}>The performance report is available to Administrator and Finance roles only. You're signed in as {(window.FX.roleById(currentUser.roleId) || {}).label || "Operator"}.</div>
        </Card>
      ) : (
        <Card pad={22}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 16, flexWrap: "wrap", marginBottom: 16 }}>
            <div>
              <div style={{ fontSize: 15, fontWeight: 700, color: "var(--fg-strong)" }}>Team performance</div>
              <div style={{ fontSize: 13, color: "var(--fg-mute)", marginTop: 4 }}>{rangeLabel} · average <strong style={{ color: "var(--fg-strong)" }}>{avgRange ? avgRange.toFixed(2) : "—"}</strong> from {ratedInRange.length} rated · {resolvedInRange} resolved</div>
            </div>
            <div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
              {[["this", "This month"], ["last", "Last month"], ["30", "30 days"], ["all", "All time"], ["custom", "Custom"]].map(([k, l]) => (
                <button key={k} onClick={() => setRange(k)} style={{ padding: "6px 12px", borderRadius: "var(--r-pill)", fontSize: 12, fontWeight: 500, border: "1px solid " + (range === k ? "var(--brand)" : "var(--border)"), background: range === k ? "var(--brand-soft)" : "var(--surface)", color: range === k ? "var(--brand)" : "var(--fg-mute)" }}>{l}</button>
              ))}
            </div>
          </div>
          {range === "custom" && (
            <div style={{ display: "flex", gap: 12, marginBottom: 18, alignItems: "end", flexWrap: "wrap" }}>
              <Field label="From"><TextInput type="date" value={rFrom} onChange={setRFrom} /></Field>
              <Field label="To"><TextInput type="date" value={rTo} onChange={setRTo} /></Field>
            </div>
          )}
          <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
            {byAgent.map(a => (
              <div key={a.agent} style={{ display: "flex", alignItems: "center", gap: 14 }}>
                <span style={{ width: 150, flex: "none", fontSize: 13.5, fontWeight: 600, color: "var(--fg-strong)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{a.agent} <span style={{ color: "var(--fg-mute)", fontWeight: 400, fontFamily: "var(--font-mono)", fontSize: 11.5 }}>({a.n})</span></span>
                <div style={{ flex: 1, height: 10, background: "var(--bg-mist)", borderRadius: 999, overflow: "hidden" }}><div style={{ width: (a.avg / 5 * 100) + "%", height: "100%", background: "var(--accent)", borderRadius: 999 }} /></div>
                <span style={{ display: "flex", alignItems: "center", gap: 6, width: 92, flex: "none", justifyContent: "flex-end" }}><StarRating value={Math.round(a.avg)} readOnly size={13} /><span style={{ fontFamily: "var(--font-mono)", fontSize: 12.5, fontWeight: 700, color: "var(--fg-strong)" }}>{a.avg.toFixed(1)}</span></span>
              </div>
            ))}
            {byAgent.length === 0 && <div style={{ fontSize: 13.5, color: "var(--fg-mute)", padding: "8px 0" }}>No ratings in {rangeLabel.toLowerCase()}.</div>}
          </div>
        </Card>
      )}

      {/* respond drawer */}
      <Modal open={!!openInq} onClose={() => setOpen(null)} title={openInq ? "Inquiry " + openInq.ref : ""} width={580}>
        {openInq && (
          <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
            <div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
              <InquiryStatusPill status={openInq.status} />
              <span style={{ fontSize: 12.5, color: "var(--fg-mute)", fontFamily: "var(--font-mono)" }}>{openInq.tracking}</span>
              <span style={{ fontSize: 12.5, color: "var(--fg-mute)" }}>· {openInq.customerEmail}</span>
              {openInq.rating && <span style={{ marginLeft: "auto" }}><StarRating value={openInq.rating} readOnly size={14} /></span>}
            </div>
            {/* Assignment (allocate / reassign) */}
            <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "11px 13px", background: "var(--bg-mist)", borderRadius: "var(--r-md)" }}>
              <Icon name="user" size={15} color="var(--brand)" />
              <span style={{ fontSize: 13, fontWeight: 600, color: "var(--fg-strong)", flex: "none" }}>{openInq.assignedTo ? "Assigned to" : "Allocate to"}</span>
              <div style={{ flex: 1, minWidth: 0 }}>
                <Select value={openInq.assignedTo || ""} onChange={v => onAssign(openInq.ref, v || null)} placeholder="Unassigned — choose a user…" options={activeUsers.map(u => ({ value: u.id, label: u.name + " · " + ((window.FX.roleById(u.roleId) || {}).label || "") }))} style={{ paddingTop: 8, paddingBottom: 8, fontSize: 13 }} />
              </div>
              {openInq.assignedTo && <button onClick={() => onAssign(openInq.ref, null)} title="Unassign" style={{ background: "none", border: "1px solid var(--border)", borderRadius: 8, padding: "7px 10px", fontSize: 12.5, color: "var(--fg-mute)", cursor: "pointer", flex: "none" }}>Clear</button>}
            </div>
            <InquiryThread inq={openInq} />
            {openInq.status !== "resolved" && (
              <div style={{ borderTop: "1px solid var(--border)", paddingTop: 14 }}>
                <Field label="Reply to customer"><textarea value={reply} onChange={e => setReply(e.target.value)} rows={3} placeholder="Type your response — this emails the customer…" style={{ ...inputStyle, resize: "vertical", fontSize: 13.5, lineHeight: 1.5 }} /></Field>
                <div style={{ display: "flex", gap: 10, marginTop: 12, flexWrap: "wrap" }}>
                  <Button variant="primary" icon="send" disabled={!reply.trim()} onClick={sendReply}>Send reply &amp; email</Button>
                  <Button variant="secondary" icon="check-circle" onClick={() => { if (reply.trim()) onRespond(openInq.ref, reply.trim()); onSetStatus(openInq.ref, "resolved"); onNotify && onNotify(`Inquiry ${openInq.ref} resolved`); setReply(""); }}>Resolve</Button>
                </div>
              </div>
            )}
            {openInq.status === "resolved" && (
              <div style={{ display: "flex", justifyContent: "flex-end" }}>
                <Button variant="ghost" icon="repeat" onClick={() => onSetStatus(openInq.ref, "in-progress")}>Reopen</Button>
              </div>
            )}
          </div>
        )}
      </Modal>
      <NewInquiryModal open={newOpen} onClose={() => setNewOpen(false)} customers={customers} bookings={bookings} onCreate={p => { onCreate && onCreate(p); setNewOpen(false); }} />
    </div>
  );
}

/* CE creates an inquiry against a customer, optionally tied to one of their bookings. */
function NewInquiryModal({ open, onClose, customers, bookings, onCreate }) {
  const [customerId, setCustomerId] = useStateInq("");
  const [tracking, setTracking] = useStateInq("");
  const [type, setType] = useStateInq(window.FX.INQUIRY_TYPES[0]);
  const [message, setMessage] = useStateInq("");
  React.useEffect(() => { if (open) { setCustomerId(""); setTracking(""); setType(window.FX.INQUIRY_TYPES[0]); setMessage(""); } }, [open]);
  const cust = customers.find(c => c.id === customerId) || null;
  const custBookings = cust ? bookings.filter(b => b.customerId === cust.id || b.customerName === cust.name) : [];
  const bookingOpts = custBookings.map(b => ({ value: b.tracking, label: `${b.tracking} · ${b.pickup ? b.pickup.suburb : "?"} → ${b.dropoff ? b.dropoff.suburb : "?"} · ${b.status}` }));
  const ok = cust && message.trim();
  return (
    <Modal open={open} onClose={onClose} title="New inquiry" width={540}>
      <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
        <div style={{ display: "flex", gap: 8, alignItems: "flex-start", background: "var(--brand-soft)", padding: "10px 12px", borderRadius: "var(--r-sm)" }}>
          <Icon name="headset" size={15} color="var(--brand)" style={{ flex: "none", marginTop: 1 }} />
          <span style={{ fontSize: 12.5, color: "var(--fg-body)", lineHeight: 1.45 }}>Log an inquiry on a customer's behalf. Tie it to one of their bookings, or leave it as a general inquiry against the customer.</span>
        </div>
        <Field label="Customer *">
          <Select value={customerId} onChange={v => { setCustomerId(v); setTracking(""); }} placeholder="Select a customer…" options={customers.map(c => ({ value: c.id, label: c.name + (c.ref ? " · " + c.ref : "") }))} />
        </Field>
        <Field label="Against a booking (optional)" hint={cust ? (custBookings.length ? "Choose one of this customer's bookings, or leave blank for a general inquiry." : "This customer has no bookings on file — it'll be a general inquiry.") : "Pick a customer first to list their bookings."}>
          <Select value={tracking} onChange={setTracking} placeholder="General inquiry — no specific booking" options={bookingOpts} disabled={!cust || custBookings.length === 0} />
        </Field>
        <Field label="Query type"><Select value={type} onChange={setType} options={window.FX.INQUIRY_TYPES} /></Field>
        <Field label="Details *"><textarea value={message} onChange={e => setMessage(e.target.value)} rows={4} placeholder="What's the inquiry about?…" style={{ ...inputStyle, resize: "vertical", fontSize: 13.5, lineHeight: 1.5 }} /></Field>
        <div style={{ display: "flex", justifyContent: "flex-end", gap: 10 }}>
          <Button variant="ghost" onClick={onClose}>Cancel</Button>
          <Button variant="primary" icon="check" disabled={!ok} onClick={() => onCreate({ customerId: cust.id, tracking: tracking || "", type, message: message.trim() })}>Create inquiry</Button>
        </div>
      </div>
    </Modal>
  );
}

Object.assign(window, { InquiryStatusPill, StarRating, LodgeInquiryModal, InquiryThread, CustomerInquiries, CsrInquiries, NewInquiryModal });
