// TruckOrderCount.jsx — the counting workflow.
//
// Layout: full-page takeover (no sidebar/tabs distractions while counting).
//   Header   — date + cancel + finalize
//   Body     — items grouped by storage area, each row:
//                Item name + vendor
//                Count by purchase unit  (e.g. unopened cases)
//                Count by storage unit   (e.g. partial prep pans)
//                Live subtotal in purchase units
//                Suggested order amount (auto-calc'd)
//                Override input
//   Footer   — summary bar with totals + finalize button
//
// Counts are persisted via the parent's onUpdateLine (which writes to
// localStorage), so a refresh keeps the in-progress count.

const { useState: useTC, useMemo: useMemoTC } = React;

const CountingScreen = ({ draft, pars, onUpdateLine, onUpdateMeta, onCancel, onFinalize, pinGate, setPinGate }) => {
  const allItems   = window.SAMPLE_INVENTORY_ITEMS  || [];
  const allAreas   = window.SAMPLE_STORAGE_AREAS    || [];
  const allVendors = window.SAMPLE_VENDORS          || [];

  const itemById   = useMemoTC(() => Object.fromEntries(allItems.map(i => [i.id, i])), [allItems]);
  const areaById   = useMemoTC(() => Object.fromEntries(allAreas.map(a => [a.id, a])), [allAreas]);
  const vendorById = useMemoTC(() => Object.fromEntries(allVendors.map(v => [v.id, v])), [allVendors]);

  // "Show missed only" filter — hides any line that's been counted or skipped.
  const [showMissedOnly, setShowMissedOnly] = useTC(false);

  // A line is considered "handled" if the user typed anything OR explicitly skipped.
  const isLineHandled = (line) =>
    line.skipped === true ||
    (line.countStorage !== '' && line.countStorage !== null && line.countStorage !== undefined) ||
    (line.countPurchase !== '' && line.countPurchase !== null && line.countPurchase !== undefined);

  // Group draft lines by storage area for the count workflow.
  // Lines whose item belongs to an excluded vendor are dropped first so the
  // header summary, group buckets, and finalize math all agree.
  const excludedVendors = new Set(draft.excludedVendorIds || []);
  const activeLines = useMemoTC(
    () => draft.lines.filter(l => {
      const item = itemById[l.itemId];
      if (!item || excludedVendors.has(item.vendorId)) return false;
      if (showMissedOnly && isLineHandled(l)) return false;
      return true;
    }),
    [draft.lines, itemById, draft.excludedVendorIds, showMissedOnly]
  );

  const groups = useMemoTC(() => {
    const buckets = {};
    allAreas.forEach(a => buckets[a.id] = { area: a, lines: [] });
    buckets['__none'] = { area: { id: '__none', name: 'Other / Unassigned' }, lines: [] };

    activeLines.forEach(line => {
      const item = itemById[line.itemId];
      if (!item) return;
      const key = areaById[item.storageAreaId] ? item.storageAreaId : '__none';
      buckets[key].lines.push({ ...line, item });
    });

    return Object.values(buckets).filter(g => g.lines.length > 0);
  }, [activeLines, itemById, areaById, allAreas]);

  // Build the vendor toggle strip — every vendor that has at least one
  // active inventory item in this draft.
  const vendorStrip = useMemoTC(() => {
    const counts = {};
    draft.lines.forEach(line => {
      const item = itemById[line.itemId];
      if (!item || !item.vendorId) return;
      counts[item.vendorId] = (counts[item.vendorId] || 0) + 1;
    });
    return Object.keys(counts)
      .map(id => ({ vendor: vendorById[id], count: counts[id] }))
      .filter(v => v.vendor)
      .sort((a, b) => a.vendor.name.localeCompare(b.vendor.name));
  }, [draft.lines, itemById, vendorById]);

  // Summary numbers for footer — only counts active (un-excluded) lines.
  const summary = useMemoTC(() => {
    let countedCount = 0;
    let totalLines = 0;
    let totalToOrder = 0;
    let overrideCount = 0;

    activeLines.forEach(line => {
      const item = itemById[line.itemId];
      if (!item) return;
      totalLines += 1;
      // Skipped lines count as "handled" but contribute nothing to order/overrides.
      if (line.skipped) {
        countedCount += 1;
        return;
      }
      const onHand = window.truckOnHand(item, line.countStorage, line.countPurchase);
      const suggested = window.truckSuggested(pars[line.itemId], onHand);
      const finalRaw = (line.finalOverride === null || line.finalOverride === undefined || line.finalOverride === '')
        ? suggested
        : Number(line.finalOverride);
      const final = isNaN(finalRaw) ? 0 : finalRaw;
      if (line.countStorage !== '' || line.countPurchase !== '') countedCount += 1;
      if (final > 0) totalToOrder += 1;
      if (line.finalOverride !== null && line.finalOverride !== undefined && line.finalOverride !== '' && Number(line.finalOverride) !== suggested) overrideCount += 1;
    });

    return { countedCount, totalLines, totalToOrder, overrideCount };
  }, [activeLines, pars, itemById]);

  const startedBy = window.SAMPLE_STAFF.find(s => s.id === draft.createdByStaffId);

  return (
    <div style={{
      minHeight: '100%',
      background: 'var(--bg-base)',
      display: 'flex', flexDirection: 'column',
    }}>
      {/* Sticky header */}
      <div style={{
        position: 'sticky', top: 0, zIndex: 4,
        flexShrink: 0,
        padding: '16px 32px',
        background: '#FFFFFF',
        borderBottom: '1px solid var(--border-2)',
        display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 20,
        flexWrap: 'wrap',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
          <button onClick={onCancel} style={{
            width: 32, height: 32, borderRadius: 8,
            background: 'transparent', border: '1px solid var(--border-2)',
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            cursor: 'pointer',
          }} title="Cancel">
            <PIcon name="x" size={15} color="var(--fg-2)" />
          </button>
          <div>
            <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--fg-3)', textTransform: 'uppercase', letterSpacing: '0.08em' }}>
              New truck order
            </div>
            <div style={{ fontSize: 18, fontWeight: 600, letterSpacing: '-0.015em', color: 'var(--fg-1)' }}>
              {toFmtDate(draft.createdAt)}
            </div>
          </div>
          {startedBy && (
            <div style={{ marginLeft: 8, display: 'inline-flex', alignItems: 'center', gap: 8, padding: '4px 10px', background: 'var(--bg-sunken)', borderRadius: 999 }}>
              <PAvatar staff={startedBy} size={20} />
              <span style={{ fontSize: 12, color: 'var(--fg-2)' }}>Started by {startedBy.name}</span>
            </div>
          )}
        </div>

        {/* Header summary */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
          <label style={{
            display: 'inline-flex', alignItems: 'center', gap: 8,
            padding: '6px 12px',
            background: showMissedOnly ? '#FFF8EC' : 'var(--bg-sunken)',
            border: '1px solid ' + (showMissedOnly ? '#F0CB7D' : 'transparent'),
            borderRadius: 999,
            fontSize: 12, fontWeight: 500,
            color: showMissedOnly ? '#92400E' : 'var(--fg-2)',
            cursor: 'pointer',
            userSelect: 'none',
          }}>
            <input
              type="checkbox"
              checked={showMissedOnly}
              onChange={e => setShowMissedOnly(e.target.checked)}
              style={{ margin: 0 }}
            />
            Show missed only
          </label>
          <Stat label="Counted" value={`${summary.countedCount} / ${summary.totalLines}`} />
          <Stat label="To order" value={summary.totalToOrder} accent />
          {summary.overrideCount > 0 && (
            <Stat label="Overrides" value={summary.overrideCount} warn />
          )}
          <PBtn variant="primary" onClick={onFinalize} disabled={summary.countedCount === 0}>
            <PIcon name="check" size={14} />
            Finalize order
          </PBtn>
        </div>
      </div>

      {/* Body */}
      <div style={{ flex: 1, padding: '24px 32px 80px' }}>
        <div style={{ maxWidth: 1200, margin: '0 auto' }}>
          {/* Note + vendor strip */}
          <div style={{ marginBottom: 16 }}>
            <input
              value={draft.note || ''}
              onChange={e => onUpdateMeta({ note: e.target.value })}
              placeholder="Optional note for this order…"
              className="portal-input"
              style={{ fontSize: 13, background: 'transparent' }}
            />
          </div>

          {vendorStrip.length > 0 && (
            <div style={{
              marginBottom: 24,
              padding: '12px 14px',
              background: '#FFFFFF',
              border: '1px solid var(--border-2)',
              borderRadius: 10,
              display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap',
            }}>
              <span style={{ fontSize: 10.5, fontWeight: 700, color: 'var(--fg-3)', textTransform: 'uppercase', letterSpacing: '0.08em' }}>
                Vendors
              </span>
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, flex: 1 }}>
                {vendorStrip.map(({ vendor, count }) => {
                  const excluded = excludedVendors.has(vendor.id);
                  return (
                    <button
                      key={vendor.id}
                      onClick={() => {
                        const cur = draft.excludedVendorIds || [];
                        const next = excluded ? cur.filter(id => id !== vendor.id) : [...cur, vendor.id];
                        onUpdateMeta({ excludedVendorIds: next });
                      }}
                      style={{
                        display: 'inline-flex', alignItems: 'center', gap: 6,
                        padding: '5px 11px',
                        background: excluded ? '#FFFFFF' : 'var(--fg-1)',
                        color: excluded ? 'var(--fg-3)' : '#FFFFFF',
                        border: '1px solid ' + (excluded ? 'var(--border-2)' : 'var(--fg-1)'),
                        borderRadius: 999,
                        fontSize: 12, fontWeight: 500,
                        cursor: 'pointer',
                        textDecoration: excluded ? 'line-through' : 'none',
                        opacity: excluded ? 0.7 : 1,
                      }}
                    >
                      {vendor.name}
                      <span style={{
                        fontSize: 11, fontWeight: 600,
                        color: excluded ? 'var(--fg-3)' : 'rgba(255,255,255,0.7)',
                        fontFamily: 'var(--font-num)',
                      }}>{count}</span>
                    </button>
                  );
                })}
              </div>
              {excludedVendors.size > 0 && (
                <button
                  onClick={() => onUpdateMeta({ excludedVendorIds: [] })}
                  style={{
                    fontSize: 11.5, color: 'var(--fg-2)', background: 'transparent',
                    padding: '4px 8px', cursor: 'pointer',
                  }}
                >Include all</button>
              )}
            </div>
          )}

          {/* Groups */}
          {groups.length === 0 ? (
            <div className="portal-empty">
              <div style={{ fontSize: 14, color: 'var(--fg-2)' }}>
                {vendorStrip.length > 0 && excludedVendors.size === vendorStrip.length
                  ? 'All vendors are excluded — select at least one above.'
                  : 'No active items in inventory. Toggle items on in Par Settings first.'}
              </div>
            </div>
          ) : groups.map(group => (
            <CountGroup
              key={group.area.id}
              area={group.area}
              lines={group.lines}
              pars={pars}
              vendorById={vendorById}
              onUpdateLine={onUpdateLine}
            />
          ))}
        </div>
      </div>

      {/* PIN gate — needed inside CountingScreen because it's a full-screen takeover */}
      {pinGate && (
        <PinGate
          purpose={pinGate.purpose}
          onCancel={() => setPinGate(null)}
          onSuccess={pinGate.onSuccess}
        />
      )}
    </div>
  );
};

