// TruckOrderScreen.jsx — iPad app's Truck Order feature.
//
// Flow:
//   list      — past orders + "Start new order" button (PIN gated)
//   counting  — full-screen takeover: vendor toggle, group-by-storage-area,
//               count rows (compact display, skip, on-hand, suggested order)
//   summary   — finalized order, regrouped by vendor, with iframe-PDF export
//
// PIN gating uses the same SAMPLE_STAFF list as the portal.
// Pars and inventory items come from window.SAMPLE_TRUCK_PARS and
// window.SAMPLE_INVENTORY_ITEMS — same source the portal uses. (Real sync
// will move to Supabase later.)

const { useState: useTo, useEffect: useEffectTo, useMemo: useMemoTo, useRef: useRefTo } = React;

// LocalStorage keys are iPad-specific so the device's in-progress draft and
// the portal's draft don't collide. The order log here is the iPad's local
// view — when Supabase comes online, both ends will write to the same backend.
const IPAD_TRUCK_DRAFT_KEY  = 'ipad_truck_draft_v1';
const IPAD_TRUCK_ORDERS_KEY = 'ipad_truck_orders_v1';

// ------------------------------------------------------------------
// Formatters (locally-scoped; the portal has the same names exported as
// window.toFmt*, but we don't want to depend on portal scripts being
// loaded in the iPad app).
// ------------------------------------------------------------------
const toFmtDateTo = (iso) => {
  if (!iso) return '';
  const d = new Date(iso);
  return d.toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' });
};
const toFmtTimeTo = (iso) => {
  if (!iso) return '';
  const d = new Date(iso);
  return d.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' });
};
const toFmtQtyTo = (n) => {
  if (n === 0 || n === '0') return '0';
  const v = Number(n);
  if (!isFinite(v)) return '0';
  if (Math.abs(v - Math.round(v)) < 0.001) return String(Math.round(v));
  return v.toFixed(2).replace(/\.?0+$/, '');
};
const escapeHtmlTo = (s) => String(s ?? '').replace(/[&<>"']/g, c => ({
  '&':'&amp;', '<':'&lt;', '>':'&gt;', '"':'&quot;', "'":'&#39;',
})[c]);

// Persist helper hook (used by draft + orders) — small wrapper around
// useState that mirrors the value into localStorage so reloads keep state.
const usePersistedTo = (key, initial) => {
  const [val, setVal] = useTo(() => {
    try {
      const raw = localStorage.getItem(key);
      return raw ? JSON.parse(raw) : initial;
    } catch { return initial; }
  });
  useEffectTo(() => {
    try {
      if (val === null || val === undefined) localStorage.removeItem(key);
      else localStorage.setItem(key, JSON.stringify(val));
    } catch {}
  }, [val]);
  return [val, setVal];
};

