// Lead capture modal — window.__openBooking()
// Security: CSRF token, CAPTCHA, honeypot, mirrored field validation, rate-limit UX

const BookingModal = ({ onClose }) => {
  const TOTAL   = 15;
  const MSG_MAX = 2000;
  const EMPTY   = { name: '', email: '', phone: '', business: '', service: '', message: '', captchaAnswer: '', _hp: '' };

  const [form,        setForm]        = React.useState(EMPTY);
  const [fieldErrors, setFieldErrors] = React.useState({});
  const [captcha,     setCaptcha]     = React.useState(null);
  const [csrfToken,   setCsrfToken]   = React.useState('');
  const [sent,        setSent]        = React.useState(false);
  const [busy,        setBusy]        = React.useState(false);
  const [countdown,   setCountdown]   = React.useState(TOTAL);
  const [rateLimited, setRateLimited] = React.useState(0); // seconds until retry

  const firstRef   = React.useRef(null);
  const successRef = React.useRef(null);

  const set = (k) => (e) => {
    setForm(f => ({ ...f, [k]: e.target.value }));
    // Clear field error on change
    if (fieldErrors[k]) setFieldErrors(f => ({ ...f, [k]: false }));
  };

  // ── Client-side validation mirrors backend rules ────────────────────────────
  const EMAIL_RE  = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/;
  const PHONE_RE  = /^\+?[\d\s\-\.\(\)]{7,20}$/;

  const SAFE_TEXT_RE = /<script|javascript:|on\w{2,}=|<iframe|<object|union.{0,50}select|insert\s+into|drop\s+table/i;

  const validate = () => {
    const e = {};
    const n = form.name.trim();
    const em = form.email.trim();
    const ph = form.phone.trim();
    const msg = form.message.trim();

    if (!n)                     { e.name    = true; }
    else if (n.length > 100)    { e.name    = true; }
    else if (SAFE_TEXT_RE.test(n)) { e.name = true; }

    if (!em)                     { e.email   = true; }
    else if (!EMAIL_RE.test(em)) { e.email   = true; }

    if (!ph)                        { e.phone    = true; }
    else if (!PHONE_RE.test(ph))    { e.phone    = true; }

    if (!form.business)             { e.business = true; }
    if (!form.service)              { e.service  = true; }

    if (!form.captchaAnswer.trim()) { e.captcha  = true; }

    if (msg.length > MSG_MAX)       { e.message = true; }
    else if (SAFE_TEXT_RE.test(msg)) { e.message = true; }

    return e;
  };

  // ── Load CAPTCHA + CSRF in parallel ────────────────────────────────────────
  const base = window.__bookingApiBase || '';

  const loadCaptcha = React.useCallback(async () => {
    setCaptcha(null);
    try {
      const res  = await fetch(base + 'captcha.php', { credentials: 'same-origin' });
      const data = await res.json();
      setCaptcha(data);
    } catch {
      window.__toast?.('warning', 'Could not load verification — please refresh the page.');
    }
  }, []);

  const loadCsrf = React.useCallback(async () => {
    try {
      const res  = await fetch(base + 'csrf.php', { credentials: 'same-origin' });
      const data = await res.json();
      setCsrfToken(data.token || '');
    } catch {
      // Non-fatal — submit will fail with a clear error if CSRF is missing
    }
  }, []);

  // ── Lifecycle ───────────────────────────────────────────────────────────────
  React.useEffect(() => {
    // Fetch both in parallel
    Promise.all([loadCaptcha(), loadCsrf()]);

    const onKey = (e) => { if (e.key === 'Escape') close(); };
    window.addEventListener('keydown', onKey);
    document.body.style.overflow = 'hidden';
    setTimeout(() => firstRef.current?.focus(), 80);
    return () => {
      window.removeEventListener('keydown', onKey);
      document.body.style.overflow = '';
    };
  }, []);

  React.useEffect(() => {
    if (sent) setTimeout(() => successRef.current?.focus(), 60);
  }, [sent]);

  // Countdown auto-close
  React.useEffect(() => {
    if (!sent) return;
    if (countdown <= 0) { close(); return; }
    const id = setTimeout(() => setCountdown(c => c - 1), 1000);
    return () => clearTimeout(id);
  }, [sent, countdown]);

  // Rate-limit countdown display
  React.useEffect(() => {
    if (rateLimited <= 0) return;
    const id = setTimeout(() => setRateLimited(s => Math.max(0, s - 1)), 1000);
    return () => clearTimeout(id);
  }, [rateLimited]);

  // ── Close ───────────────────────────────────────────────────────────────────
  const close = () => {
    onClose();
    setTimeout(() => {
      setForm(EMPTY);
      setSent(false);
      setFieldErrors({});
      setCountdown(TOTAL);
      setRateLimited(0);
    }, 350);
  };

  // ── Submit ──────────────────────────────────────────────────────────────────
  const submit = async (e) => {
    e.preventDefault();

    const errs = validate();
    if (Object.keys(errs).length) {
      setFieldErrors(errs);
      const labels = {
        name:     'full name',
        email:    'valid email address',
        phone:    'phone number',
        business: 'business type',
        service:  'service you\'re interested in',
        captcha:  'verification answer',
        message:  'message (check length/content)',
      };
      const missing = Object.keys(errs).map(k => labels[k]).filter(Boolean);
      window.__toast?.('warning', 'Required: ' + missing.join(', ') + '.');
      return;
    }

    setFieldErrors({});
    setBusy(true);

    try {
      const res = await fetch(base + 'submit.php', {
        method:      'POST',
        credentials: 'same-origin',  // sends session cookie for CSRF
        headers:     { 'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest' },
        body: JSON.stringify({
          name:          form.name.trim(),
          email:         form.email.trim().toLowerCase(),
          phone:         form.phone.trim(),
          business:      form.business,
          service:       form.service,
          message:       form.message.trim(),
          _hp:           form._hp,
          _csrf:         csrfToken,
          captchaAnswer: parseInt(form.captchaAnswer, 10),
          captchaToken:  captcha?.token,
          captchaTs:     captcha?.ts,
        }),
      });

      const json = await res.json();

      if (res.ok && json.ok) {
        setSent(true);

      } else if (res.status === 429) {
        // Rate limited — show countdown
        const wait = json.retry_after || 60;
        setRateLimited(wait);
        window.__toast?.('error', json.error || 'Too many requests — please wait before trying again.');

      } else if (res.status === 403) {
        // CSRF / origin error — reload token and notify
        window.__toast?.('error', json.error || 'Security check failed — please refresh the page.');
        loadCsrf();

      } else {
        window.__toast?.('error', json.error || 'Something went wrong — please try again.');
        if (json.refreshCaptcha) {
          setForm(f => ({ ...f, captchaAnswer: '' }));
          loadCaptcha();
        }
        if (json.field_errors) {
          const fe = {};
          json.field_errors.forEach(k => { fe[k] = true; });
          setFieldErrors(fe);
        }
      }
    } catch {
      window.__toast?.('error', 'Network error — please check your connection and try again.');
    }

    setBusy(false);
  };

  // ── Render ──────────────────────────────────────────────────────────────────
  const barWidth   = `${(countdown / TOTAL) * 100}%`;
  const msgLen     = form.message.length;
  const msgNearMax = msgLen > MSG_MAX * 0.85;

  return (
    <div className="modal-wrap" onClick={(e) => { if (e.target === e.currentTarget) close(); }}>
      <div
        className="booking-modal"
        role="dialog" aria-modal="true"
        aria-label={sent ? 'Enquiry submitted' : 'Book a free consultation'}
      >

        {/* ── Sticky header ────────────────────────────────────────────────── */}
        <div className="modal-header">
          <div>
            {!sent && <span className="section-eyebrow" style={{ marginBottom: 0 }}>Free · No commitment</span>}
            <h3 className="modal-title">{sent ? 'Request received!' : 'Book a free consultation'}</h3>
          </div>
          <button className="drawer-close" onClick={close} aria-label="Close modal">
            <Icon name="close" size={16} />
          </button>
        </div>

        {/* ── Rate-limit banner ────────────────────────────────────────────── */}
        {rateLimited > 0 && !sent && (
          <div className="rate-banner" role="alert">
            <Icon name="clock" size={15} />
            <span>Too many requests — please wait <strong>{rateLimited}s</strong> before trying again.</span>
          </div>
        )}

        {/* ── Form ─────────────────────────────────────────────────────────── */}
        {!sent && (
          <form className="modal-form" onSubmit={submit} noValidate>

            {/* Honeypot — visually hidden, bots fill it */}
            <div style={{ display: 'none' }} aria-hidden="true">
              <input type="text" name="_hp" value={form._hp} onChange={set('_hp')} tabIndex={-1} autoComplete="off" />
            </div>

            {/* Name + Email */}
            <div className="form-2col">
              <div className="form-row">
                <label htmlFor="bm-name">Full name <span className="form-req">*</span></label>
                <input
                  id="bm-name" ref={firstRef}
                  type="text" autoComplete="name" placeholder="Jane Smith"
                  value={form.name} onChange={set('name')} maxLength={100}
                  className={fieldErrors.name ? 'error' : ''}
                  aria-invalid={!!fieldErrors.name} aria-required="true"
                />
              </div>
              <div className="form-row">
                <label htmlFor="bm-email">Email address <span className="form-req">*</span></label>
                <input
                  id="bm-email"
                  type="email" autoComplete="email" placeholder="jane@gmail.com"
                  value={form.email} onChange={set('email')} maxLength={254}
                  className={fieldErrors.email ? 'error' : ''}
                  aria-invalid={!!fieldErrors.email} aria-required="true"
                />
              </div>
            </div>

            {/* Phone + Business type */}
            <div className="form-2col">
              <div className="form-row">
                <label htmlFor="bm-phone">Phone number <span className="form-req">*</span></label>
                <input
                  id="bm-phone" type="tel" autoComplete="tel" placeholder="07700 900000"
                  value={form.phone} onChange={set('phone')} maxLength={20}
                  className={fieldErrors.phone ? 'error' : ''}
                  aria-invalid={!!fieldErrors.phone} aria-required="true"
                />
              </div>
              <div className="form-row">
                <label htmlFor="bm-business">Business type <span className="form-req">*</span></label>
                <select id="bm-business" value={form.business} onChange={set('business')}
                  className={fieldErrors.business ? 'error' : ''}
                  aria-invalid={!!fieldErrors.business} aria-required="true">
                  <option value="">Select…</option>
                  <option>Electrician / Trades</option>
                  <option>Care home</option>
                  <option>Restaurant / Takeaway</option>
                  <option>Builder / Construction</option>
                  <option>Cleaning</option>
                  <option>Ecommerce</option>
                  <option>Other</option>
                </select>
              </div>
            </div>

            {/* Service interest */}
            <div className="form-row">
              <label htmlFor="bm-service">I'm interested in <span className="form-req">*</span></label>
              <select id="bm-service" value={form.service} onChange={set('service')}
                className={fieldErrors.service ? 'error' : ''}
                aria-invalid={!!fieldErrors.service} aria-required="true">
                <option value="">Select…</option>
                <option>New website</option>
                <option>Local SEO</option>
                <option>Google Business Profile</option>
                <option>Social media management</option>
                <option>Ecommerce store</option>
                <option>Not sure yet</option>
              </select>
            </div>

            {/* Message with character counter */}
            <div className="form-row">
              <div className="form-label-row">
                <label htmlFor="bm-message">Anything else?</label>
                <span className={`char-count${msgNearMax ? ' warn' : ''}`} aria-live="polite">
                  {msgLen}/{MSG_MAX}
                </span>
              </div>
              <textarea
                id="bm-message" rows={3}
                placeholder="Tell us about your business and what you're looking to achieve…"
                value={form.message} onChange={set('message')} maxLength={MSG_MAX}
                className={fieldErrors.message ? 'error' : ''}
                aria-invalid={!!fieldErrors.message}
              />
            </div>

            {/* CAPTCHA */}
            <div className="form-row">
              <label>Verify you're human <span className="form-req">*</span></label>
              <div className="captcha-wrap">
                <div className="captcha-question">
                  {captcha
                    ? <>
                        <span className="captcha-math">{captcha.question}</span>
                        <button
                          type="button" className="captcha-reload"
                          onClick={() => { setForm(f => ({ ...f, captchaAnswer: '' })); loadCaptcha(); }}
                          aria-label="Get a new verification question"
                        >
                          <Icon name="refresh" size={14} />
                        </button>
                      </>
                    : <span className="captcha-loading"><span className="mini-spinner" aria-hidden="true" /> Loading…</span>
                  }
                </div>
                <input
                  type="number" inputMode="numeric"
                  placeholder="Answer"
                  value={form.captchaAnswer} onChange={set('captchaAnswer')}
                  className={fieldErrors.captcha ? 'error' : ''}
                  aria-label="Verification answer" aria-invalid={!!fieldErrors.captcha} aria-required="true"
                  disabled={!captcha}
                />
              </div>
            </div>

            {/* Submit */}
            <button
              type="submit"
              className={`btn btn-primary modal-submit${busy ? ' btn-loading' : ''}`}
              disabled={busy || !captcha || rateLimited > 0}
              aria-busy={busy}
            >
              {busy
                ? <><span className="btn-spinner" aria-hidden="true" />Sending…</>
                : rateLimited > 0
                  ? <>Wait {rateLimited}s…</>
                  : <>Book my free consultation <Icon name="arrowRight" size={16} /></>
              }
            </button>

            <p className="modal-note">
              <Icon name="check" size={13} /> Reply within one working day · No pressure, just honest advice
            </p>
          </form>
        )}

        {/* ── Success state ─────────────────────────────────────────────────── */}
        {sent && (
          <div className="modal-success" ref={successRef} tabIndex={-1} aria-live="polite">
            <div className="success-ring">
              <div className="success-icon-wrap">
                <Icon name="check" size={34} strokeWidth={2.5} />
              </div>
            </div>

            <h3 className="success-title">We'll be in touch soon!</h3>
            <p className="success-body">
              Thanks <strong>{form.name.split(' ')[0] || 'for reaching out'}</strong>. Your request has been received and we aim to reply within one working day — no sales pressure, just honest advice about what would work for your business.
            </p>

            <div className="success-details">
              <span><Icon name="check" size={13} /> Confirmation sent to <strong>{form.email}</strong></span>
              <span><Icon name="check" size={13} /> Response within one working day</span>
            </div>

            <div className="countdown-wrap" role="timer" aria-label={`Window closes in ${countdown} seconds`}>
              <div className="countdown-track">
                <div className="countdown-fill" style={{ width: barWidth }} />
              </div>
              <p className="countdown-text">
                This window will close automatically in <strong>{countdown}</strong> {countdown === 1 ? 'second' : 'seconds'}…
              </p>
            </div>

            <button className="btn btn-secondary close-now-btn" onClick={close}>
              Close now <Icon name="close" size={14} />
            </button>
          </div>
        )}

      </div>
    </div>
  );
};

window.BookingModal = BookingModal;
