// PERCH Reserve Modal — SINGLE-SCREEN embedded Stripe Elements checkout.
// Loaded by index.html alongside pdp-sections.jsx.
//
// Cameron 2026-08-26: collapsed the 3-step flow (Confirm → Details → Payment) into ONE screen.
// Buyer sees: email input + Stripe Payment Element + Reserve button. Nothing else.
// Name / install address / phone are captured post-payment on the concierge kickoff call.
//
// Also killed: every italic (<em>, fontStyle:'italic', Fraunces italic) — the checkout register
// is non-italic across the board.
//
// 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';

function ReserveModal({ open, onClose, listingId, variantSlug, variantLabel }) {
  const { useState, useEffect, useRef } = React;
  const [email, setEmail] = useState('');
  const [pending, setPending] = useState(false);
  const [err, setErr] = useState('');
  const [legalDoc, setLegalDoc] = useState(''); // '/terms?embed=1' or '/privacy?embed=1' → 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 emailInputRef = useRef(null);
  const intentRequestedRef = useRef(false);

  const validEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);

  // 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/';
    document.head.appendChild(s);
  }, [open]);

  // Autofocus email input on open
  useEffect(() => {
    if (open) {
      setTimeout(function(){ if (emailInputRef.current) emailInputRef.current.focus(); }, 60);
    }
  }, [open]);

  // Create the PaymentIntent + mount the Payment Element as soon as we have a valid email.
  // Fires exactly once per open. Wallets (Apple/Google/Link) pre-fill name/address/phone.
  useEffect(() => {
    if (!open || !validEmail || clientSecret || intentRequestedRef.current) return;
    intentRequestedRef.current = true;
    (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: '',
            email: email.trim().toLowerCase(),
            phone: '',
            installAddress: '',
            installState: '',
            freightRegion: 'quoted',
            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: { type: 'tabs', defaultCollapsed: false },
          wallets: { applePay: 'auto', googlePay: 'auto' },
          defaultValues: {
            billingDetails: { email: email.trim().toLowerCase() },
          },
        });
        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.');
        intentRequestedRef.current = false;
      } finally { setPending(false); }
    })();
  }, [open, validEmail]);

  // Reset on close
  useEffect(function(){
    if (!open) {
      setEmail(''); setClientSecret(''); setReservationRef('');
      setStripe(null); setElements(null); setErr(''); setPending(false); setLegalDoc('');
      intentRequestedRef.current = false;
    }
  }, [open]);

  if (!open) return null;

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

  // ═══════════════ Modal shell — SINGLE SCREEN ═══════════════
  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 Bough',
  },
    React.createElement('div', { className: 'rsv-modal' },

      // Header (non-italic)
      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 Bough',
            variantLabel ? React.createElement('span', { className: 'rsv-head-variant' }, ' · ' + variantLabel) : null
          )
        ),
        React.createElement('button', { type: 'button', className: 'rsv-close', onClick: onClose, 'aria-label': 'Close' }, '×')
      ),

      // Body — one screen, price recap + email + Payment Element + terms micro + Reserve button
      React.createElement('div', { className: 'rsv-body' },

        // Price recap — full pre-purchase disclosure per GMC misrep policy
        React.createElement('p', { className: 'rsv-lede', style: { marginTop: 0 } },
          '$1,000 deposit · up to $925 refundable within 14 days or before production begins.'
        ),
        React.createElement('p', { className: 'rsv-lede rsv-lede--micro', style: { marginTop: 6, marginBottom: 4, fontSize: 12, opacity: 0.75 } },
          '$75 non-refundable transaction-processing fee. Home purchase price is not refundable once production begins.'
        ),
        React.createElement('p', { className: 'rsv-lede rsv-lede--micro', style: { marginTop: 6, marginBottom: 18 } },
          'Your dashboard opens next — book your Land Check kickoff on the spot.'
        ),

        // Email — the only required field
        React.createElement('div', { className: 'rsv-field' },
          React.createElement('label', { className: 'rsv-label', htmlFor: 'rsv-email' }, 'Email for receipt + build updates'),
          React.createElement('input', {
            id: 'rsv-email',
            ref: emailInputRef,
            type: 'email',
            className: 'rsv-input',
            placeholder: 'you@email.com',
            value: email,
            onChange: function(e){ setEmail(e.target.value); },
            autoComplete: 'email',
            inputMode: 'email',
            maxLength: 200,
            style: { fontSize: '16px' }, // iOS zoom prevention
          })
        ),

        // Stripe Payment Element mount — appears as soon as email is valid
        React.createElement('div', { className: 'rsv-stripe' },
          React.createElement('div', {
            ref: paymentElementRef,
            className: 'rsv-stripe-mount',
            style: { minHeight: validEmail ? 200 : 0, transition: 'min-height 200ms ease' }
          }),
          !validEmail ? React.createElement('div', { className: 'rsv-hint' }, 'Enter your email to load secure checkout.') : null,
          validEmail && pending && !clientSecret ? React.createElement('div', { className: 'rsv-loading' }, 'Preparing secure checkout…') : null
        ),

        // Terms micro (one line, non-italic)
        React.createElement('p', { className: 'rsv-hint', style: { marginTop: 8, marginBottom: 0 } },
          'By reserving I agree to PERCH’s ',
          React.createElement('button', {
            type: 'button', className: 'rsv-legal-link',
            onClick: function(e){ e.preventDefault(); setLegalDoc('/refund-policy?embed=1'); },
          }, 'Refund Policy'),
          ' · ',
          React.createElement('button', {
            type: 'button', className: 'rsv-legal-link',
            onClick: function(e){ e.preventDefault(); setLegalDoc('/terms?embed=1'); },
          }, 'Terms'),
          ' · ',
          React.createElement('button', {
            type: 'button', className: 'rsv-legal-link',
            onClick: function(e){ e.preventDefault(); setLegalDoc('/privacy?embed=1'); },
          }, 'Privacy')
        ),

        // 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'
                  : legalDoc.indexOf('/privacy') === 0 ? 'PERCH Privacy'
                  : 'PERCH Refund Policy'
              ),
              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'
                : legalDoc.indexOf('/privacy') === 0 ? 'PERCH Privacy'
                : 'PERCH Refund Policy',
            }),
            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,

        // Primary Reserve button (full-width, forest-deep, 52px min-height)
        React.createElement('div', { className: 'rsv-actions', style: { marginTop: 16 } },
          React.createElement('button', {
            type: 'button',
            className: 'rsv-btn rsv-btn-primary',
            style: { width: '100%', minHeight: 52, justifyContent: 'center', fontSize: '15px' },
            disabled: !clientSecret || pending,
            onClick: handlePay,
          },
            pending ? 'Processing…' : ('Reserve · ' + RESERVE_AMOUNT_LABEL)
          )
        )
      )
    )
  );
}

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