// ------------------------------------------------------------------
// One storage-area group
// ------------------------------------------------------------------
const CountGroup = ({ area, lines, pars, vendorById, onUpdateLine }) => {
  const countedHere = lines.filter(l => l.countStorage !== '' || l.countPurchase !== '').length;

  return (
    <div style={{ marginBottom: 28 }}>
      <div style={{
        display: 'flex', alignItems: 'center', gap: 10,
        marginBottom: 8, paddingBottom: 8,
        borderBottom: '1px solid var(--border-2)',
      }}>
        <PIcon name="box" size={15} color="var(--fg-2)" />
        <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--fg-1)', letterSpacing: '-0.005em' }}>{area.name}</div>
        <div style={{ fontSize: 11, color: 'var(--fg-3)', fontFamily: 'var(--font-num)' }}>
          {countedHere}/{lines.length} counted
        </div>
        <div style={{ flex: 1 }} />
        <div style={{ fontSize: 10, color: 'var(--fg-3)', textTransform: 'uppercase', letterSpacing: '0.06em', fontWeight: 600 }}>
          {lines.length} item{lines.length === 1 ? '' : 's'}
        </div>
      </div>

      <div style={{
        background: '#FFFFFF',
        border: '1px solid var(--border-2)',
        borderRadius: 10,
        overflow: 'hidden',
      }}>
        <div style={{
          display: 'grid',
          gridTemplateColumns: '1.6fr 1.4fr 0.9fr 1fr',
          padding: '8px 16px',
          background: '#FAFAF9',
          borderBottom: '1px solid var(--border-2)',
          fontSize: 10.5, fontWeight: 700, color: 'var(--fg-2)',
          textTransform: 'uppercase', letterSpacing: '0.06em',
        }}>
          <div>Item</div>
          <div style={{ textAlign: 'right', paddingRight: 8 }}>Count</div>
          <div style={{ textAlign: 'right' }}>On hand</div>
          <div style={{ textAlign: 'right' }}>Order</div>
        </div>

        {lines.map((line, i) => (
          <CountRow
            key={line.itemId}
            line={line}
            par={pars[line.itemId]}
            vendor={vendorById[line.item.vendorId]}
            onUpdate={(patch) => onUpdateLine(line.itemId, patch)}
            isLast={i === lines.length - 1}
          />
        ))}
      </div>
    </div>
  );
};