// ------------------------------------------------------------------
// Top-level Truck Order screen
// ------------------------------------------------------------------
const TruckOrderScreen = ({ onExitFullscreen, showToast }) => {
  // Flow state: 'list' | 'counting' | 'summary'
  const [flow, setFlow] = useTo({ kind: 'list', orderId: null });

  // Persisted state: in-progress draft + order log
  const [draft, setDraft]   = usePersistedTo(IPAD_TRUCK_DRAFT_KEY, null);
  const [orders, setOrders] = usePersistedTo(IPAD_TRUCK_ORDERS_KEY, []);

  // PIN gate state (shared by start + finalize)
  const [pinGate, setPinGate] = useTo(null);

  // Pars + inventory come from data files (same source the portal uses)
  const pars = window.SAMPLE_TRUCK_PARS || {};

  // ---------- actions ----------
  const startNewOrder = () => {
    setPinGate({
      purpose: 'Start truck order',
      onSuccess: (staff) => {
        const items = (window.SAMPLE_INVENTORY_ITEMS || []).filter(i => (pars[i.id] || {}).active !== false);
        const newDraft = {
          id: 'to-' + Date.now().toString(36),
          createdAt: new Date().toISOString(),
          createdByStaffId: staff.id,
          note: '',
          excludedVendorIds: [],
          lines: items.map(it => ({
            itemId: it.id,
            countStorage: '',
            countPurchase: '',
            skipped: false,
            finalOverride: null,
          })),
        };
        setDraft(newDraft);
        setFlow({ kind: 'counting', orderId: newDraft.id });
        setPinGate(null);
      },
    });
  };

  const resumeDraft = () => {
    if (!draft) return;
    setFlow({ kind: 'counting', orderId: draft.id });
  };

  const updateDraftLine = (itemId, patch) =>
    setDraft(d => d ? ({ ...d, lines: d.lines.map(l => l.itemId === itemId ? { ...l, ...patch } : l) }) : d);
  const updateDraftMeta = (patch) => setDraft(d => d ? ({ ...d, ...patch }) : d);

  const cancelDraft = () => {
    if (!confirm('Discard this count? All entered counts will be lost.')) return;
    setDraft(null);
    setFlow({ kind: 'list' });
  };

  const finalizeDraft = () => {
    if (!draft) return;
    setPinGate({
      purpose: 'Finalize truck order',
      onSuccess: (staff) => {
        const excluded = new Set(draft.excludedVendorIds || []);
        const keptLines = draft.lines.filter(l => {
          if (l.skipped) return false;
          const item = (window.SAMPLE_INVENTORY_ITEMS || []).find(i => i.id === l.itemId);
          return item && !excluded.has(item.vendorId);
        });
        const snapshot = {
          ...draft,
          finalizedAt: new Date().toISOString(),
          finalizedByStaffId: staff.id,
          lines: keptLines.map(l => {
            const item = (window.SAMPLE_INVENTORY_ITEMS || []).find(i => i.id === l.itemId);
            const onHand = window.truckOnHand(item, l.countStorage, l.countPurchase);
            const suggested = window.truckSuggested(pars[l.itemId], onHand);
            const final = (l.finalOverride === null || l.finalOverride === undefined || l.finalOverride === '')
              ? suggested
              : Number(l.finalOverride);
            return {
              itemId: l.itemId,
              countStorage: Number(l.countStorage) || 0,
              countPurchase: Number(l.countPurchase) || 0,
              suggested,
              final,
              overridden: final !== suggested,
            };
          }),
        };
        setOrders(prev => [snapshot, ...prev]);
        setDraft(null);
        setFlow({ kind: 'summary', orderId: snapshot.id });
        setPinGate(null);
        showToast && showToast({ message: 'Truck order finalized', icon: 'check', staff });
      },
    });
  };

  const viewOrder = (id) => setFlow({ kind: 'summary', orderId: id });
  const backToList = () => setFlow({ kind: 'list' });

  const deleteOrder = (id) => {
    if (!confirm('Delete this order? This cannot be undone.')) return;
    setOrders(prev => prev.filter(o => o.id !== id));
    backToList();
  };

  const summaryOrder = useMemoTo(() => {
    if (flow.kind !== 'summary') return null;
    return orders.find(o => o.id === flow.orderId);
  }, [flow, orders]);

  // ---------- render ----------
  if (flow.kind === 'counting' && draft) {
    return (
      <>
        <TruckOrderCount
          draft={draft}
          pars={pars}
          onUpdateLine={updateDraftLine}
          onUpdateMeta={updateDraftMeta}
          onCancel={cancelDraft}
          onFinalize={finalizeDraft}
        />
        {pinGate && (
          <TruckPinGate
            purpose={pinGate.purpose}
            onCancel={() => setPinGate(null)}
            onSuccess={pinGate.onSuccess}
          />
        )}
      </>
    );
  }

  if (flow.kind === 'summary' && summaryOrder) {
    return (
      <TruckOrderSummaryView
        order={summaryOrder}
        onBack={backToList}
        onDelete={() => deleteOrder(summaryOrder.id)}
      />
    );
  }

  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
      <TruckOrderList
        draft={draft}
        orders={orders}
        onStartNew={startNewOrder}
        onResume={resumeDraft}
        onViewOrder={viewOrder}
      />
      {pinGate && (
        <TruckPinGate
          purpose={pinGate.purpose}
          onCancel={() => setPinGate(null)}
          onSuccess={pinGate.onSuccess}
        />
      )}
    </div>
  );
};

