/* =============================================================
   CoreIQ Office — Expiring stock (LIVE)

   The back-office half of what the handheld records in the aisle: the shop
   floor scans a product and types the date off the pack, and those sightings
   land in product_expiry_checks. Without this screen that is data entry into
   a table nobody reads — worse than not collecting it, because it costs staff
   real time and looks like it is working.

   Deliberately NOT a stock screen. On-hand is a projection of the movements
   ledger; an expiry sighting is an observation about a shelf. The quantity
   shown is what the operator counted at that moment, and is labelled as such.
   ============================================================= */
const { useState: expUseState, useEffect: expUseEffect, useMemo: expUseMemo } = React;

function expMoney(cents) {
  if (cents == null) return "—";
  return "$" + (Number(cents) / 100).toFixed(2);
}

// Australian order, matching what the handheld asks the operator to type.
function expDate(iso) {
  if (!iso) return "—";
  const d = new Date(iso);
  if (isNaN(d)) return String(iso).slice(0, 10);
  const dd = String(d.getDate()).padStart(2, "0");
  const mm = String(d.getMonth() + 1).padStart(2, "0");
  return dd + "/" + mm + "/" + d.getFullYear();
}

// "Expired" and "expiring" are different jobs: one comes off the shelf today,
// the other is a markdown decision. The wording has to keep them apart.
function expWhen(daysLeft) {
  const n = Number(daysLeft);
  if (n < 0) return { text: "Expired " + Math.abs(n) + "d ago", tone: "void" };
  if (n === 0) return { text: "Expires today", tone: "void" };
  if (n <= 30) return { text: n + " days", tone: "hold" };
  return { text: n + " days", tone: "" };
}

const EXP_WINDOWS = [30, 60, 90, 180];