// ------------------------------------------------------------------
// One item row
// ------------------------------------------------------------------
const CountRow = ({ line, par, vendor, onUpdate, isLast }) => {
  const item = line.item;
  const skipped = line.skipped === true;

  // Skipped row: minimal display — small struck-through item name, click anywhere to un-skip.
  if (skipped) {
    return (
      <div
        onClick={() => onUpdate({ skipped: false })}
        style={{
          display: 'flex', alignItems: 'center', gap: 10,
          padding: '8px 16px',
          borderBottom: isLast ? 'none' : '1px solid var(--border-2)',
          background: '#FBFAF8',
          cursor: 'pointer',
          transition: 'background 120ms ease',
        }}
        onMouseEnter={e => e.currentTarget.style.background = '#F5F4F0'}
        onMouseLeave={e => e.currentTarget.style.background = '#FBFAF8'}
        title="Click to un-skip and expand"
      >
        <button
          onClick={e => { e.stopPropagation(); onUpdate({ skipped: false }); }}
          style={{
            width: 22, height: 22, borderRadius: 999,
            background: 'var(--bg-sunken)', border: 'none', cursor: 'pointer',
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            flexShrink: 0,
          }}
          title="Un-skip"
        >
          <PIcon name="chevronD" size={11} color="var(--fg-3)" />
        </button>
        <span style={{
          fontSize: 12, color: 'var(--fg-3)',
          textDecoration: 'line-through',
        }}>
          {item.name}
        </span>
        <span style={{
          fontSize: 10, fontWeight: 600, color: 'var(--fg-3)',
          textTransform: 'uppercase', letterSpacing: '0.06em',
          marginLeft: 'auto',
        }}>Skipped</span>
      </div>
    );
  }

  const onHand = window.truckOnHand(item, line.countStorage, line.countPurchase);
  const suggested = window.truckSuggested(par, onHand);

  const hasOverride = line.finalOverride !== null && line.finalOverride !== undefined && line.finalOverride !== '';
  const finalAmount = hasOverride ? Number(line.finalOverride) : suggested;
  const isOverridden = hasOverride && Number(line.finalOverride) !== suggested;

  const hasCount = line.countStorage !== '' || line.countPurchase !== '';
  const hasSubUnit = item.conversion && Number(item.conversion) !== 1 && item.storageUnit && item.storageUnit !== item.purchaseUnit;
  const displayN = window.truckDisplayN(item);
  const isStorageLarger = window.truckIsStorageLarger(item);
  const onHandDisplay = window.truckOnHandDisplay(item, line.countStorage, line.countPurchase);

  // Layout by SIZE, not by purchase/storage role:
  //   smaller-unit input (with /N divisor) on the left
  //   larger-unit input on the right
  // Broccoli (R=2, purchase larger): small=storage(pan), large=purchase(case)
  // Rice     (R<1, storage larger):  small=purchase(bag), large=storage(bin)
  const smallerKey  = isStorageLarger ? 'countPurchase' : 'countStorage';
  const smallerUnit = isStorageLarger ? item.purchaseUnit : item.storageUnit;
  const largerKey   = isStorageLarger ? 'countStorage' : 'countPurchase';
  const largerUnit  = isStorageLarger ? item.storageUnit : item.purchaseUnit;
  const onHandDisplayUnit = largerUnit;

  // Compact count input — sized to the digit so the row feels light.
  const countInputStyle = {
    width: 56, height: 32,
    border: '1px solid var(--border-2)',
    borderRadius: 6,
    padding: '0 8px',
    fontFamily: 'var(--font-num)',
    fontSize: 14, fontWeight: 600,
    textAlign: 'center',
    background: '#FFFFFF',
  };
  // Smaller variant for the partial / sub-unit count.
  const subCountInputStyle = {
    ...countInputStyle,
    width: 44, height: 26,
    fontSize: 12,
  };

  return (
    <div style={{
      display: 'grid',
      gridTemplateColumns: '1.6fr 1.4fr 0.9fr 1fr',
      padding: '12px 16px',
      borderBottom: isLast ? 'none' : '1px solid var(--border-2)',
      alignItems: 'center',
      background: hasCount ? '#FBFAF8' : 'transparent',
      transition: 'background 120ms ease',
    }}>
      {/* Item */}
      <div style={{ display: 'flex', alignItems: 'flex-start', gap: 8 }}>
        <button
          onClick={() => onUpdate({ skipped: true })}
          title="Skip this item"
          style={{
            width: 22, height: 22, borderRadius: 999,
            background: 'transparent', border: '1px solid var(--border-2)', cursor: 'pointer',
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            flexShrink: 0, marginTop: 2,
          }}
        >
          <PIcon name="x" size={11} color="var(--fg-3)" />
        </button>
        <div style={{ minWidth: 0 }}>
          <div style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--fg-1)' }}>{item.name}</div>
          <div style={{ fontSize: 11, color: 'var(--fg-3)', marginTop: 2 }}>
            {vendor?.name || 'No vendor'}
            {par && (
              <span style={{ marginLeft: 8, color: 'var(--fg-3)', fontFamily: 'var(--font-num)' }}>
                · par {par.threshold !== null && par.threshold !== undefined ? `${par.threshold}–${par.max}` : `up to ${par.max}`}
              </span>
            )}
          </div>
        </div>
      </div>

      {/* Count — compact:
            with sub-unit:
                [small partial] /N        +  [full]
                          storage unit
            (storage unit right-aligned so it lines up across rows)
            without sub-unit: just [full]
      */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 6, justifyContent: 'flex-end' }}>
        {hasSubUnit && (
          <>
            <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 2 }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
                <input type="number" step="0.01" min="0"
                  value={line[smallerKey]}
                  onChange={e => onUpdate({ [smallerKey]: e.target.value })}
                  placeholder="0"
                  style={subCountInputStyle}
                  title={smallerUnit}
                />
                <span style={{ fontSize: 12, color: 'var(--fg-3)', fontFamily: 'var(--font-num)', fontWeight: 500 }}>
                  /{toFmtQty(displayN)}
                </span>
              </div>
              <span style={{ fontSize: 10, color: 'var(--fg-3)', lineHeight: 1.1 }}>
                {smallerUnit}
              </span>
            </div>
            <span style={{ fontSize: 14, color: 'var(--fg-3)', fontWeight: 500, margin: '0 2px' }}>+</span>
          </>
        )}
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 2 }}>
          <input type="number" step="1" min="0"
            value={line[largerKey]}
            onChange={e => onUpdate({ [largerKey]: e.target.value })}
            placeholder="0"
            style={countInputStyle}
            title={largerUnit}
          />
          {hasSubUnit && (
            <span style={{ fontSize: 10, color: 'var(--fg-3)', lineHeight: 1.1 }}>
              {largerUnit}
            </span>
          )}
        </div>
      </div>

      {/* Subtotal on-hand (in the larger unit so it always reads as a small, intuitive number) */}
      <div style={{ textAlign: 'right' }}>
        <div style={{ fontSize: 14, fontWeight: 600, color: hasCount ? 'var(--fg-1)' : 'var(--fg-3)', fontFamily: 'var(--font-num)' }}>
          {hasCount ? toFmtQty(onHandDisplay) : '—'}
        </div>
        <div style={{ fontSize: 10.5, color: 'var(--fg-3)' }}>{onHandDisplayUnit}</div>
      </div>

      {/* Order — input on its own row, purchase unit label under it (so inputs align across rows). */}
      <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 2 }}>
        {isOverridden && (
          <OverrideMark>was {suggested}</OverrideMark>
        )}
        <input type="number" step="1" min="0"
          value={hasOverride ? line.finalOverride : (hasCount ? suggested : '')}
          onChange={e => {
            const v = e.target.value;
            if (v === '' || Number(v) === suggested) {
              onUpdate({ finalOverride: null });
            } else {
              onUpdate({ finalOverride: v });
            }
          }}
          placeholder="—"
          style={{
            width: 60, height: 32,
            border: isOverridden ? '1px solid #F0CB7D' : '1px solid var(--border-2)',
            borderRadius: 6,
            padding: '0 8px',
            fontFamily: 'var(--font-num)',
            fontSize: 15, fontWeight: 700,
            textAlign: 'center',
            background: isOverridden ? '#FFF8EC' : (finalAmount > 0 ? '#F0F7E8' : '#FFFFFF'),
            color: isOverridden ? '#92400E' : (finalAmount > 0 ? '#2D6A2A' : 'var(--fg-3)'),
          }}
        />
        <span style={{ fontSize: 10.5, color: 'var(--fg-3)' }}>{item.purchaseUnit}</span>
      </div>
    </div>
  );
};
const Stat = ({ label, value, accent, warn }) => (
  <div style={{ textAlign: 'center' }}>
    <div style={{
      fontSize: 20, fontWeight: 700,
      fontFamily: 'var(--font-num)',
      letterSpacing: '-0.015em',
      color: warn ? '#92400E' : (accent ? '#2D6A2A' : 'var(--fg-1)'),
    }}>{value}</div>
    <div style={{ fontSize: 10, fontWeight: 600, color: 'var(--fg-3)', textTransform: 'uppercase', letterSpacing: '0.06em', marginTop: 2 }}>
      {label}
    </div>
  </div>
);

Object.assign(window, { CountingScreen });
