/* GarageWiz — Dealer / Cost Panel (PIN-gated slide-out, hidden from customer) */
(function () {
  const e = React.createElement;
  const { useState, useEffect, useRef } = React;
  const Icon = window.Icon, Btn = window.Btn;

  function PinPad({ onSubmit, error }) {
    const [pin, setPin] = useState('');
    const press = (d) => { if (pin.length < 4) { const np = pin + d; setPin(np); if (np.length === 4) setTimeout(() => { onSubmit(np); setPin(''); }, 120); } };
    const del = () => setPin(p => p.slice(0, -1));
    return e('div', { style: { padding: '34px 30px', textAlign: 'center' } },
      e('div', { style: { width: 60, height: 60, borderRadius: 18, background: 'rgba(245,224,65,.15)', display: 'grid', placeItems: 'center', margin: '0 auto 16px', color: 'var(--yellow)' } }, e(Icon, { name: 'lock', size: 28 })),
      e('div', { className: 'display', style: { fontSize: 22, fontWeight: 600, color: '#fff' } }, 'Dealer view'),
      e('div', { style: { color: 'rgba(255,255,255,.6)', fontSize: 13.5, marginTop: 5, marginBottom: 22 } }, 'Enter your 4-digit PIN'),
      e('div', { style: { display: 'flex', gap: 12, justifyContent: 'center', marginBottom: 22 } },
        [0, 1, 2, 3].map(i => e('div', { key: i, style: { width: 16, height: 16, borderRadius: 999, background: i < pin.length ? 'var(--yellow)' : 'rgba(255,255,255,.18)', transition: 'background .15s' } })),
      ),
      error ? e('div', { style: { color: '#FF8A7E', fontSize: 13.5, fontWeight: 600, marginBottom: 14 } }, 'Wrong PIN — try again') : null,
      e('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 12, maxWidth: 240, margin: '0 auto' } },
        ['1', '2', '3', '4', '5', '6', '7', '8', '9', '', '0', 'del'].map((k, i) =>
          k === '' ? e('div', { key: i }) :
          e('button', {
            key: i, onClick: () => k === 'del' ? del() : press(k),
            style: { height: 56, borderRadius: 14, border: 'none', cursor: 'pointer', background: 'rgba(255,255,255,.08)', color: '#fff', fontFamily: 'var(--display)', fontWeight: 600, fontSize: k === 'del' ? 16 : 22, display: 'grid', placeItems: 'center' },
          }, k === 'del' ? e(Icon, { name: 'back', size: 20 }) : k)),
      ),
      e('div', { style: { color: 'rgba(255,255,255,.35)', fontSize: 12, marginTop: 18 } }, 'Demo PIN: ' + (window.GW.defaultSettings.dealerPin)),
    );
  }

  function Stat({ label, value, accent, big }) {
    return e('div', { style: { display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', gap: 12, padding: big ? '14px 0' : '11px 0', borderBottom: '1px solid rgba(255,255,255,.1)' } },
      e('div', { style: { color: 'rgba(255,255,255,.7)', fontSize: big ? 14 : 13.5, fontWeight: 600 } }, label),
      e('div', { className: 'display num', style: { fontSize: big ? 26 : 18, fontWeight: 600, color: accent || '#fff' } }, value),
    );
  }

  function DealerPanel() {
    const app = window.useApp();
    const [error, setError] = useState(false);
    const open = !!app.dealer;
    // Dealer View is admin-only AND always PIN-protected (even for admins),
    // so it can't be opened accidentally while presenting to a customer.
    const isAdmin = !!(app.user && app.user.role === 'admin');
    const unlocked = isAdmin && app.dealerUnlocked;
    // Dealer View follows what's on screen: the whole estimate (cart) when
    // viewing it, otherwise the single door being configured.
    const onEstimate = app.route.section === 'estimate' && app.estimate && app.estimate.items && app.estimate.items.length;
    const result = onEstimate ? GW.computeEstimate(app.estimate, app.settings) : GW.compute(app.config, app.settings);
    const s = result.settings;
    const ready = onEstimate ? !result.empty : result.configured;

    function checkPin(p) {
      if (p === String(s.dealerPin)) { setError(false); app.setDealerUnlocked(true); }
      else { setError(true); setTimeout(() => setError(false), 1200); }
    }

    const marginPct = ready ? result.margin : 0;
    const floorPct = s.floorMargin;
    const targetPct = s.targetMargin;
    // bar scale 0..(target+0.1)
    const scaleMax = targetPct + 0.08;
    const barPct = (v) => Math.max(0, Math.min(100, (v / scaleMax) * 100));

    // dealer slider sets a manual discount and clears any coupon (they're one field)
    const setDiscount = (d) => onEstimate
      ? app.updateEstimate({ discount: Math.round(d), couponCode: null })
      : app.setConfig(Object.assign({}, app.config, { discount: Math.round(d), couponCode: null }));

    return e(React.Fragment, null,
      // scrim
      open ? e('div', { onClick: app.closeDealer, style: { position: 'fixed', inset: 0, background: 'rgba(1,30,40,.4)', zIndex: 150, animation: 'gw-fade .15s ease' } }) : null,
      // panel
      e('aside', {
        style: {
          position: 'fixed', top: 0, right: 0, height: '100%', width: 'min(420px, 92vw)', zIndex: 160,
          background: 'var(--navy-deep)', boxShadow: '-20px 0 60px rgba(0,0,0,.4)',
          transform: open ? 'translateX(0)' : 'translateX(105%)', transition: 'transform .32s cubic-bezier(.3,.7,.2,1)',
          display: 'flex', flexDirection: 'column', overflow: 'hidden',
        },
      },
        // header
        e('div', { style: { display: 'flex', alignItems: 'center', gap: 10, padding: '16px 20px', borderBottom: '1px solid rgba(255,255,255,.1)', background: 'rgba(0,0,0,.2)' } },
          e('div', { style: { width: 9, height: 9, borderRadius: 999, background: '#FF6B5B', boxShadow: '0 0 8px #FF6B5B' } }),
          e('div', { className: 'grow' },
            e('div', { className: 'display', style: { color: '#fff', fontSize: 16, fontWeight: 600 } }, 'Dealer View'),
            e('div', { style: { color: 'var(--yellow)', fontSize: 11.5, fontWeight: 700, letterSpacing: '.04em' } }, 'HIDDEN FROM CUSTOMER'),
          ),
          e('button', { onClick: app.closeDealer, style: { background: 'rgba(255,255,255,.1)', border: 'none', borderRadius: 999, width: 34, height: 34, display: 'grid', placeItems: 'center', color: '#fff', cursor: 'pointer' } }, e(Icon, { name: 'close', size: 18 })),
        ),

        !isAdmin
          ? e('div', { style: { padding: 40, textAlign: 'center', color: 'rgba(255,255,255,.7)' } }, e(Icon, { name: 'lock', size: 28, style: { marginBottom: 10 } }), e('div', null, 'Dealer View is available to admins only.'))
          : !unlocked
          ? e(PinPad, { onSubmit: checkPin, error })
          : !ready
            ? e('div', { style: { padding: 40, textAlign: 'center', color: 'rgba(255,255,255,.6)' } }, e(Icon, { name: 'info', size: 28, style: { marginBottom: 10 } }), e('div', null, onEstimate ? 'Add items to the estimate to see the numbers.' : 'Configure a door to see the numbers.'))
            : e('div', { style: { padding: '20px 22px 30px', overflowY: 'auto' } },
              // margin bar
              e('div', { style: { background: 'rgba(255,255,255,.05)', borderRadius: 16, padding: '16px 16px 18px', marginBottom: 18 } },
                e('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 12 } },
                  e('div', { style: { color: 'rgba(255,255,255,.7)', fontSize: 13, fontWeight: 600, whiteSpace: 'nowrap' } }, 'Current margin'),
                  e('div', { className: 'display num', style: { fontSize: 30, fontWeight: 700, color: result.atFloor ? '#FF8A7E' : marginPct >= targetPct - 0.001 ? 'var(--yellow)' : '#8FE3FF' } }, GW.pct(marginPct)),
                ),
                e('div', { style: { position: 'relative', height: 14, background: 'rgba(255,255,255,.1)', borderRadius: 999 } },
                  // floor zone
                  e('div', { style: { position: 'absolute', left: 0, top: 0, bottom: 0, width: barPct(floorPct) + '%', background: 'rgba(255,107,91,.3)', borderRadius: '999px 0 0 999px' } }),
                  // fill
                  e('div', { style: { position: 'absolute', left: 0, top: 0, bottom: 0, width: barPct(marginPct) + '%', background: result.atFloor ? '#FF6B5B' : 'linear-gradient(90deg,#00B1ED,#F5E041)', borderRadius: 999, transition: 'width .25s' } }),
                  // floor marker
                  e('div', { style: { position: 'absolute', left: barPct(floorPct) + '%', top: -4, bottom: -4, width: 2, background: '#FF6B5B' } }),
                  // target marker
                  e('div', { style: { position: 'absolute', left: barPct(targetPct) + '%', top: -4, bottom: -4, width: 2, background: 'var(--yellow)' } }),
                ),
                e('div', { style: { display: 'flex', justifyContent: 'space-between', marginTop: 8, fontSize: 11, color: 'rgba(255,255,255,.5)', fontWeight: 600 } },
                  e('span', null, 'Floor ' + GW.pct(floorPct)), e('span', null, 'Target ' + GW.pct(targetPct))),
              ),

              // cost buildup
              onEstimate
                ? e('div', { style: { background: 'rgba(255,255,255,.05)', borderRadius: 16, padding: '14px 16px', marginBottom: 14 } },
                    e('div', { style: { color: 'rgba(255,255,255,.6)', fontSize: 11, fontWeight: 800, letterSpacing: '.08em', marginBottom: 8 } }, 'ESTIMATE COST (' + result.itemCount + ' item' + (result.itemCount === 1 ? '' : 's') + ')'),
                    result.lines.map(l => e('div', { key: l.idx, style: { display: 'flex', justifyContent: 'space-between', gap: 10, padding: '5px 0', fontSize: 13 } },
                      e('span', { style: { color: 'rgba(255,255,255,.8)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, (l.qty > 1 ? l.qty + '× ' : '') + l.label),
                      e('span', { className: 'num', style: { color: '#fff', fontWeight: 600, flexShrink: 0 } }, GW.fmtCents(l.cost)),
                    )),
                    e('div', { style: { display: 'flex', justifyContent: 'space-between', padding: '7px 0 2px', marginTop: 4, borderTop: '1px solid rgba(255,255,255,.12)', fontSize: 14, whiteSpace: 'nowrap' } },
                      e('span', { style: { color: '#fff', fontWeight: 700 } }, '= Total cost (incl. tax)'),
                      e('span', { className: 'num', style: { color: 'var(--yellow)', fontWeight: 700 } }, GW.fmtCents(result.cost))),
                    e('div', { style: { color: 'rgba(255,255,255,.45)', fontSize: 11, marginTop: 8, lineHeight: 1.45 } }, 'Each line keeps its own margin & floor; the discount room below is the whole order down to the floor.'),
                  )
                : e('div', { style: { background: 'rgba(255,255,255,.05)', borderRadius: 16, padding: '14px 16px', marginBottom: 14 } },
                    e('div', { style: { color: 'rgba(255,255,255,.6)', fontSize: 11, fontWeight: 800, letterSpacing: '.08em', marginBottom: 8 } }, 'COST BUILDUP'),
                    result.lines.concat(result.addonLines).map(l => e('div', { key: l.key, style: { display: 'flex', justifyContent: 'space-between', gap: 10, padding: '5px 0', fontSize: 13 } },
                      e('span', { style: { color: 'rgba(255,255,255,.8)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, l.label + ((result.qty || 1) > 1 ? ' × ' + result.qty : '')),
                      e('span', { className: 'num', style: { color: '#fff', fontWeight: 600, flexShrink: 0 } }, GW.fmtCents(l.sell * (result.qty || 1))),
                    )),
                    e('div', { style: { display: 'flex', justifyContent: 'space-between', padding: '7px 0 5px', marginTop: 4, borderTop: '1px solid rgba(255,255,255,.12)', fontSize: 13, whiteSpace: 'nowrap' } },
                      e('span', { style: { color: 'rgba(255,255,255,.8)', fontWeight: 700 } }, 'Subtotal'),
                      e('span', { className: 'num', style: { color: '#fff', fontWeight: 700 } }, GW.fmtCents(result.sell))),
                    e('div', { style: { display: 'flex', justifyContent: 'space-between', padding: '5px 0', fontSize: 13, whiteSpace: 'nowrap' } },
                      e('span', { style: { color: 'rgba(255,255,255,.6)' } }, '+ Tax (' + GW.pct(s.taxRate) + ')'),
                      e('span', { className: 'num', style: { color: 'rgba(255,255,255,.85)' } }, GW.fmtCents(result.tax))),
                    e('div', { style: { display: 'flex', justifyContent: 'space-between', padding: '7px 0 2px', borderTop: '1px solid rgba(255,255,255,.12)', fontSize: 14, whiteSpace: 'nowrap' } },
                      e('span', { style: { color: '#fff', fontWeight: 700 } }, '= Total cost'),
                      e('span', { className: 'num', style: { color: 'var(--yellow)', fontWeight: 700 } }, GW.fmtCents(result.cost))),
                    e('div', { style: { color: 'rgba(255,255,255,.45)', fontSize: 11, marginTop: 8, lineHeight: 1.45 } }, '÷ ' + (1 - s.targetMargin).toFixed(2) + ' (' + GW.pct(s.targetMargin) + ' margin on the combined total)' + (result.floorRuleApplied ? ' — below floor, so price = cost + $' + result.minProfit.toLocaleString() : '')),
                  ),

              // numbers
              e('div', { style: { marginBottom: 18 } },
                e(Stat, { label: 'Customer price', value: GW.fmt(result.price), accent: '#8FE3FF', big: true }),
                e(Stat, { label: 'Gross profit', value: GW.fmt(result.profit), accent: 'var(--yellow)', big: true }),
                e(Stat, { label: 'Min price @ ' + GW.pct(floorPct) + ' floor', value: GW.fmt(result.floorPrice), accent: '#FF8A7E' }),
              ),

              // discount control
              e('div', { style: { background: 'rgba(255,255,255,.05)', borderRadius: 16, padding: '16px' } },
                e('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 4 } },
                  e('div', { style: { color: '#fff', fontWeight: 700, fontSize: 14 } }, 'Discount room'),
                  e('div', { className: 'display num', style: { color: 'var(--yellow)', fontSize: 18, fontWeight: 600 } }, GW.fmt(result.maxDiscount - result.discount) + ' left'),
                ),
                e('div', { style: { color: 'rgba(255,255,255,.55)', fontSize: 12, marginBottom: 12 } }, 'How much you can come down before the ' + GW.pct(floorPct) + ' floor.'),
                e('input', {
                  type: 'range', min: 0, max: Math.max(1, result.maxDiscount), step: 10, value: result.discount,
                  onChange: ev => setDiscount(Number(ev.target.value)),
                  className: 'dealer-range', style: { width: '100%' },
                }),
                e('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: 12 } },
                  e('div', null,
                    e('div', { style: { color: 'rgba(255,255,255,.55)', fontSize: 11.5, fontWeight: 700 } }, 'APPLIED DISCOUNT'),
                    e('div', { className: 'display num', style: { color: '#fff', fontSize: 22, fontWeight: 600 } }, '−' + GW.fmt(result.discount)),
                  ),
                  e('div', { style: { display: 'flex', gap: 6 } },
                    [0, 250, 500].map(d => e('button', { key: d, onClick: () => setDiscount(d), disabled: d > result.maxDiscount, style: { border: '1px solid rgba(255,255,255,.2)', background: result.discount === d ? 'var(--yellow)' : 'transparent', color: result.discount === d ? 'var(--ink)' : '#fff', borderRadius: 999, padding: '7px 12px', fontFamily: 'var(--display)', fontWeight: 600, fontSize: 13, cursor: 'pointer', opacity: d > result.maxDiscount ? .35 : 1 } }, d === 0 ? 'Reset' : '$' + d)),
                  ),
                ),
              ),

              e('div', { style: { marginTop: 18, color: 'rgba(255,255,255,.45)', fontSize: 11.5, lineHeight: 1.5, display: 'flex', gap: 8 } },
                e(Icon, { name: 'info', size: 15, style: { flexShrink: 0, marginTop: 1 } }),
                onEstimate
                  ? 'Every line keeps its own minimum-profit floor. The discount above is clamped to the whole order’s floor — never below minimum.'
                  : ('The $' + (result.minProfit || s.minProfitDoor).toLocaleString() + ' minimum profit floor (doors) is applied silently — no labor line is ever shown to the customer.')),
            ),
      ),
    );
  }
  window.DealerPanel = DealerPanel;
})();
