// PERCH Reserve Modal — branded 3-step in-modal Stripe Elements flow.
// Loaded by index.html alongside pdp-sections.jsx.
//
// Step 1 (Confirm) — variant + install address + freight status
// Step 2 (Details) — name, email, phone
// Step 3 (Payment) — T&C consent + embedded Stripe Payment Element ($1,000)
//
// On payment_intent success → redirect to /homes/the-nest/reserved?ref=PN-XXXXXX
// Stripe webhook (server side) handles Firestore write + confirmation email.

const RESERVE_AMOUNT_LABEL = '$1,000';
const REFUNDABLE_AMOUNT_LABEL = '$925';
const NONREFUND_AMOUNT_LABEL = '$75';
const FREE_STATES = ['NC', 'SC', 'GA', 'TN', 'VA'];
const MAPBOX_TOKEN = 'pk.eyJ1Ijoiam92YW5jb25zdWx0aW5nIiwiYSI6ImNtc216bzJmMTFtZngyeW9xMGYxdDg1eG4ifQ.Sx8bkZ63nfQyGleNqcdfFQ';

function isFreightFree(state) {
  return FREE_STATES.indexOf(String(state || '').trim().toUpperCase()) !== -1;
}

// Mapbox Geocoding v5 autocomplete — US addresses only, structured response.
// Returns [{ placeName, state (2-letter), lat, lng, city, zip }, ...]
async function geocodeAddress(q) {
  if (!q || q.trim().length < 3) return [];
  const url = 'https://api.mapbox.com/geocoding/v5/mapbox.places/' +
    encodeURIComponent(q) +
    '.json?country=US&types=address&autocomplete=true&limit=5&access_token=' + MAPBOX_TOKEN;
  try {
    const r = await fetch(url);
    if (!r.ok) return [];
    const j = await r.json();
    return (j.features || []).map(function(f){
      var stateCtx = (f.context || []).find(function(c){ return String(c.id || '').indexOf('region') === 0; });
      var cityCtx = (f.context || []).find(function(c){ return String(c.id || '').indexOf('place') === 0; });
      var zipCtx = (f.context || []).find(function(c){ return String(c.id || '').indexOf('postcode') === 0; });
      var state = stateCtx && stateCtx.short_code ? String(stateCtx.short_code).replace('US-','').toUpperCase() : '';
      return {
        placeName: f.place_name,
        state: state,
        city: cityCtx ? cityCtx.text : '',
        zip: zipCtx ? zipCtx.text : '',
        lat: (f.center || [])[1],
        lng: (f.center || [])[0],
      };
    });
  } catch (e) { return []; }
}

