/* Price groups — per-customer trade pricing.
   Define groups with a flat £/m gang-sheet rate, then add customers one by one.
   The rate applies automatically to any draft/quote built for a group member. */

function pgApi(path, method = "GET", body) {
  return fetch(path, {
    method,
    headers: body !== undefined ? { "Content-Type": "application/json" } : undefined,
    body: body !== undefined ? JSON.stringify(body) : undefined,
  }).then(async (r) => {
    if (!r.ok) { let m; try { m = (await r.json()).error; } catch {} throw new Error(m || r.status + " " + r.statusText); }
    return r.json();
  });
}

const pgRate = (v) => (v != null && v !== "" && Number(v) > 0 ? "£" + Number(v).toFixed(2) + "/m" : "standard");

/* Add-a-customer search box (reuses the review customer-search endpoint). */
function PgCustomerPicker({ onPick }) {
  const { useState, useRef, useCallback } = React;
  const [q, setQ] = useState("");
  const [results, setResults] = useState([]);
  const [busy, setBusy] = useState(false);
  const timer = useRef(null);

  const run = useCallback((text) => {
    setQ(text);
    if (timer.current) clearTimeout(timer.current);
    if (!text.trim()) { setResults([]); return; }
    timer.current = setTimeout(async () => {
      setBusy(true);
      try { const r = await pgApi("/api/reviews/customers?q=" + encodeURIComponent(text.trim())); setResults(r.customers || []); }
      catch { setResults([]); }
      finally { setBusy(false); }
    }, 250);
  }, []);

  return (
    <div style={{ position: "relative", marginTop: 8 }}>
      <input className="inp" placeholder="Add a customer — search name or email…" value={q}
             onChange={(e) => run(e.target.value)} style={{ width: "100%", fontSize: 13 }} />
      {busy && <span className="kick" style={{ position: "absolute", right: 10, top: 9 }}>…</span>}
      {results.length > 0 && (
        <div style={{ position: "absolute", zIndex: 5, left: 0, right: 0, top: "100%", marginTop: 4, background: "var(--panel,#fff)", border: "1px solid var(--bd,#e2e5ea)", borderRadius: 8, boxShadow: "0 8px 24px rgba(0,0,0,.12)", maxHeight: 260, overflowY: "auto" }}>
          {results.map((c) => (
            <button key={c.id} className="pg-opt"
                    onClick={() => { onPick(c); setQ(""); setResults([]); }}
                    style={{ display: "block", width: "100%", textAlign: "left", padding: "8px 12px", background: "none", border: "none", borderBottom: "1px solid var(--bd,#f0f2f5)", cursor: "pointer", fontSize: 13 }}>
              <strong>{c.name || "—"}</strong>{c.email ? <span className="dim" style={{ marginLeft: 6 }}>{c.email}</span> : null}
              {c.ordersCount ? <span className="kick" style={{ marginLeft: 6 }}>{c.ordersCount} orders</span> : null}
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

/* One group: rate editor + member list + add picker. */
function PgGroupCard({ group, onChange }) {
  const { useState } = React;
  const [dtf, setDtf] = useState(group.dtfRate ?? "");
  const [uv, setUv] = useState(group.uvRate ?? "");
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState(null);
  const dirty = String(dtf) !== String(group.dtfRate ?? "") || String(uv) !== String(group.uvRate ?? "");

  const saveRates = async () => {
    setBusy(true); setErr(null);
    try { await pgApi("/api/price-groups", "POST", { id: group.id, name: group.name, dtfRate: dtf === "" ? null : Number(dtf), uvRate: uv === "" ? null : Number(uv) }); await onChange(); }
    catch (e) { setErr(e.message); } finally { setBusy(false); }
  };
  const addCustomer = async (c) => {
    setBusy(true); setErr(null);
    try { await pgApi(`/api/price-groups/${group.id}/members`, "POST", { customerId: c.id, name: c.name, email: c.email }); await onChange(); }
    catch (e) { setErr(e.message); } finally { setBusy(false); }
  };
  const removeCustomer = async (m) => {
    setBusy(true); setErr(null);
    try { await pgApi(`/api/price-groups/${group.id}/members/${encodeURIComponent(String(m.customerId).split("/").pop())}`, "DELETE"); await onChange(); }
    catch (e) { setErr(e.message); } finally { setBusy(false); }
  };
  const removeGroup = async () => {
    if (!confirm(`Delete price group "${group.name}"? Its ${group.members.length} member(s) will be unassigned and their trade tag removed.`)) return;
    setBusy(true); setErr(null);
    try { await pgApi(`/api/price-groups/${group.id}`, "DELETE"); await onChange(); }
    catch (e) { setErr(e.message); setBusy(false); }
  };

  return (
    <div className="card" style={{ padding: 16, marginBottom: 16 }}>
      <div style={{ display: "flex", alignItems: "baseline", gap: 10, marginBottom: 12 }}>
        <h3 style={{ margin: 0, fontSize: 16 }}>{group.name}</h3>
        <span className="kick">{group.members.length} customer{group.members.length === 1 ? "" : "s"}</span>
        <button className="btn btn--ghost btn--sm" style={{ marginLeft: "auto", color: "#c0392b" }} disabled={busy} onClick={removeGroup}>Delete group</button>
      </div>

      <div style={{ display: "flex", gap: 16, flexWrap: "wrap", alignItems: "flex-end", marginBottom: 6 }}>
        <label style={{ fontSize: 12.5 }}>
          <div className="dim" style={{ marginBottom: 3 }}>DTF £/m inc VAT (flat)</div>
          <input className="inp" type="number" step="0.01" min="0" placeholder="standard" value={dtf} onChange={(e) => setDtf(e.target.value)} style={{ width: 120 }} />
        </label>
        <label style={{ fontSize: 12.5 }}>
          <div className="dim" style={{ marginBottom: 3 }}>UV DTF £/m inc VAT (flat)</div>
          <input className="inp" type="number" step="0.01" min="0" placeholder="standard" value={uv} onChange={(e) => setUv(e.target.value)} style={{ width: 120 }} />
        </label>
        {dirty && <button className="btn btn--primary btn--sm" disabled={busy} onClick={saveRates}>Save rates</button>}
        <span className="kick">Leave blank to keep the standard volume tiers for that product.</span>
      </div>

      {group.members.length > 0 && (
        <div style={{ marginTop: 12, display: "flex", flexDirection: "column", gap: 4 }}>
          {group.members.map((m) => (
            <div key={m.customerId} style={{ display: "flex", alignItems: "center", gap: 8, padding: "5px 8px", background: "var(--panel-2,#f7f8fa)", borderRadius: 6, fontSize: 13 }}>
              <strong>{m.name || "—"}</strong>
              {m.email ? <span className="dim">{m.email}</span> : null}
              <button className="btn btn--ghost btn--sm" style={{ marginLeft: "auto", color: "#c0392b" }} disabled={busy} onClick={() => removeCustomer(m)} title="Remove from group">✕</button>
            </div>
          ))}
        </div>
      )}

      <PgCustomerPicker onPick={addCustomer} />
      {err && <div style={{ color: "#c0392b", fontSize: 12.5, marginTop: 8 }}>{err}</div>}
    </div>
  );
}

function PricingView({ go }) {
  const { useState, useEffect, useCallback } = React;
  const [groups, setGroups] = useState(null);
  const [err, setErr] = useState(null);
  const [newName, setNewName] = useState("");
  const [creating, setCreating] = useState(false);

  const load = useCallback(async () => {
    setErr(null);
    try { const r = await pgApi("/api/price-groups"); setGroups(r.groups || []); }
    catch (e) { setErr(e.message); setGroups([]); }
  }, []);
  useEffect(() => { load(); }, [load]);

  // Member lists aren't included in the list payload — fetch each group's detail.
  const [detail, setDetail] = useState({});
  useEffect(() => {
    if (!groups) return;
    let alive = true;
    Promise.all(groups.map((g) => pgApi("/api/price-groups/" + g.id).then((r) => r.group).catch(() => ({ ...g, members: [] }))))
      .then((list) => { if (alive) setDetail(Object.fromEntries(list.filter(Boolean).map((g) => [g.id, g]))); });
    return () => { alive = false; };
  }, [groups]);

  const create = async () => {
    if (!newName.trim()) return;
    setCreating(true); setErr(null);
    try { await pgApi("/api/price-groups", "POST", { name: newName.trim() }); setNewName(""); await load(); }
    catch (e) { setErr(e.message); } finally { setCreating(false); }
  };

  return (
    <div className="board">
      <div className="toolbar" style={{ gap: 10, flexWrap: "wrap" }}>
        <span className="kick">Trade groups · a flat per-metre rate applies to any quote built for a member</span>
        <div style={{ marginLeft: "auto", display: "flex", gap: 8 }}>
          <input className="inp" placeholder="New group name (e.g. Trade)" value={newName}
                 onChange={(e) => setNewName(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") create(); }} style={{ width: 220, fontSize: 13 }} />
          <button className="btn btn--primary btn--sm" disabled={creating || !newName.trim()} onClick={create}>{creating ? "Creating…" : "Create group"}</button>
        </div>
      </div>

      {err && <div style={{ color: "#c0392b", fontSize: 13, margin: "10px 0" }}>{err}</div>}

      {groups === null ? (
        <div className="empty"><div className="t">Loading…</div></div>
      ) : groups.length === 0 ? (
        <div className="empty">
          <Icon name="tag" />
          <div className="t">No price groups yet</div>
          <div className="m">Create a group (e.g. "Trade"), set its flat £/m rate, then add customers. Members get that rate on every quote you build for them.</div>
        </div>
      ) : (
        <div style={{ maxWidth: 720 }}>
          {groups.map((g) => (
            <PgGroupCard key={g.id} group={detail[g.id] || { ...g, members: [] }} onChange={load} />
          ))}
        </div>
      )}
    </div>
  );
}