function ExpiringStock() {
  const { scope } = window.useOffice();
  const [windowDays, setWindowDays] = expUseState(90);
  const [data, setData] = expUseState(null);
  const [err, setErr] = expUseState(null);
  const [busyId, setBusyId] = expUseState(null);
  const [reloadKey, setReloadKey] = expUseState(0);
  const [q, setQ] = expUseState("");

  expUseEffect(() => {
    let alive = true;
    setData(null);
    setErr(null);
    const siteId = scope === "all" ? undefined : scope;
    window.OfficeAPI.getExpiring(windowDays, siteId)
      .then((d) => { if (alive) setData(d); })
      .catch((e) => { if (alive) setErr(String((e && e.message) || e)); });
    return () => { alive = false; };
  }, [windowDays, scope, reloadKey]);

  const shown = expUseMemo(() => {
    if (!data) return [];
    const needle = q.trim().toLowerCase();
    if (!needle) return data.items;
    return data.items.filter((i) =>
      (i.name || "").toLowerCase().includes(needle) ||
      (i.sku || "").toLowerCase().includes(needle) ||
      (i.brand || "").toLowerCase().includes(needle));
  }, [data, q]);

  async function resolve(item) {
    setBusyId(item.id);
    try {
      await window.OfficeAPI.resolveExpiring(item.id);
      setReloadKey((k) => k + 1);
    } catch (e) {
      setErr(String((e && e.message) || e));
    } finally {
      setBusyId(null);
    }
  }

  if (err) {
    return (
      <div className="off-screen">
        <h2 className="off-screen-title">Expiring stock</h2>
        <div className="off-empty">Couldn’t load: {err}</div>
      </div>
    );
  }
  if (!data) {
    return (
      <div className="off-screen">
        <h2 className="off-screen-title">Expiring stock</h2>
        <div className="off-empty">Loading…</div>
      </div>
    );
  }

  // An empty list is honest: nothing has been flagged yet. It must not read as
  // "nothing is expiring", which is a different and much stronger claim.
  const nothingRecorded = data.items.length === 0;

  return (
    <div className="off-screen">
      <div className="off-screen-head">
        <div>
          <div className="off-screen-eyebrow">SHOP FLOOR · RECORDED ON THE HANDHELD</div>
          <h2 className="off-screen-title">Expiring stock</h2>
        </div>
      </div>

      <div className="off-table">
        <div className="off-table-toolbar" style={{flexWrap:'wrap', rowGap:8}}>
          <div style={{display:'flex', gap:6}}>
            {EXP_WINDOWS.map((w) => (
              <button key={w}
                className={"btn btn--sm " + (windowDays === w ? "btn--primary" : "btn--ghost")}
                onClick={() => setWindowDays(w)}>{w} days</button>
            ))}
          </div>
          <div className="input-wrap" style={{width:240}}>
            <OIcon name="search" className="input-wrap-icon"/>
            <input className="input" placeholder="Filter by product, SKU or brand…"
              value={q} onChange={(e) => setQ(e.target.value)} style={{height:34, fontSize:13}}/>
          </div>
          <div style={{marginLeft:'auto', display:'flex', gap:14, alignItems:'center', fontSize:13}}>
            {data.expiredCount > 0 && (
              <span style={{color:'var(--danger, #b42318)', fontWeight:600}}>
                {data.expiredCount} already expired
              </span>
            )}
            <span style={{color:'var(--text-muted)'}}>{data.soonCount} expiring</span>
            <span style={{fontWeight:600}}>
              {expMoney(data.totalValueAtRiskCents)} at risk
            </span>
          </div>
        </div>

        {/* The value figure is only as complete as the counts behind it. Saying
            so keeps it from being read as the whole exposure. */}
        {data.withoutQuantity > 0 && (
          <div style={{padding:'8px 14px', fontSize:12.5, color:'var(--text-muted)', borderBottom:'1px solid var(--border-subtle)'}}>
            {data.withoutQuantity} of these were flagged without a quantity, so they carry no value —
            the figure above is the value of what was actually counted.
          </div>
        )}

        <div className="off-grid" style={{gridTemplateColumns:'1fr 120px 130px 90px 110px 120px'}}>
          <div className="off-grid-headcell">Product</div>
          <div className="off-grid-headcell">Expiry</div>
          <div className="off-grid-headcell">When</div>
          <div className="off-grid-headcell" style={{justifyContent:'flex-end'}}>Counted</div>
          <div className="off-grid-headcell" style={{justifyContent:'flex-end'}}>At risk</div>
          <div className="off-grid-headcell"></div>

          {nothingRecorded && (
            <div style={{gridColumn:'1 / -1', padding:'26px 14px', fontSize:13, color:'var(--text-muted)', textAlign:'center'}}>
              Nothing flagged yet. Expiry dates are recorded on the handheld —
              scan a product, tap “Record expiry”, type the date off the pack.
            </div>
          )}

          {shown.map((i) => {
            const when = expWhen(i.daysLeft);
            return (
              <div key={i.id} className="off-grid-row">
                <div className="off-grid-cell off-cell-strong">
                  {i.name}
                  {i.brand ? <span className="off-muted" style={{fontWeight:400}}> · {i.brand}</span> : null}
                  {i.batchNumber ? <span className="off-muted" style={{fontWeight:400}}> · batch {i.batchNumber}</span> : null}
                </div>
                <div className="off-grid-cell off-cell-mono">{expDate(i.expiryDate)}</div>
                <div className="off-grid-cell">
                  <span className={"badge " + (when.tone ? "badge--" + when.tone : "")}>{when.text}</span>
                </div>
                <div className="off-grid-cell off-cell-num">
                  {i.quantity == null ? <span className="off-muted">—</span> : Number(i.quantity).toFixed(0)}
                </div>
                <div className="off-grid-cell off-cell-num">{expMoney(i.valueAtRiskCents)}</div>
                <div className="off-grid-cell">
                  <button className="btn btn--ghost btn--sm" disabled={busyId === i.id}
                    onClick={() => resolve(i)}
                    title="Marked down, pulled or returned — clears it from this list without deleting the record">
                    {busyId === i.id ? "…" : "Dealt with"}
                  </button>
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

window.OFFICE_SCREENS = Object.assign(window.OFFICE_SCREENS || {}, { expiring: ExpiringStock });