function ReserveModal({ open, onClose, listingId, variantSlug, variantLabel }) {
  const { useState, useEffect, useRef } = React;
  const [step, setStep] = useState(1);
  const [installAddress, setInstallAddress] = useState('');
  const [installState, setInstallState] = useState('');
  const [addrSuggestions, setAddrSuggestions] = useState([]);
  const [addrOpen, setAddrOpen] = useState(false);
  const [addrConfirmed, setAddrConfirmed] = useState(false);
  const addrDebounceRef = useRef(null);
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [phone, setPhone] = useState('');
  const [consent, setConsent] = useState(false);
  const [pending, setPending] = useState(false);
  const [err, setErr] = useState('');
  const [legalDoc, setLegalDoc] = useState(''); // '/terms?embed=1' or '/privacy?embed=1' → shows in-modal iframe overlay

  // Stripe state
  const [stripe, setStripe] = useState(null);
  const [elements, setElements] = useState(null);
  const [clientSecret, setClientSecret] = useState('');
  const [reservationRef, setReservationRef] = useState('');
  const paymentElementRef = useRef(null);

  const freight = isFreightFree(installState) ? 'free' : 'quoted';

  // Load Stripe.js once when modal opens
  useEffect(() => {
    if (!open || window.Stripe) { return; }
    var s = document.createElement('script');
    s.src = 'https://js.stripe.com/v3/';
    s.onload = function(){ /* Stripe global ready */ };
    document.head.appendChild(s);
  }, [open]);

  // On entering step 3, create the PaymentIntent + mount the Payment Element
  useEffect(() => {
    if (step !== 3 || clientSecret || !open) return;
    (async function(){
      setPending(true); setErr('');
      try {
        var r = await fetch('/api/reserve-intent', {
          method:'POST',
          headers:{ 'Content-Type':'application/json' },
          body: JSON.stringify({
            listingId: listingId || 'the-nest',
            variantSlug: variantSlug || '',
            name: name.trim(),
            email: email.trim().toLowerCase(),
            phone: phone.trim(),
            installAddress: installAddress.trim(),
            installState: installState.trim().toUpperCase(),
            freightRegion: freight,
            acknowledgedTerms: true,
            pageUrl: location.href,
          }),
        });
        if (!r.ok) throw new Error('server ' + r.status);
        var j = await r.json();
        setClientSecret(j.clientSecret);
        setReservationRef(j.reservationRef);

        // Wait for Stripe.js
        var start = Date.now();
        while (!window.Stripe && Date.now() - start < 8000) {
          await new Promise(function(res){ setTimeout(res, 100); });
        }
        if (!window.Stripe) throw new Error('Stripe.js failed to load');

        var pkKey = window.__PERCH_STRIPE_PK__ || 'STRIPE_PK_MISSING';
        var stripeInstance = window.Stripe(pkKey);
        var elementsInstance = stripeInstance.elements({
          clientSecret: j.clientSecret,
          appearance: {
            theme: 'stripe',
            variables: {
              colorPrimary: '#C97A3A',
              colorBackground: '#FBF6EA',
              colorText: '#14301D',
              colorDanger: '#C97A3A',
              fontFamily: 'Fraunces, Georgia, serif',
              spacingUnit: '4px',
              borderRadius: '8px',
            },
            rules: {
              '.Input': { border: '1px solid rgba(20,48,29,0.20)', boxShadow: 'none', padding: '12px 14px' },
              '.Input:focus': { border: '1px solid #C97A3A', boxShadow: '0 0 0 3px rgba(201,122,58,0.14)' },
              '.Label': { fontFamily: 'DM Mono, ui-monospace, monospace', fontSize: '10.5px', letterSpacing: '0.22em', textTransform: 'uppercase', color: '#3C4A3E', fontWeight: '600' },
            },
          },
        });
        var pe = elementsInstance.create('payment', { layout: 'tabs' });
        setStripe(stripeInstance);
        setElements(elementsInstance);
        setTimeout(function(){ if (paymentElementRef.current) pe.mount(paymentElementRef.current); }, 60);
      } catch (e) {
        setErr((e && e.message) || 'Could not open secure checkout. Try again in a moment.');
      } finally { setPending(false); }
    })();
  }, [step, open]);

  // Reset on close
  useEffect(function(){
    if (!open) {
      setStep(1); setInstallAddress(''); setInstallState(''); setName(''); setEmail('');
      setPhone(''); setConsent(false); setClientSecret(''); setReservationRef('');
      setStripe(null); setElements(null); setErr(''); setPending(false);
    }
  }, [open]);

  if (!open) return null;

  var validStep1 = addrConfirmed && installAddress.trim().length > 4 && installState.trim().length === 2;
  var validEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
  var validStep2 = name.trim().length > 1 && validEmail;

  async function handlePay() {
    if (!stripe || !elements || pending) return;
    setPending(true); setErr('');
    try {
      var result = await stripe.confirmPayment({
        elements: elements,
        confirmParams: {
          return_url: window.location.origin + '/homes/' + (listingId || 'the-nest') + '/reserved?ref=' + encodeURIComponent(reservationRef),
          receipt_email: email.trim().toLowerCase(),
        },
      });
      if (result && result.error) {
        setErr(result.error.message || 'Payment failed. Please check the card and try again.');
        setPending(false);
      }
      // If no error, Stripe redirects to return_url.
    } catch (e) {
      setErr((e && e.message) || 'Payment failed.');
      setPending(false);
    }
  }

  // ═══════════════ Modal shell ═══════════════
  return React.createElement('div', {
    className: 'rsv-scrim',
    onClick: function(e){ if (e.target === e.currentTarget) onClose(); },
    role: 'dialog', 'aria-modal': 'true', 'aria-label': 'Reserve The Nest',
  },
    React.createElement('div', { className: 'rsv-modal' },

      // Header
      React.createElement('div', { className: 'rsv-head' },
        React.createElement('div', null,
          React.createElement('div', { className: 'rsv-head-eyebrow' }, 'Reserve · ' + RESERVE_AMOUNT_LABEL),
          React.createElement('div', { className: 'rsv-head-title' },
            'The Nest',
            variantLabel ? React.createElement('span', { className: 'rsv-head-variant' }, ' · ' + variantLabel) : null
          )
        ),
        React.createElement('button', { type: 'button', className: 'rsv-close', onClick: onClose, 'aria-label': 'Close' }, '×')
      ),

      // Progress
      React.createElement('div', { className: 'rsv-progress' },
        [1,2,3].map(function(n){
          return React.createElement('div', { key: n, className: 'rsv-progress-step' + (step >= n ? ' is-done' : '') },
            React.createElement('span', { className: 'rsv-progress-num' }, String(n)),
            React.createElement('span', { className: 'rsv-progress-label' },
              n === 1 ? 'Confirm' : n === 2 ? 'Details' : 'Payment'
            )
          );
        })
      ),

      // ── STEP 1 · Confirm site ──
      step === 1 && React.createElement('div', { className: 'rsv-body' },
        React.createElement('h2', { className: 'rsv-h' }, 'Where will ',
          React.createElement('em', null, 'The Nest'), ' land?'),
        React.createElement('p', { className: 'rsv-lede' },
          'Free site delivery to NC, SC, GA, TN, VA. Every other state ships nationwide — freight is quoted with your contract.'),

        React.createElement('div', { className: 'rsv-field', style: { position: 'relative' }},
          React.createElement('label', { className: 'rsv-label' }, 'Install address'),
          React.createElement('input', {
            type: 'text', className: 'rsv-input', placeholder: 'Start typing your address…',
            value: installAddress,
            onChange: function(e){
              var v = e.target.value; setInstallAddress(v); setAddrConfirmed(false); setInstallState('');
              if (addrDebounceRef.current) clearTimeout(addrDebounceRef.current);
              addrDebounceRef.current = setTimeout(async function(){
                var results = await geocodeAddress(v);
                setAddrSuggestions(results); setAddrOpen(results.length > 0);
              }, 220);
            },
            onFocus: function(){ if (addrSuggestions.length) setAddrOpen(true); },
            onBlur: function(){ setTimeout(function(){ setAddrOpen(false); }, 160); },
            maxLength: 300, autoComplete: 'off', 'aria-autocomplete': 'list',
          }),
          addrOpen && addrSuggestions.length > 0 && React.createElement('ul', { className: 'rsv-autocomplete' },
            addrSuggestions.map(function(s, i){
              return React.createElement('li', {
                key: i, className: 'rsv-autocomplete-item',
                onMouseDown: function(e){
                  e.preventDefault();
                  setInstallAddress(s.placeName);
                  setInstallState(s.state);
                  setAddrConfirmed(true); setAddrOpen(false);
                },
              },
                React.createElement('svg', { width: 16, height: 16, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round', strokeLinejoin: 'round', className: 'rsv-autocomplete-pin' },
                  React.createElement('path', { d: 'M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z' }),
                  React.createElement('circle', { cx: 12, cy: 10, r: 3 })
                ),
                React.createElement('span', null, s.placeName)
              );
            })
          ),
          addrConfirmed && installState ? React.createElement('div', { className: 'rsv-hint ' + (freight === 'free' ? 'is-free' : 'is-quoted') },
            freight === 'free'
              ? '✓ Free site delivery to ' + installState + ' · Set day scheduled at contract'
              : 'Freight quoted to ' + installState + ' at contract · Nationwide delivery available'
          ) : (installAddress && !addrConfirmed ? React.createElement('div', { className: 'rsv-hint' },
            'Select an address from the dropdown so we can confirm freight.'
          ) : null)
        ),

        React.createElement('div', { className: 'rsv-actions' },
          React.createElement('button', { type: 'button', className: 'rsv-btn rsv-btn-ghost', onClick: onClose }, 'Cancel'),
          React.createElement('button', {
            type: 'button', className: 'rsv-btn rsv-btn-primary',
            disabled: !validStep1, onClick: function(){ setStep(2); },
          },
            'Continue',
            React.createElement('svg', { width:14, height:14, viewBox:'0 0 24 24', fill:'none', stroke:'currentColor', strokeWidth:2, strokeLinecap:'round', strokeLinejoin:'round' },
              React.createElement('path', { d: 'M5 12h14M12 5l7 7-7 7' })
            )
          )
        )
      ),

      // ── STEP 2 · Details ──
      step === 2 && React.createElement('div', { className: 'rsv-body' },
        React.createElement('h2', { className: 'rsv-h' }, 'Where should we ',
          React.createElement('em', null, 'send everything?')),
        React.createElement('p', { className: 'rsv-lede' },
          'Your confirmation, Land Check pre-scan, and concierge kickoff call all route here.'),

        React.createElement('div', { className: 'rsv-field-row' },
          React.createElement('div', { className: 'rsv-field' },
            React.createElement('label', { className: 'rsv-label' }, 'Your name'),
            React.createElement('input', { type: 'text', className: 'rsv-input', placeholder: 'Full name', value: name, onChange: function(e){ setName(e.target.value); }, autoComplete: 'name', maxLength: 120 })
          ),
          React.createElement('div', { className: 'rsv-field' },
            React.createElement('label', { className: 'rsv-label' }, 'Email'),
            React.createElement('input', { type: 'email', className: 'rsv-input', placeholder: 'you@email.com', value: email, onChange: function(e){ setEmail(e.target.value); }, autoComplete: 'email', maxLength: 200 })
          )
        ),
        React.createElement('div', { className: 'rsv-field' },
          React.createElement('label', { className: 'rsv-label' }, 'Phone ',
            React.createElement('span', { className: 'rsv-label-opt' }, 'Optional')),
          React.createElement('input', { type: 'tel', className: 'rsv-input', placeholder: '(555) 123-4567', value: phone, onChange: function(e){ setPhone(e.target.value); }, autoComplete: 'tel', maxLength: 40 }),
          React.createElement('div', { className: 'rsv-hint' }, 'Only used for delivery day coordination — never marketing.')
        ),

        React.createElement('div', { className: 'rsv-actions' },
          React.createElement('button', { type: 'button', className: 'rsv-btn rsv-btn-ghost', onClick: function(){ setStep(1); } },
            React.createElement('svg', { width:14, height:14, viewBox:'0 0 24 24', fill:'none', stroke:'currentColor', strokeWidth:2, strokeLinecap:'round', strokeLinejoin:'round' }, React.createElement('path', { d:'M19 12H5M12 19l-7-7 7-7' })),
            'Back'
          ),
          React.createElement('button', {
            type: 'button', className: 'rsv-btn rsv-btn-primary',
            disabled: !validStep2, onClick: function(){ setStep(3); },
          }, 'Continue to payment',
            React.createElement('svg', { width:14, height:14, viewBox:'0 0 24 24', fill:'none', stroke:'currentColor', strokeWidth:2, strokeLinecap:'round', strokeLinejoin:'round' },
              React.createElement('path', { d: 'M5 12h14M12 5l7 7-7 7' })
            )
          )
        )
      ),

      // ── STEP 3 · Payment ──
      step === 3 && React.createElement('div', { className: 'rsv-body' },
        React.createElement('h2', { className: 'rsv-h' }, 'Hold your ',
          React.createElement('em', null, 'build slot.')),
        React.createElement('p', { className: 'rsv-lede' },
          RESERVE_AMOUNT_LABEL + ' now, mostly refundable. Deposit funds route to a PERCH-controlled Stripe account — no card details ever touch our servers.'),

        // Terms card
        React.createElement('div', { className: 'rsv-terms' },
          React.createElement('div', { className: 'rsv-terms-h' }, 'How the ' + RESERVE_AMOUNT_LABEL + ' breaks down'),
          React.createElement('ul', { className: 'rsv-terms-list' },
            React.createElement('li', null,
              React.createElement('strong', null, REFUNDABLE_AMOUNT_LABEL + ' refundable'),
              ' · Returns within 14 days if you don\'t sign OR your site plan doesn\'t clear local review.'),
            React.createElement('li', null,
              React.createElement('strong', null, NONREFUND_AMOUNT_LABEL + ' Land Check retainer'),
              ' · Covers your PERCH Land Check pre-scan (zoning, setbacks, utilities), emailed within 24 hours.'),
            React.createElement('li', null,
              React.createElement('strong', null, 'Nothing else charged today.'),
              ' Contract, financing, and full escrow follow separately after your kickoff call.')
          )
        ),

        // Stripe Payment Element mount
        React.createElement('div', { className: 'rsv-stripe' },
          React.createElement('div', { className: 'rsv-stripe-label' }, 'Card details'),
          React.createElement('div', {
            ref: paymentElementRef,
            className: 'rsv-stripe-mount',
            style: { minHeight: 200 }
          }),
          pending && !clientSecret ? React.createElement('div', { className: 'rsv-loading' }, 'Preparing secure checkout…') : null
        ),

        React.createElement('label', { className: 'rsv-consent' },
          React.createElement('input', { type: 'checkbox', checked: consent, onChange: function(e){ setConsent(e.target.checked); } }),
          React.createElement('span', null,
            React.createElement('strong', null, 'I agree'), ' to the ',
            REFUNDABLE_AMOUNT_LABEL, ' refundable / ', NONREFUND_AMOUNT_LABEL, ' non-refundable split above, and PERCH\'s ',
            React.createElement('button', {
              type: 'button', className: 'rsv-legal-link',
              onClick: function(e){ e.preventDefault(); setLegalDoc('/terms?embed=1'); },
            }, 'Terms'),
            ' and ',
            React.createElement('button', {
              type: 'button', className: 'rsv-legal-link',
              onClick: function(e){ e.preventDefault(); setLegalDoc('/privacy?embed=1'); },
            }, 'Privacy'),
            '. I authorize the ' + RESERVE_AMOUNT_LABEL + ' charge.'
          )
        ),

        // Legal doc overlay — in-modal iframe popup, dismissible without losing form state
        legalDoc ? React.createElement('div', {
          className: 'rsv-legal-scrim',
          onClick: function(e){ if (e.target === e.currentTarget) setLegalDoc(''); },
          role: 'dialog', 'aria-modal': 'true',
        },
          React.createElement('div', { className: 'rsv-legal-modal' },
            React.createElement('div', { className: 'rsv-legal-head' },
              React.createElement('div', { className: 'rsv-legal-title' },
                legalDoc.indexOf('/terms') === 0 ? 'PERCH Terms' : 'PERCH Privacy'
              ),
              React.createElement('button', {
                type: 'button', className: 'rsv-legal-close',
                onClick: function(){ setLegalDoc(''); }, 'aria-label': 'Close',
              }, '×')
            ),
            React.createElement('iframe', {
              src: legalDoc, className: 'rsv-legal-iframe',
              title: legalDoc.indexOf('/terms') === 0 ? 'PERCH Terms' : 'PERCH Privacy',
            }),
            React.createElement('div', { className: 'rsv-legal-foot' },
              React.createElement('button', {
                type: 'button', className: 'rsv-btn rsv-btn-primary',
                onClick: function(){ setLegalDoc(''); },
              }, 'Back to reserve')
            )
          )
        ) : null,

        err ? React.createElement('div', { className: 'rsv-err' }, err) : null,

        React.createElement('div', { className: 'rsv-actions' },
          React.createElement('button', { type: 'button', className: 'rsv-btn rsv-btn-ghost', onClick: function(){ setStep(2); }, disabled: pending },
            React.createElement('svg', { width:14, height:14, viewBox:'0 0 24 24', fill:'none', stroke:'currentColor', strokeWidth:2, strokeLinecap:'round', strokeLinejoin:'round' }, React.createElement('path', { d:'M19 12H5M12 19l-7-7 7-7' })),
            'Back'
          ),
          React.createElement('button', {
            type: 'button', className: 'rsv-btn rsv-btn-ember',
            disabled: !consent || !clientSecret || pending, onClick: handlePay,
          }, pending ? 'Processing…' : ('Reserve for ' + RESERVE_AMOUNT_LABEL),
            React.createElement('svg', { width:14, height:14, viewBox:'0 0 24 24', fill:'none', stroke:'currentColor', strokeWidth:2, strokeLinecap:'round', strokeLinejoin:'round' },
              React.createElement('path', { d: 'M5 12h14M12 5l7 7-7 7' })
            )
          )
        )
      )
    )
  );
}

// Expose the modal to the App shell.
Object.assign(window, { ReserveModal });
