/* =============================================================
   CoreIQ Office — Price Position (LIVE · this pharmacy)

   Where our shelf price sits against the latest OBSERVED competitor price.
   Source: public.competitor_prices (migrated CWH observations + Office captures),
   compared within-tenant only (market research, not cross-pharmacy coordination).

   Honest by construction: the "reduce to sell faster" recommendation runs on
   FRONT-OF-SHOP RETAIL lines only. Prescription/ethical lines are shown as a
   monitor — for a script the competitor's captured price is the patient co-pay,
   not a like-for-like retail price, so the gap there is informational only.
   ============================================================= */
const { useState: ppState, useEffect: ppEffect, useRef: ppRef } = React;

const ppM = (c) => "$" + (Number(c || 0) / 100).toLocaleString("en-AU", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
const ppPct = (v) => (v > 0 ? "+" : "") + Number(v).toFixed(1) + "%";

// A small typeahead that resolves one of OUR products to feed a capture.
function ProductPicker({ value, onPick }) {
  const [q, setQ] = ppState("");
  const [matches, setMatches] = ppState([]);
  const [open, setOpen] = ppState(false);
  const t = ppRef(null);
  ppEffect(() => () => { if (t.current) clearTimeout(t.current); }, []); // clear pending debounce on unmount
  const search = (text) => {
    setQ(text); onPick(null);
    if (t.current) clearTimeout(t.current);
    if (!text.trim()) { setMatches([]); setOpen(false); return; }
    t.current = setTimeout(() => {
      window.OfficeAPI.listProducts({ search: text.trim(), limit: 8 })
        .then((ps) => { setMatches(ps || []); setOpen(true); })
        .catch(() => { setMatches([]); setOpen(false); });
    }, 220);
  };
  if (value) {
    return (
      <div style={{display:"flex", alignItems:"center", gap:8}}>
        <span style={{flex:1, fontSize:"var(--fs-13)", fontWeight:600}}>{value.name}</span>
        <button className="btn btn--ghost btn--sm" onClick={() => { onPick(null); setQ(""); }}>change</button>
      </div>
    );
  }
  return (
    <div style={{position:"relative"}}>
      <input className="off-input" style={{width:"100%"}} placeholder="Search a product by name or barcode…" value={q} onChange={(e) => search(e.target.value)} onFocus={() => matches.length && setOpen(true)}/>
      {open && matches.length > 0 && (
        <div style={{position:"absolute", top:"100%", left:0, right:0, zIndex:20, background:"var(--surface)", border:"1px solid var(--line)", borderRadius:8, marginTop:4, maxHeight:240, overflowY:"auto", boxShadow:"0 8px 24px rgba(0,0,0,.12)"}}>
          {matches.map((p) => (
            <div key={p.id} style={{padding:"9px 12px", cursor:"pointer", fontSize:"var(--fs-13)", borderBottom:"1px solid var(--line)"}}
              onMouseDown={() => { onPick(p); setOpen(false); }}>
              <div style={{fontWeight:600}}>{p.name}</div>
              <div style={{fontSize:"var(--fs-11)", color:"var(--text-subtle)", fontFamily:"var(--font-mono)"}}>{p.sku} · our {ppM(p.sellPriceCents)}</div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// Capture a competitor price. `fixedProduct` pins the product (product-page use);
// otherwise the form shows a product picker (price-position screen use).
function CompetitorCaptureForm({ fixedProduct, onSaved, onCancel }) {
  const [product, setProduct] = ppState(fixedProduct || null);
  const [competitor, setCompetitor] = ppState("Chemist Warehouse");
  const [price, setPrice] = ppState("");
  const [url, setUrl] = ppState("");
  const [busy, setBusy] = ppState(false);
  const [msg, setMsg] = ppState(null);

  const submit = async () => {
    setMsg(null);
    const pid = product ? product.id : null;
    if (!pid) { setMsg({ ok: false, t: "Pick a product first." }); return; }
    if (!competitor.trim()) { setMsg({ ok: false, t: "Competitor name is required." }); return; }
    const dollars = parseFloat(price);
    if (!(dollars >= 0)) { setMsg({ ok: false, t: "Enter a valid price." }); return; }
    setBusy(true);
    try {
      await window.OfficeAPI.recordCompetitorPrice({
        productId: pid,
        competitor: competitor.trim(),
        priceCents: Math.round(dollars * 100),
        priceBasis: "manual",
        url: url.trim() || null,
      });
      setMsg({ ok: true, t: "Saved." });
      setPrice(""); setUrl("");
      if (!fixedProduct) setProduct(null);
      if (onSaved) onSaved();
    } catch (e) {
      setMsg({ ok: false, t: String((e && e.message) || e) });
    } finally { setBusy(false); }
  };

  return (
    <div className="off-card" style={{background:"var(--bg-subtle)"}}>
      <div className="off-card-header"><h3 className="off-card-title">Add a competitor price</h3>
        {onCancel && <button className="btn btn--ghost btn--sm" onClick={onCancel}>close</button>}
      </div>
      <div style={{display:"flex", flexDirection:"column", gap:10, maxWidth:520}}>
        {!fixedProduct && (
          <label style={{display:"block"}}><span style={{fontSize:"var(--fs-12)", color:"var(--text-subtle)"}}>Product</span>
            <ProductPicker value={product} onPick={setProduct}/></label>
        )}
        <div style={{display:"flex", gap:10}}>
          <label style={{flex:2}}><span style={{fontSize:"var(--fs-12)", color:"var(--text-subtle)"}}>Competitor</span>
            <input className="off-input" style={{width:"100%"}} value={competitor} onChange={(e) => setCompetitor(e.target.value)}/></label>
          <label style={{flex:1}}><span style={{fontSize:"var(--fs-12)", color:"var(--text-subtle)"}}>Their price</span>
            <input className="off-input" style={{width:"100%"}} inputMode="decimal" placeholder="0.00" value={price} onChange={(e) => setPrice(e.target.value)}/></label>
        </div>
        <label style={{display:"block"}}><span style={{fontSize:"var(--fs-12)", color:"var(--text-subtle)"}}>Link (optional)</span>
          <input className="off-input" style={{width:"100%"}} placeholder="https://…" value={url} onChange={(e) => setUrl(e.target.value)}/></label>
        <div style={{display:"flex", alignItems:"center", gap:12}}>
          <button className="btn btn--primary btn--sm" disabled={busy} onClick={submit}>{busy ? "Saving…" : "Save observation"}</button>
          {msg && <span style={{fontSize:"var(--fs-12)", color: msg.ok ? "var(--paid)" : "var(--void-text)"}}>{msg.t}</span>}
        </div>
      </div>
    </div>
  );
}

// A single price-position row's gap chip (above = dearer than market = red-ish).
function GapChip({ deltaPct, isRx }) {
  if (isRx) return <span style={{fontSize:"var(--fs-11)", color:"var(--text-subtle)"}}>{ppPct(deltaPct)} · monitor</span>;
  const above = deltaPct > 0.05;
  const below = deltaPct < -0.05;
  const c = above ? "var(--void-text)" : below ? "var(--paid)" : "var(--text-subtle)";
  const bg = above ? "var(--void-bg)" : below ? "var(--paid-bg)" : "var(--bg-subtle)";
  return <span style={{fontSize:"var(--fs-12)", fontWeight:700, color:c, background:bg, padding:"2px 8px", borderRadius:12, fontVariantNumeric:"tabular-nums"}}>{ppPct(deltaPct)}</span>;
}

function PricePosition() {
  const { setScreen, setScreenState } = window.useOffice();
  const [scope, setScope] = ppState("retail");
  const [position, setPosition] = ppState("all");
  const [search, setSearch] = ppState("");
  const [data, setData] = ppState(null);
  const [err, setErr] = ppState(null);
  const [loading, setLoading] = ppState(true);
  const [showAdd, setShowAdd] = ppState(false);
  const [reloadKey, setReloadKey] = ppState(0);

  ppEffect(() => {
    let alive = true;
    setLoading(true);
    const q = { scope, position, limit: 200 };
    if (search.trim()) q.search = search.trim();
    window.OfficeAPI.pricePosition(q)
      .then((d) => { if (alive) { setData(d); setErr(null); setLoading(false); } })
      .catch((e) => { if (alive) { setErr(String((e && e.message) || e)); setLoading(false); } });
    return () => { alive = false; };
  }, [scope, position, search, reloadKey]);

  const openProduct = (pid) => { setScreenState((st) => ({ ...st, activeProductId: pid, productFrom: "pricePosition" })); setScreen("productDetail"); };
  const s = data && data.summary;
  const rows = (data && data.rows) || [];
  const Kpi = window.KpiCard;

  const SCOPES = [
    { k: "retail", label: "Retail (front of shop)" },
    { k: "rx", label: "Prescription" },
    { k: "all", label: "All" },
  ];
  const POS = [
    { k: "all", label: "All" },
    { k: "above", label: "Above market" },
    { k: "below", label: "Below market" },
  ];

  return (
    <div className="off-screen">
      <header className="off-screen-header">
        <div className="off-screen-header-meta">
          <span className="off-screen-eyebrow">live · this pharmacy · competitor observations</span>
          <h2 className="off-screen-title">Price position</h2>
        </div>
        <button className="btn btn--secondary btn--sm" onClick={() => setShowAdd((v) => !v)}>
          <window.OIcon name="plus"/> Add competitor price
        </button>
      </header>

      <div className="off-screen-body">
        {showAdd && <div style={{marginBottom:16}}><CompetitorCaptureForm onSaved={() => setReloadKey((k) => k + 1)} onCancel={() => setShowAdd(false)}/></div>}

        {/* KPIs — counts are honest: above/below are over the retail subset only */}
        {s && Kpi && (
          <div className="off-grid-kpis" style={{display:"grid", gridTemplateColumns:"repeat(4, 1fr)", gap:14, marginBottom:18}}>
            <Kpi label="Products compared" value={Number(s.productsCompared).toLocaleString("en-AU")} delta={{ text: s.retailCompared + " retail · " + s.rxCompared + " script" }}/>
            <Kpi label="Above market (retail)" value={Number(s.above).toLocaleString("en-AU")} delta={{ text: "priced higher → room to sharpen", dir: s.above > 0 ? "down" : undefined }}/>
            <Kpi label="Below market (retail)" value={Number(s.below).toLocaleString("en-AU")} delta={{ text: "priced lower → headroom" }}/>
            <Kpi label="Avg gap to market" value={s.avgDeltaPct == null ? "—" : ppPct(s.avgDeltaPct)} delta={{ text: "retail, vs latest observed" }}/>
          </div>
        )}

        {/* controls */}
        <div style={{display:"flex", alignItems:"center", gap:12, marginBottom:14, flexWrap:"wrap"}}>
          <div className="tabset">
            {SCOPES.map((t) => (
              <button key={t.k} className="tabset-item" aria-selected={scope === t.k} onClick={() => setScope(t.k)}>{t.label}</button>
            ))}
          </div>
          <div style={{display:"flex", gap:6}}>
            {POS.map((t) => (
              <button key={t.k} className={"btn btn--sm " + (position === t.k ? "btn--primary" : "btn--ghost")} onClick={() => setPosition(t.k)}>{t.label}</button>
            ))}
          </div>
          <input className="off-input" style={{marginLeft:"auto", minWidth:220}} placeholder="Filter products…" value={search} onChange={(e) => setSearch(e.target.value)}/>
        </div>

        {err && <div className="off-card" style={{borderColor:"var(--void-border)", background:"var(--void-bg)", color:"var(--void-text)", padding:"12px 16px"}}><window.OIcon name="alert"/> {err}</div>}

        {scope === "rx" && (
          <div style={{display:"flex", alignItems:"center", gap:8, padding:"10px 14px", marginBottom:12, background:"var(--bg-subtle)", borderRadius:8, fontSize:"var(--fs-12)", color:"var(--text-subtle)"}}>
            <window.OIcon name="info"/> Prescription lines — the competitor's captured price is the patient co-pay, not a like-for-like retail price. Shown for monitoring; the gap is informational.
          </div>
        )}

        {!loading && !err && rows.length === 0 && (
          <div className="off-card" style={{padding:"28px 20px", textAlign:"center"}}>
            <div style={{fontSize:"var(--fs-15)", fontWeight:600, marginBottom:6}}>
              {scope === "retail" ? "No front-of-shop retail comparisons yet" : "No competitor observations match"}
            </div>
            <div style={{fontSize:"var(--fs-13)", color:"var(--text-subtle)", maxWidth:520, margin:"0 auto"}}>
              {scope === "retail"
                ? "Your observed competitor prices so far are prescription items — switch to Prescription to monitor those. Capture a retail competitor price above, and new comparisons also arrive from the national feed as it grows."
                : "Try a different scope or clear the filter."}
            </div>
          </div>
        )}

        {rows.length > 0 && (
          <div className="off-card">
            <div className="off-card-header">
              <h3 className="off-card-title">{position === "above" ? "Priced above market" : position === "below" ? "Priced below market" : "Our price vs latest competitor"}</h3>
              <span className="off-card-meta">{rows.length} line{rows.length === 1 ? "" : "s"} · sorted by gap</span>
            </div>
            <div className="off-grid" style={{gridTemplateColumns:"1fr 150px 100px 100px 96px"}}>
              <div className="off-grid-headcell">Product</div>
              <div className="off-grid-headcell">Competitor</div>
              <div className="off-grid-headcell" style={{justifyContent:"flex-end"}}>Our price</div>
              <div className="off-grid-headcell" style={{justifyContent:"flex-end"}}>Theirs</div>
              <div className="off-grid-headcell" style={{justifyContent:"flex-end"}}>Gap</div>
              {rows.map((r, i) => (
                <div key={i} className="off-grid-row" style={{cursor:"pointer"}} onClick={() => r.productId && openProduct(r.productId)}>
                  <div className="off-grid-cell off-cell-strong" style={{display:"flex", alignItems:"center", gap:8, minWidth:0}}>
                    <span style={{overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap"}}>{r.productName || r.productId}</span>
                    {r.isRx && <span style={{flexShrink:0, fontSize:9, fontWeight:700, letterSpacing:.4, color:"var(--text-subtle)", border:"1px solid var(--line)", borderRadius:4, padding:"1px 5px"}}>SCRIPT</span>}
                  </div>
                  <div className="off-grid-cell" style={{display:"flex", alignItems:"center", gap:6}}>
                    {r.url
                      ? <a href={r.url} target="_blank" rel="noopener noreferrer" onClick={(e) => e.stopPropagation()} style={{color:"var(--brand)", textDecoration:"none", overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap"}}>{r.competitor}</a>
                      : <span style={{overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap"}}>{r.competitor}</span>}
                  </div>
                  <div className="off-grid-cell off-cell-num">{ppM(r.ourSellCents)}</div>
                  <div className="off-grid-cell off-cell-num off-muted">{ppM(r.competitorPriceCents)}</div>
                  <div className="off-grid-cell" style={{justifyContent:"flex-end"}}><GapChip deltaPct={r.deltaPct} isRx={r.isRx}/></div>
                </div>
              ))}
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

window.CompetitorCaptureForm = CompetitorCaptureForm;
window.OFFICE_SCREENS = Object.assign(window.OFFICE_SCREENS || {}, { pricePosition: PricePosition });
