/* GarageWiz — Quote Summary (customer-facing, no cost breakdown) */
(function () {
  const e = React.createElement;
  const { useState, useEffect } = React;
  const Icon = window.Icon, Btn = window.Btn, Badge = window.Badge, Input = window.Input, Field = window.Field,
        DoorPreview = window.DoorPreview, Modal = window.Modal, Mascot = window.Mascot;

  function QuoteSummary() {
    const app = window.useApp();
    const config = app.config;
    const result = GW.compute(config, app.settings);
    const [cust, setCust] = useState(config.customer || { name: '', phone: '', email: '' });
    const [code, setCode] = useState(config.couponCode || '');
    const [cpErr, setCpErr] = useState('');
    const model = GW.findModel(config.modelCode);
    const height = GW.findHeight(config.heightId);
    const special = config.width && !(GW.widths.find(w => w.ft === config.width) || {}).std;

    const applyCoupon = () => {
      const cp = GW.findCoupon(code);
      if (!cp) { setCpErr('Invalid or inactive code.'); return; }
      setCpErr(''); app.setConfig(Object.assign({}, config, { couponCode: cp.code, discount: 0 }));
    };
    const removeCoupon = () => { setCode(''); setCpErr(''); app.setConfig(Object.assign({}, config, { couponCode: null, discount: 0 })); };

    // stamp the offer date once, the first time a quote is generated
    useEffect(() => { if (!config.quoteDate) app.setConfig(Object.assign({}, config, { quoteDate: new Date().toISOString() })); }, []);
    const validity = GW.quoteValidity(config.quoteDate, app.settings);

    // share-for-admin-review
    const [shareOpen, setShareOpen] = useState(false);
    const [shareNote, setShareNote] = useState('');
    const buildSnapshot = () => ({ v: 1, config: Object.assign({}, app.config, { customer: cust }), note: shareNote, rep: (app.user && app.user.name) || 'Sales rep', ts: Date.now() });
    const reviewLink = (snap) => location.origin + location.pathname + '#/review/' + GW.encodeReview(snap);
    const shareReview = () => {
      const snap = buildSnapshot();
      const link = reviewLink(snap);
      GW.reviews.unshift({ id: 'rv' + Date.now(), rep: snap.rep, note: shareNote, customer: cust.name || '', price: result.price, data: GW.encodeReview(snap), ts: snap.ts, status: 'pending' });
      GW.saveReviews();
      try { navigator.clipboard && navigator.clipboard.writeText(link).then(() => app.toast('Review link copied — send it to your admin.')); } catch (e) {}
      return link;
    };

    if (!result.configured) {
      return e('div', { style: { maxWidth: 760, margin: '0 auto', padding: '60px 24px' } },
        e(window.EmptyState, {
          title: 'Nothing to summarize yet', sub: 'Build a door first, then come back to present the quote.',
          action: e(Btn, { variant: 'primary', icon: 'door', onClick: () => app.go('#/doors') }, 'Build a door'),
        }),
      );
    }

    const specLines = result.lines.concat(result.addonLines);

    function downloadPdf() {
      const jsPDFns = window.jspdf;
      if (!jsPDFns || !jsPDFns.jsPDF) { app.toast('PDF tool still loading — try again in a moment.'); return; }
      const doc = new jsPDFns.jsPDF({ unit: 'pt', format: 'letter' });
      const W = doc.internal.pageSize.getWidth();
      const M = 48;

      // header band
      doc.setFillColor(0, 95, 122);
      doc.rect(0, 0, W, 96, 'F');
      doc.setTextColor(255, 255, 255);
      doc.setFont('helvetica', 'bold'); doc.setFontSize(26);
      doc.text('GarageWiz', M, 50);
      doc.setFont('helvetica', 'normal'); doc.setFontSize(10);
      doc.setTextColor(245, 224, 65);
      doc.text('OVERHEAD DOORS', M, 68);
      doc.setTextColor(255, 255, 255); doc.setFontSize(11);
      doc.text('Your custom quote', W - M, 44, { align: 'right' });
      doc.setFontSize(10);
      doc.text(validity.issuedLabel, W - M, 62, { align: 'right' });
      doc.setFontSize(9); doc.setTextColor(245, 224, 65);
      doc.text('Valid through ' + validity.expiresLabel, W - M, 77, { align: 'right' });

      let y = 134;
      doc.setTextColor(25, 25, 25);

      if (cust.name || cust.phone || cust.email) {
        doc.setFont('helvetica', 'bold'); doc.setFontSize(10); doc.setTextColor(120, 120, 120);
        doc.text('PREPARED FOR', M, y); y += 18;
        doc.setTextColor(25, 25, 25); doc.setFontSize(15);
        if (cust.name) { doc.text(cust.name, M, y); y += 18; }
        const contact = [cust.phone, cust.email].filter(Boolean).join('   ·   ');
        if (contact) { doc.setFont('helvetica', 'normal'); doc.setFontSize(11); doc.setTextColor(110, 110, 110); doc.text(contact, M, y); y += 14; }
        y += 14;
      }

      doc.setFont('helvetica', 'bold'); doc.setFontSize(10); doc.setTextColor(120, 120, 120);
      doc.text('YOUR CONFIGURATION' + (result.qty > 1 ? '  (×' + result.qty + ' DOORS)' : ''), M, y); y += 8;
      doc.setDrawColor(225, 225, 225); doc.line(M, y, W - M, y); y += 22;

      specLines.forEach(l => {
        doc.setFont('helvetica', 'bold'); doc.setFontSize(12.5); doc.setTextColor(25, 25, 25);
        doc.text(String(l.label), M, y);
        if (l.sub) { doc.setFont('helvetica', 'normal'); doc.setFontSize(10.5); doc.setTextColor(130, 130, 130); doc.text(String(l.sub), M, y + 15); y += 34; }
        else { y += 24; }
        doc.setDrawColor(238, 238, 238); doc.line(M, y - 10, W - M, y - 10);
      });

      y += 16;
      // total box
      doc.setFillColor(0, 95, 122);
      doc.roundedRect(M, y, W - M * 2, 78, 8, 8, 'F');
      doc.setTextColor(245, 224, 65); doc.setFont('helvetica', 'bold'); doc.setFontSize(10);
      doc.text('TOTAL · FULLY INSTALLED' + (result.qty > 1 ? ' (' + result.qty + ' DOORS · ' + GW.fmt(result.unitPrice) + ' EA)' : ''), M + 22, y + 30);
      doc.setTextColor(255, 255, 255); doc.setFontSize(30);
      doc.text(GW.fmt(result.price), W - M - 22, y + 44, { align: 'right' });
      doc.setFont('helvetica', 'normal'); doc.setFontSize(9); doc.setTextColor(220, 235, 240);
      doc.text('Includes professional installation, hardware, and haul-away of your old door.', M + 22, y + 56);
      y += 100;

      if (result.bundleSavings > 0) {
        doc.setFont('helvetica', 'bold'); doc.setFontSize(10.5); doc.setTextColor(34, 150, 94);
        doc.text('You saved ' + GW.fmt(result.bundleSavings) + ' with package pricing.', M, y); y += 22;
      }
      if (result.discount > 0) {
        doc.setFont('helvetica', 'bold'); doc.setFontSize(10.5); doc.setTextColor(34, 150, 94);
        doc.text((result.coupon ? ('Coupon ' + result.coupon.code + ': ') : 'Discount: ') + '−' + GW.fmt(result.discount) + ' applied.', M, y); y += 22;
      }

      if (special) {
        doc.setFont('helvetica', 'normal'); doc.setFontSize(10); doc.setTextColor(150, 90, 10);
        const msg = doc.splitTextToSize(app.settings.leadTimeMsg, W - M * 2);
        doc.text(msg, M, y); y += msg.length * 13 + 10;
      }

      // customer approval / signature
      if (config.signature && config.signature.dataUrl) {
        doc.setFont('helvetica', 'bold'); doc.setFontSize(10); doc.setTextColor(120, 120, 120);
        doc.text('CUSTOMER APPROVAL', M, y); y += 6;
        doc.setDrawColor(225, 225, 225); doc.line(M, y, W - M, y); y += 10;
        try { doc.addImage(config.signature.dataUrl, 'PNG', M, y, 200, 64); } catch (e) {}
        doc.setFont('helvetica', 'normal'); doc.setFontSize(10); doc.setTextColor(25, 25, 25);
        const sWhen = new Date(config.signature.signedAt || Date.now()).toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' });
        doc.text('Approved by ' + (config.signature.name || 'Customer'), M, y + 80);
        doc.setTextColor(130, 130, 130); doc.text('Signed ' + sWhen, M, y + 95);
        y += 110;
      }

      doc.setFont('helvetica', 'normal'); doc.setFontSize(9); doc.setTextColor(160, 160, 160);
      doc.text('Backed by the GarageWiz workmanship guarantee.', M, 740);

      const safeName = (cust.name || 'GarageWiz-Quote').replace(/[^a-z0-9]+/gi, '-');
      doc.save(safeName + '.pdf');
      app.toast('Quote PDF downloaded');
    }

    return e('div', { style: { maxWidth: 1080, margin: '0 auto', padding: '28px 24px 80px' } },
      // toolbar
      e('div', { className: 'no-print', style: { display: 'flex', alignItems: 'center', gap: 12, marginBottom: 14, flexWrap: 'wrap' } },
        e(Btn, { variant: 'ghost', icon: 'arrowL', onClick: () => app.go('#/doors') }, 'Back to configurator'),
        e('div', { className: 'grow' }),
        e(Btn, { variant: 'ghost', icon: 'mail', onClick: () => setShareOpen(true) }, 'Share for review'),
        e(Btn, { variant: 'ghost', icon: 'print', onClick: () => window.print() }, 'Print'),
        e(Btn, { variant: 'ghost', icon: 'download', onClick: downloadPdf }, 'Download PDF'),
        e(Btn, { variant: 'primary', icon: 'plus', onClick: () => {
          app.addToEstimate({ type: 'door', config: JSON.parse(JSON.stringify(Object.assign({}, config, { couponCode: null, discount: 0, signature: null }))) });
          app.resetConfig(); app.toast('Door added to estimate'); app.go('#/estimate');
        } }, 'Add to estimate'),
      ),

      // validity banner
      e('div', { style: { display: 'flex', alignItems: 'center', gap: 9, marginBottom: 18, fontSize: 13.5, color: validity.expired ? 'var(--danger)' : 'var(--ink-2)' } },
        e(Icon, { name: validity.expired ? 'info' : 'check', size: 16, style: { color: validity.expired ? 'var(--danger)' : 'var(--good)' } }),
        validity.expired
          ? e('span', null, e('strong', null, 'This offer has expired'), ' — generated ' + validity.issuedLabel + '. Re-issue to refresh pricing.')
          : e('span', null, 'Offer valid through ', e('strong', null, validity.expiresLabel), ' · ' + validity.daysLeft + ' day' + (validity.daysLeft === 1 ? '' : 's') + ' left'),
      ),

      // quote sheet
      e('div', { className: 'card quote-sheet', style: { overflow: 'hidden' } },
        // header band
        e('div', { style: { background: 'linear-gradient(160deg, var(--teal) 0%, var(--teal-800) 100%)', color: '#fff', padding: '26px 34px', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 18, flexWrap: 'wrap' } },
          e('div', null,
            e(window.Wordmark, { height: 44 }),
          ),
          e('div', { style: { textAlign: 'right' } },
            e('div', { className: 'eyebrow', style: { color: 'var(--yellow)' } }, 'Your custom quote'),
            e('div', { style: { fontSize: 13.5, color: 'rgba(255,255,255,.8)', marginTop: 2 } }, new Date().toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' })),
          ),
        ),

        e('div', { className: 'quote-grid', style: { display: 'grid', gridTemplateColumns: '1fr 360px', gap: 0 } },
          // left: details
          e('div', { style: { padding: '30px 34px' } },
            // customer
            e('div', { className: 'no-print', style: { marginBottom: 26 } },
              e('div', { className: 'eyebrow', style: { marginBottom: 12 } }, 'Prepared for'),
              e('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 } },
                e(Field, { label: 'Customer name', style: { gridColumn: '1 / -1' } }, e(Input, { placeholder: 'e.g. The Hendersons', value: cust.name, onChange: ev => setCust(c => ({ ...c, name: ev.target.value })) })),
                e(Field, { label: 'Phone' }, e(Input, { placeholder: '(555) 123-4567', value: cust.phone, onChange: ev => setCust(c => ({ ...c, phone: ev.target.value })) })),
                e(Field, { label: 'Email' }, e(Input, { placeholder: 'name@email.com', value: cust.email, onChange: ev => setCust(c => ({ ...c, email: ev.target.value })) })),
              ),
            ),
            // print-only customer
            cust.name ? e('div', { className: 'print-only', style: { marginBottom: 22, display: 'none' } },
              e('div', { className: 'eyebrow', style: { marginBottom: 6 } }, 'Prepared for'),
              e('div', { style: { fontWeight: 700, fontSize: 17 } }, cust.name),
              e('div', { className: 'muted' }, [cust.phone, cust.email].filter(Boolean).join(' · ')),
            ) : null,

            e('div', { style: { display: 'flex', alignItems: 'center', gap: 10, marginBottom: 12 } },
              e('div', { className: 'eyebrow', style: { marginBottom: 0 } }, 'Your configuration'),
              result.qty > 1 ? e('span', { className: 'badge badge-prem' }, '× ' + result.qty + ' doors') : null,
            ),
            e('div', { style: { display: 'flex', flexDirection: 'column' } },
              specLines.map((l, i) => e('div', { key: l.key, style: { display: 'flex', alignItems: 'flex-start', gap: 12, padding: '13px 0', borderTop: i ? '1px solid var(--line)' : 'none' } },
                e('span', { style: { width: 26, height: 26, borderRadius: 999, background: 'var(--good-bg)', color: 'var(--good)', display: 'grid', placeItems: 'center', flexShrink: 0, marginTop: 1 } }, e(Icon, { name: 'check', size: 15, strokeWidth: 3 })),
                e('div', { className: 'grow' },
                  e('div', { style: { fontWeight: 700, fontSize: 15.5 } }, l.label),
                  l.sub ? e('div', { className: 'muted', style: { fontSize: 13.5 } }, l.sub) : null,
                ),
              )),
            ),

            special ? e('div', { style: { display: 'flex', gap: 10, alignItems: 'flex-start', background: 'var(--warn-bg)', borderRadius: 12, padding: '13px 15px', marginTop: 18 } },
              e(Icon, { name: 'truck', size: 20, style: { color: '#9A5B07', flexShrink: 0 } }),
              e('div', { style: { fontSize: 13, color: '#7A4A07' } }, app.settings.leadTimeMsg),
            ) : null,
          ),

          // right: visual + price
          e('div', { style: { background: 'var(--field)', padding: '30px 28px', borderLeft: '1px solid var(--line)' } },
            e(DoorPreview, { config, result }),
            e('div', { style: { marginTop: 22, background: '#fff', borderRadius: 'var(--r-lg)', padding: '22px', textAlign: 'center', boxShadow: 'var(--sh-1)' } },
              e('div', { className: 'eyebrow' }, 'Total · fully installed'),
              result.qty > 1 ? e('div', { style: { fontSize: 13, fontWeight: 700, color: 'var(--ink-2)', marginTop: 6 } }, result.qty + ' doors · ' + GW.fmt(result.unitPrice) + ' each') : null,
              result.discount > 0 ? e('div', { className: 'num', style: { fontSize: 18, color: 'var(--ink-3)', textDecoration: 'line-through', marginTop: 6 } }, GW.fmt(result.listPrice)) : null,
              e('div', { className: 'display num', style: { fontSize: 46, fontWeight: 700, color: 'var(--teal)', lineHeight: 1, margin: '8px 0' } }, GW.fmt(result.price)),
              result.discount > 0 ? e('div', { style: { display: 'inline-flex', alignItems: 'center', gap: 6, background: 'var(--good-bg)', color: 'var(--good)', borderRadius: 999, padding: '5px 12px', fontWeight: 700, fontSize: 13, margin: '0 0 10px' } },
                e(Icon, { name: 'tag', size: 14 }), (result.coupon ? (result.coupon.code + ' · ') : '') + 'You save ' + GW.fmt(result.discount)) : null,
              result.bundleSavings > 0 ? e('div', { style: { display: 'inline-flex', alignItems: 'center', gap: 6, background: 'var(--good-bg)', color: 'var(--good)', borderRadius: 999, padding: '5px 12px', fontWeight: 700, fontSize: 13, margin: '0 0 10px' } },
                e(Icon, { name: 'check', size: 14, strokeWidth: 3 }), 'You save ' + GW.fmt(result.bundleSavings) + ' with packages') : null,
              e('div', { className: 'muted', style: { fontSize: 12.5, lineHeight: 1.5 } }, 'Includes professional installation, hardware, and haul-away of your old door. No hidden fees.'),
            ),

            // coupon entry (rep-facing, no PIN needed) — hidden in print
            e('div', { className: 'no-print', style: { marginTop: 14, background: '#fff', borderRadius: 'var(--r-lg)', padding: '16px 18px', boxShadow: 'var(--sh-1)' } },
              e('div', { style: { fontSize: 12, fontWeight: 800, letterSpacing: '.04em', textTransform: 'uppercase', color: 'var(--ink-3)', marginBottom: 10, display: 'flex', alignItems: 'center', gap: 7 } }, e(Icon, { name: 'tag', size: 15 }), 'Coupon code'),
              result.couponCode
                ? e('div', { style: { display: 'flex', alignItems: 'center', gap: 10 } },
                    e('div', { className: 'grow' },
                      e('div', { style: { fontWeight: 800, fontFamily: 'var(--display)', letterSpacing: '.05em', fontSize: 16, color: 'var(--good)' } }, result.couponCode),
                      e('div', { className: 'muted', style: { fontSize: 12.5 } }, result.coupon ? (GW.couponLabel(result.coupon) + ' · −' + GW.fmt(result.discount) + ' applied') : 'Applied'),
                    ),
                    e(Btn, { variant: 'ghost', size: 'sm', onClick: removeCoupon }, 'Remove'))
                : e('div', null,
                    e('div', { style: { display: 'flex', gap: 8 } },
                      e('input', { value: code, onChange: ev => { setCode(ev.target.value.toUpperCase()); setCpErr(''); }, onKeyDown: ev => ev.key === 'Enter' && applyCoupon(), placeholder: 'Enter approved code', style: { flex: 1, minWidth: 0, padding: '10px 12px', borderRadius: 10, border: '1.5px solid var(--line-2)', fontWeight: 700, letterSpacing: '.05em', textTransform: 'uppercase', outline: 'none', fontFamily: 'var(--display)' } }),
                      e(Btn, { variant: 'teal', size: 'sm', onClick: applyCoupon }, 'Apply')),
                    cpErr ? e('div', { style: { color: 'var(--danger)', fontSize: 12.5, fontWeight: 600, marginTop: 8 } }, cpErr) : null,
                  ),
            ),

            // customer approval / signature
            e('div', { style: { marginTop: 14 } },
              e(window.ApprovalBlock, {
                signature: config.signature,
                onApprove: (sig) => app.setConfig(Object.assign({}, config, { signature: sig })),
                onClear: () => app.setConfig(Object.assign({}, config, { signature: null })),
              })),

            e('div', { className: 'no-print', style: { display: 'flex', gap: 8, marginTop: 14, justifyContent: 'center', color: 'var(--ink-3)', fontSize: 12.5, alignItems: 'center' } },
              e(Icon, { name: 'shield', size: 16 }), 'Backed by the GarageWiz workmanship guarantee'),
          ),
        ),
      ),

      // ---- Share for admin review ----
      e(Modal, { open: shareOpen, onClose: () => setShareOpen(false), title: 'Share for admin review', width: 480 },
        e('div', { style: { display: 'flex', flexDirection: 'column', gap: 14 } },
          e('p', { className: 'muted', style: { fontSize: 14, margin: 0, lineHeight: 1.5 } }, 'Send this exact quote to an admin. They can open it and use Dealer View to see costs, margin and discount room — then tell you what you can do to close.'),
          e(Field, { label: 'Note for the admin (optional)' },
            e('textarea', { value: shareNote, onChange: ev => setShareNote(ev.target.value), rows: 3, placeholder: 'e.g. Customer ready today but wants $300 off — what can we do?', style: { width: '100%', padding: '12px 14px', borderRadius: 10, border: '1.5px solid var(--line-2)', fontFamily: 'var(--body)', fontSize: 14.5, resize: 'vertical', outline: 'none' } })),
          e('div', { style: { display: 'flex', gap: 10 } },
            e(Btn, { variant: 'primary', block: true, icon: 'mail', onClick: () => { shareReview(); } }, 'Copy review link'),
          ),
          e('div', { className: 'muted', style: { fontSize: 12.5, lineHeight: 1.5 } }, 'The link is copied to your clipboard — text or email it to your admin. It also appears in the admin’s Review Requests inbox on this device.'),
        ),
      ),
    );
  }
  window.QuoteSummary = QuoteSummary;

  /* ===================== REVIEW (admin opens a shared quote) ===================== */
  function ReviewScreen() {
    const app = window.useApp();
    const raw = (app.route.raw || '').replace(/^review\/?/, '');
    const snap = GW.decodeReview(raw);
    const [loaded, setLoaded] = useState(false);
    useEffect(() => {
      if (snap && snap.estimate) { app.setEstimate(snap.estimate); setLoaded(true); }
      else if (snap && snap.config) { app.setConfig(Object.assign({}, snap.config)); setLoaded(true); }
    }, []);

    if (!snap || !(snap.config || snap.estimate)) {
      return e('div', { style: { maxWidth: 640, margin: '0 auto', padding: '60px 24px' } },
        e(window.EmptyState, { title: 'Review link not valid', sub: 'This shared quote link could not be read. Ask the rep to send a fresh link.', action: e(Btn, { variant: 'primary', icon: 'home', onClick: () => app.go('#/dashboard') }, 'Go to hub') }));
    }
    if (!loaded) return e('div', { style: { padding: 60, textAlign: 'center', color: 'var(--ink-3)' } }, 'Loading shared quote…');

    const when = new Date(snap.ts || Date.now()).toLocaleString('en-US', { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' });
    const isAdmin = app.user && app.user.role === 'admin';
    return e('div', null,
      e('div', { style: { background: 'linear-gradient(180deg, var(--navy) 0%, var(--navy-deep) 100%)', color: '#fff', padding: '16px 24px' } },
        e('div', { style: { maxWidth: 1080, margin: '0 auto', display: 'flex', alignItems: 'center', gap: 14, flexWrap: 'wrap' } },
          e('div', { style: { width: 40, height: 40, borderRadius: 11, background: 'rgba(245,224,65,.16)', color: 'var(--yellow)', display: 'grid', placeItems: 'center', flexShrink: 0 } }, e(Icon, { name: 'mail', size: 20 })),
          e('div', { className: 'grow', style: { minWidth: 0 } },
            e('div', { style: { fontWeight: 700, fontSize: 15 } }, 'Review request from ' + (snap.rep || 'a rep') + ' · ' + when),
            snap.note ? e('div', { style: { fontSize: 13.5, color: 'rgba(255,255,255,.8)', marginTop: 2 } }, '“' + snap.note + '”') : e('div', { style: { fontSize: 13, color: 'rgba(255,255,255,.6)', marginTop: 2 } }, 'No note added.'),
          ),
          isAdmin ? e(Btn, { variant: 'primary', icon: 'lock', onClick: () => app.openDealer() }, 'Open Dealer View') : null,
        ),
      ),
      snap.estimate ? e(window.EstimateScreen) : e(window.QuoteSummary),
    );
  }
  window.ReviewScreen = ReviewScreen;
})();