// ------------------------------------------------------------------
// List — orders log + draft banner + start button
// ------------------------------------------------------------------
const TruckOrderList = ({ draft, orders, onStartNew, onResume, onViewOrder }) => {
  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
      {/* Header */}
      <div style={{
        padding: '16px 28px 12px',
        borderBottom: '1px solid var(--border-1)',
        background: 'var(--bg-surface)',
      }}>
        <div style={{ fontSize: 13, fontWeight: 600, letterSpacing: '0.12em', textTransform: 'uppercase', color: 'var(--fg-3)' }}>
          Truck Order
        </div>
        <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 16, marginTop: 4 }}>
          <div>
            <div style={{ fontSize: 28, fontWeight: 600, letterSpacing: '-0.025em', color: 'var(--fg-1)' }}>
              {orders.length === 0 ? 'Ready to count' : 'Recent orders'}
            </div>
            <div style={{ fontSize: 14, color: 'var(--fg-2)', marginTop: 2 }}>
              Count what's on hand, then we'll suggest what to order.
            </div>
          </div>
          <Btn variant="primary" size="lg" icon="plus" onClick={onStartNew}>New order</Btn>
        </div>
      </div>

      {/* Body */}
      <div className="scroll-soft" style={{ flex: 1, overflowY: 'auto', padding: '20px 28px 28px' }}>
        {draft && (
          <button onClick={onResume} style={{
            width: '100%',
            textAlign: 'left',
            padding: '16px 18px',
            marginBottom: 18,
            background: '#FFF8EC',
            border: '1px solid #F0CB7D',
            borderRadius: 14,
            display: 'flex', alignItems: 'center', gap: 14,
          }}>
            <span style={{
              fontSize: 10.5, fontWeight: 700, color: '#92400E',
              background: '#FDE68A', padding: '4px 9px', borderRadius: 5,
              letterSpacing: '0.06em',
            }}>IN PROGRESS</span>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 15, fontWeight: 600, color: 'var(--fg-1)' }}>Resume in-progress count</div>
              <div style={{ fontSize: 12.5, color: 'var(--fg-2)', marginTop: 2 }}>
                Started {toFmtDateTo(draft.createdAt)} ·{' '}
                {draft.lines.filter(l => l.skipped || l.countStorage !== '' || l.countPurchase !== '').length} of {draft.lines.length} items handled
              </div>
            </div>
            <Icon name="chevron" size={20} color="var(--fg-2)" />
          </button>
        )}

        {orders.length === 0 ? (
          <div style={{
            padding: 36,
            textAlign: 'center',
            background: '#FFFFFF',
            border: '1px dashed var(--border-1)',
            borderRadius: 14,
            color: 'var(--fg-2)',
            fontSize: 14, lineHeight: 1.6,
          }}>
            No past orders yet.<br/>
            Tap <b style={{ color: 'var(--fg-1)' }}>New order</b> to start counting.
          </div>
        ) : (
          <div style={{
            background: '#FFFFFF',
            border: '1px solid var(--border-2)',
            borderRadius: 14,
            overflow: 'hidden',
          }}>
            {orders.map((o, i) => (
              <OrderRow key={o.id} order={o} onClick={() => onViewOrder(o.id)} isLast={i === orders.length - 1} />
            ))}
          </div>
        )}
      </div>
    </div>
  );
};

const OrderRow = ({ order, onClick, isLast }) => {
  const finalizer = window.SAMPLE_STAFF.find(s => s.id === order.finalizedByStaffId);
  const totalOrdered = order.lines.filter(l => l.final > 0).length;
  const overrides = order.lines.filter(l => l.overridden).length;
  return (
    <button onClick={onClick} style={{
      display: 'flex', alignItems: 'center', gap: 14,
      width: '100%', textAlign: 'left',
      padding: '14px 18px',
      borderBottom: isLast ? 'none' : '1px solid var(--border-2)',
      background: 'transparent',
      transition: 'background 120ms ease',
    }}
    onMouseEnter={e => e.currentTarget.style.background = '#FBFAF8'}
    onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
    >
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 15, fontWeight: 600, color: 'var(--fg-1)', letterSpacing: '-0.005em' }}>
          {toFmtDateTo(order.finalizedAt)}
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: 4, fontSize: 12.5, color: 'var(--fg-2)' }}>
          {finalizer && (
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
              <Avatar staff={finalizer} size={20} />
              {finalizer.name}
            </span>
          )}
          <span style={{ color: 'var(--fg-3)' }}>·</span>
          <span style={{ fontFamily: 'var(--font-num)' }}>{totalOrdered} line{totalOrdered === 1 ? '' : 's'} ordered</span>
          {overrides > 0 && (
            <>
              <span style={{ color: 'var(--fg-3)' }}>·</span>
              <span style={{
                fontSize: 11, fontWeight: 600, color: '#92400E',
                background: '#FDE68A', padding: '2px 7px', borderRadius: 999,
                fontFamily: 'var(--font-num)',
              }}>{overrides} override</span>
            </>
          )}
        </div>
      </div>
      <Icon name="chevron" size={18} color="var(--fg-3)" />
    </button>
  );
};

// ------------------------------------------------------------------
// PIN gate — modal with the iPad's existing NumPad component.
// Reused for both start + finalize.
// ------------------------------------------------------------------
const TruckPinGate = ({ purpose, onCancel, onSuccess }) => {
  const [pin, setPin] = useTo('');
  const [err, setErr] = useTo('');
  const [shake, setShake] = useTo(false);

  const tryPin = (p) => {
    const staff = window.SAMPLE_STAFF.find(s => s.pin === p);
    if (staff) {
      onSuccess(staff);
    } else {
      setErr('PIN not recognized');
      setShake(true);
      setTimeout(() => setShake(false), 450);
      setTimeout(() => { setPin(''); setErr(''); }, 600);
    }
  };

  return (
    <Modal open={true} onClose={onCancel} width={420}>
      <div style={{ padding: '24px 24px 22px', textAlign: 'center' }}>
        <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--fg-3)', textTransform: 'uppercase', letterSpacing: '0.08em' }}>
          PIN required
        </div>
        <div style={{ fontSize: 19, fontWeight: 600, color: 'var(--fg-1)', letterSpacing: '-0.015em', marginTop: 6, marginBottom: 20 }}>
          {purpose}
        </div>

        <div style={{
          display: 'flex', justifyContent: 'center', gap: 14,
          marginBottom: 8,
          animation: shake ? 'pinShake 0.45s ease' : undefined,
        }}>
          {[0,1,2,3].map(i => (
            <div key={i} style={{
              width: 18, height: 18, borderRadius: 999,
              background: i < pin.length ? 'var(--fg-1)' : 'transparent',
              border: '2px solid ' + (err ? 'var(--danger)' : 'var(--border-1)'),
              transition: 'all 120ms ease',
            }} />
          ))}
        </div>
        <div style={{ height: 18, fontSize: 12.5, color: err ? 'var(--danger)' : 'var(--fg-3)', marginBottom: 16 }}>
          {err || 'Enter your 4-digit PIN'}
        </div>

        <NumPad
          value={pin}
          onChange={setPin}
          onEnter={tryPin}
          maxLen={4}
        />

        <div style={{ marginTop: 18 }}>
          <Btn variant="ghost" onClick={onCancel} fullWidth>Cancel</Btn>
        </div>
      </div>
      <style>{`
        @keyframes pinShake {
          0%, 100% { transform: translateX(0); }
          20% { transform: translateX(-8px); }
          40% { transform: translateX(8px); }
          60% { transform: translateX(-4px); }
          80% { transform: translateX(4px); }
        }
      `}</style>
    </Modal>
  );
};

Object.assign(window, {
  TruckOrderScreen,
  // formatters + helpers used by sibling truck-order files
  toFmtDateTo, toFmtTimeTo, toFmtQtyTo, escapeHtmlTo,
});
