/* global React */
const { useState: useStateBook, useMemo: useMemoBook } = React;

const BOOK_SERVICES = [
  { id: 'gel',    name: 'Gel Polish',        duration: '45 min',       min: 45  },
  { id: 'art',    name: 'Nail Art',          duration: '60–90 min',    min: 90  },
  { id: 'ext',    name: 'Nail Extensions',   duration: '90 min',       min: 90  },
  { id: 'gext',   name: 'Gel Extensions',    duration: '90–120 min',   min: 120 },
  { id: 'press',  name: 'Press-On Fitting',  duration: '30 min',       min: 30  },
  { id: 'mani',   name: 'Manicure',          duration: '45 min',       min: 45  },
  { id: 'pedi',   name: 'Pedicure',          duration: '60 min',       min: 60  },
  { id: 'refill', name: 'Refill',            duration: '60 min',       min: 60  },
  { id: 'custom', name: 'Custom',            duration: 'Tell us what you need', min: 60 },
];

// Convert "HH:MM" to minutes since midnight
function timeToMins(t) {
  const [h, m] = t.split(':').map(Number);
  return h * 60 + m;
}

// Is slot `t` blocked given existing bookings (array of {start, duration_min}) and own selection duration?
function isSlotBlocked(t, bookings, selectedDuration) {
  const slotStart = timeToMins(t);
  const slotEnd   = slotStart + selectedDuration;
  // 1. This slot's own block overlaps an existing booking
  for (const b of bookings) {
    const bStart = timeToMins(b.start);
    const bEnd   = bStart + b.duration_min;
    if (bStart < slotEnd && bEnd > slotStart) return true;
  }
  return false;
}

const TIME_GROUPS = {
  Morning:   ['10:00', '10:30', '11:00', '11:30', '12:00', '12:30'],
  Afternoon: ['13:00', '13:30', '14:00', '14:30', '15:00', '15:30', '16:00', '16:30'],
  Evening:   ['17:00', '17:30', '18:00', '18:30', '19:00', '19:30', '20:00']
};

function emptyPerson(idx) {
  return {
    id: idx,
    name: '',
    mobile: '',
    email: '',
    services: idx === 0 ? ['gel'] : []
  };
}

function formatDate(d) {
  return d.toLocaleDateString('en-IN', { weekday: 'short', day: 'numeric', month: 'short' });
}

window.BookHero = function BookHero() {
  return (
    <section className="book-hero">
      <div className="shell">
        <div className="eyebrow">Reserve · Step into luxury</div>
        <h1 className="display book-hero-title">
          Book your <span className="script-inline">moment</span>.
        </h1>
        <p className="book-hero-sub">A few details and you're set. Confirmation lands on your WhatsApp instantly — no calls, no waiting.</p>
      </div>
    </section>
  );
};

window.BookForm = function BookForm() {
  const [people, setPeople] = useStateBook([emptyPerson(0)]);
  const [date, setDate] = useStateBook(null); // Date object
  const [time, setTime] = useStateBook(null);
  const [submitted, setSubmitted] = useStateBook(false);
  const [submitting, setSubmitting] = useStateBook(false);
  const [submitError, setSubmitError] = useStateBook('');
  const [touched, setTouched] = useStateBook(false);
  const [bookings, setBookings] = useStateBook([]); // [{start, duration_min}]
  const [loadingSlots, setLoadingSlots] = useStateBook(false);
  const [payConfig, setPayConfig] = useStateBook(null);
  const [confirmedRef, setConfirmedRef] = useStateBook(null);

  const today = new Date();
  today.setHours(0, 0, 0, 0);

  // Load payment config once
  React.useEffect(() => {
    if (window.LQ_PUB) window.LQ_PUB.fetchPaymentConfig().then(setPayConfig);
  }, []);

  // Total duration of the primary person's selected services (used for slot blocking)
  const selectedDuration = useMemoBook(() => {
    const primary = people[0];
    if (!primary || primary.services.length === 0) return 60;
    return primary.services.reduce((sum, sid) => {
      const svc = BOOK_SERVICES.find(x => x.id === sid);
      return sum + (svc ? svc.min : 60);
    }, 0);
  }, [people[0] && people[0].services.join(',')]);

  // Re-fetch when date changes
  React.useEffect(() => {
    if (!date) { setBookings([]); return; }
    const iso = date.toISOString().slice(0, 10);
    setLoadingSlots(true);
    fetch('/api/booked-slots?date=' + iso)
      .then(r => r.ok ? r.json() : null)
      .then(j => {
        const raw = (j && j.data) || [];
        // Support both old format (array of strings) and new format (array of objects)
        const normalised = raw.map(x => typeof x === 'string' ? { start: x, duration_min: 60 } : x);
        setBookings(normalised);
      })
      .catch(() => setBookings([]))
      .finally(() => setLoadingSlots(false));
  }, [date && date.toDateString()]);

  // Clear selected time if it becomes blocked after service change
  React.useEffect(() => {
    if (time && bookings.length > 0 && isSlotBlocked(time, bookings, selectedDuration)) setTime(null);
  }, [selectedDuration, bookings.length]);

  const valid = people.every(p => p.name.trim() && /^\d{10}$/.test(p.mobile.replace(/\s/g, '')) && p.services.length > 0) && date && time;

  const updatePerson = (id, key, value) => {
    setPeople(people.map(p => p.id === id ? { ...p, [key]: value } : p));
  };

  const toggleService = (personId, sid) => {
    setPeople(people.map(p => {
      if (p.id !== personId) return p;
      const has = p.services.includes(sid);
      return { ...p, services: has ? p.services.filter(s => s !== sid) : [...p.services, sid] };
    }));
  };

  const addPerson = () => {
    if (people.length >= 4) return;
    setPeople([...people, emptyPerson(Date.now())]);
  };
  const removePerson = (id) => setPeople(people.filter(p => p.id !== id));

  const needsPayment = payConfig && payConfig.enable_booking_fee && !payConfig.test_mode && payConfig.razorpay_key_id;

  function buildBookingBodies(paymentFields) {
    const isoDate = date.toISOString().slice(0, 10);
    return people.map(p => {
      const serviceNames = p.services
        .map(sid => (BOOK_SERVICES.find(x => x.id === sid) || {}).name)
        .filter(Boolean)
        .join(', ');
      const personDuration = p.services.reduce((sum, sid) => {
        const svc = BOOK_SERVICES.find(x => x.id === sid);
        return sum + (svc ? svc.min : 60);
      }, 0) || 60;
      const noteParts = [];
      if (people.length > 1) noteParts.push('Group booking · ' + people.length + ' people');
      if (p.services.includes('custom') && p.customNote) noteParts.push('Custom request: ' + p.customNote.trim());
      return {
        name: p.name.trim(),
        mobile: p.mobile.replace(/\s/g, ''),
        email: p.email ? p.email.trim() : null,
        service: serviceNames || 'Multiple services',
        appt_date: isoDate,
        appt_time: time,
        guests: people.length,
        duration_min: personDuration,
        notes: noteParts.join(' · '),
        ...paymentFields,
      };
    });
  }

  async function doSubmit(paymentFields) {
    setSubmitting(true);
    try {
      const bodies = buildBookingBodies(paymentFields || {});
      let lastRef = null;
      for (const body of bodies) {
        const res = await (window.LQ_PUB ? window.LQ_PUB.submitBooking(body) : Promise.resolve({ data: {} }));
        if (res && res.data && res.data.ref) lastRef = res.data.ref;
      }
      setConfirmedRef(lastRef);
      setSubmitted(true);
      window.scrollTo({ top: 0, behavior: 'smooth' });
    } catch (err) {
      setSubmitError((err && (err.error || err.message)) || 'Submission failed. Please try again or message us on WhatsApp.');
    } finally {
      setSubmitting(false);
    }
  }

  const submit = async (e) => {
    e.preventDefault();
    setTouched(true);
    if (!valid) return;
    setSubmitError('');

    if (needsPayment) {
      setSubmitting(true);
      let orderData;
      try {
        orderData = await window.LQ_PUB.createPaymentOrder();
      } catch (err) {
        setSubmitError('Could not initiate payment. Please try again.');
        setSubmitting(false);
        return;
      }
      setSubmitting(false);

      const primaryPerson = people[0];
      const options = {
        key: orderData.key_id,
        amount: orderData.amount,
        currency: orderData.currency,
        order_id: orderData.order_id,
        name: 'Lacquery Nails',
        description: 'Appointment Booking Deposit',
        image: 'https://lacquerynails.in/assets/logo-round.png',
        prefill: {
          name: primaryPerson.name.trim(),
          contact: '+91' + primaryPerson.mobile.replace(/\s/g, ''),
          email: primaryPerson.email || '',
        },
        theme: { color: '#b8973a' },
        handler: function (response) {
          doSubmit({
            razorpay_payment_id: response.razorpay_payment_id,
            razorpay_order_id: response.razorpay_order_id,
            razorpay_signature: response.razorpay_signature,
          });
        },
        modal: {
          ondismiss: function () {
            setSubmitError('Payment was cancelled. Please try again to complete your booking.');
          }
        },
      };
      const rzp = new window.Razorpay(options);
      rzp.open();
    } else {
      await doSubmit(null);
    }
  };

  if (submitted) {
    return <BookConfirmation people={people} date={date} time={time} bookingRef={confirmedRef} onReset={() => { setSubmitted(false); setPeople([emptyPerson(0)]); setDate(null); setTime(null); setTouched(false); setConfirmedRef(null); }} />;
  }

  const feeAmount = payConfig && payConfig.booking_fee_amount ? payConfig.booking_fee_amount : 200;

  return (
    <section className="book-form">
      {payConfig && payConfig.test_mode && (
        <div style={{ background: '#fff3cd', borderBottom: '1px solid #ffc107', padding: '8px 0', textAlign: 'center', fontSize: 12, letterSpacing: '0.08em', textTransform: 'uppercase', color: '#856404' }}>
          Test mode active — payment bypassed
        </div>
      )}
      <div className="shell book-form-grid">
        <form className="book-form-main" onSubmit={submit}>
          {/* DISCOUNT BANNER */}
          <div className={`book-banner ${people.length >= 2 ? 'active' : ''}`}>
            <div className="book-banner-icon">
              <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
                <path d="M21 11.5l-9-7-9 7v8a2 2 0 002 2h14a2 2 0 002-2z" stroke="currentColor" strokeWidth="1.5"/>
                <path d="M9 22V12h6v10" stroke="currentColor" strokeWidth="1.5"/>
              </svg>
            </div>
            <div className="book-banner-text">
              <strong>Bring a friend, save 10%</strong>
              <span>{people.length >= 2 ? 'Group discount applied at the salon.' : 'Add a second person to unlock 10% off both bookings.'}</span>
            </div>
            {people.length < 2 && (
              <button type="button" className="book-banner-cta" onClick={addPerson}>+ Add person</button>
            )}
          </div>

          {/* PEOPLE */}
          {people.map((p, idx) => (
            <fieldset key={p.id} className="book-person">
              <div className="book-person-head">
                <div className="book-person-num">
                  <span>0{idx + 1}</span>
                  <span className="book-person-label">{idx === 0 ? 'Primary booking' : 'Guest ' + idx}</span>
                </div>
                {idx > 0 && (
                  <button type="button" className="book-person-remove" onClick={() => removePerson(p.id)}>
                    Remove
                  </button>
                )}
              </div>

              <div className="book-fields">
                <div className="book-field">
                  <label>Full name</label>
                  <input
                    type="text"
                    value={p.name}
                    onChange={e => updatePerson(p.id, 'name', e.target.value)}
                    placeholder="Ananya Reddy"
                    className={touched && !p.name.trim() ? 'invalid' : ''}
                  />
                </div>
                <div className="book-field">
                  <label>Mobile number</label>
                  <div className="book-input-prefix">
                    <span>+91</span>
                    <input
                      type="tel"
                      value={p.mobile}
                      onChange={e => updatePerson(p.id, 'mobile', e.target.value.replace(/\D/g, '').slice(0, 10))}
                      placeholder="98765 43210"
                      className={touched && !/^\d{10}$/.test(p.mobile) ? 'invalid' : ''}
                    />
                  </div>
                </div>
                <div className="book-field book-field-wide">
                  <label>Email <span className="book-optional">optional</span></label>
                  <input
                    type="email"
                    value={p.email}
                    onChange={e => updatePerson(p.id, 'email', e.target.value)}
                    placeholder="ananya@example.com"
                  />
                </div>
              </div>

              <div className="book-services">
                <label className="book-section-label">Services <span>· choose one or more</span></label>
                <div className="book-services-grid">
                  {BOOK_SERVICES.map(s => {
                    const checked = p.services.includes(s.id);
                    return (
                      <label key={s.id} className={`book-service ${checked ? 'active' : ''}`}>
                        <input type="checkbox" checked={checked} onChange={() => toggleService(p.id, s.id)} />
                        <div className="book-service-name">{s.name}</div>
                        <div className="book-service-meta">{s.duration}</div>
                        <div className="book-service-check">
                          {checked && <svg width="10" height="8" viewBox="0 0 10 8"><path d="M1 4l3 3 5-6" stroke="currentColor" strokeWidth="1.6" fill="none"/></svg>}
                        </div>
                      </label>
                    );
                  })}
                </div>
                {touched && p.services.length === 0 && <div className="book-error">Pick at least one service.</div>}

                {p.services.includes('custom') && (
                  <div className="book-field book-field-wide" style={{ marginTop: 14 }}>
                    <label>Tell us what you'd like <span className="book-optional">required for custom</span></label>
                    <textarea
                      rows="3"
                      value={p.customNote || ''}
                      onChange={e => updatePerson(p.id, 'customNote', e.target.value)}
                      placeholder="e.g. Bridal almonds with crystals, or recreate a Pinterest pin I'll send on WhatsApp"
                    />
                  </div>
                )}
              </div>
            </fieldset>
          ))}

          {people.length < 4 && (
            <button type="button" className="book-add-person" onClick={addPerson}>
              <span>+</span> Add another person {people.length === 1 && <em>· unlock 10% off</em>}
            </button>
          )}

          {/* DATE — compact native picker + quick chips */}
          <div className="book-section">
            <label className="book-section-label">Choose a date</label>

            <div className="book-date-quick">
              {[0, 1, 2, 3, 4, 5, 6].map(offset => {
                const d = new Date(today);
                d.setDate(today.getDate() + offset);
                const sel = date && d.toDateString() === date.toDateString();
                return (
                  <button
                    type="button"
                    key={offset}
                    className={`book-date-chip ${sel ? 'selected' : ''}`}
                    onClick={() => setDate(d)}
                  >
                    <span className="book-date-chip-dow">{d.toLocaleDateString('en-IN', { weekday: 'short' })}</span>
                    <span className="book-date-chip-day">{d.getDate()}</span>
                    <span className="book-date-chip-mon">{d.toLocaleDateString('en-IN', { month: 'short' })}</span>
                  </button>
                );
              })}
            </div>

            <div className="book-date-picker">
              <span className="book-date-picker-lbl">Or pick another date</span>
              <input
                type="date"
                className="book-date-input"
                min={today.toISOString().slice(0, 10)}
                value={date ? date.toISOString().slice(0, 10) : ''}
                onChange={e => {
                  if (!e.target.value) { setDate(null); return; }
                  const [y, m, d] = e.target.value.split('-').map(Number);
                  setDate(new Date(y, m - 1, d));
                }}
              />
            </div>

            {touched && !date && <div className="book-error">Pick a date.</div>}
          </div>

          {/* TIME — dropdown grouped by Morning/Afternoon/Evening, real-time availability */}
          <div className="book-section">
            <label className="book-section-label">
              Pick a time {date && <span>· {formatDate(date)}</span>}
              {loadingSlots && <span className="book-time-syncing"> · checking availability…</span>}
            </label>
            <select
              className="book-time-select"
              disabled={!date}
              value={time || ''}
              onChange={(e) => setTime(e.target.value || null)}
            >
              <option value="">{date ? 'Choose a time slot' : 'Pick a date first'}</option>
              {Object.entries(TIME_GROUPS).map(([grp, slots]) => {
                const available = slots.filter(t => !isSlotBlocked(t, bookings, selectedDuration));
                if (available.length === 0) return null;
                return (
                  <optgroup key={grp} label={grp}>
                    {available.map(t => <option key={t} value={t}>{t}</option>)}
                  </optgroup>
                );
              })}
            </select>
            {date && bookings.length > 0 && (
              <div className="book-time-note">
                Some slots hidden — {selectedDuration >= 60 ? Math.round(selectedDuration / 60) + ' hr ' + (selectedDuration % 60 ? (selectedDuration % 60) + ' min ' : '') : selectedDuration + ' min '}
                block applied for your selected services.
              </div>
            )}
            {touched && !time && <div className="book-error">Pick a time.</div>}
          </div>
        </form>

        {/* SUMMARY SIDEBAR */}
        <aside className="book-summary">
          <div className="book-summary-inner">
            <div className="book-summary-head">
              <div className="eyebrow">Your reservation</div>
              <h3 className="display">Summary</h3>
            </div>

            <div className="book-summary-when">
              <div>
                <span className="book-summary-lbl">Date</span>
                <strong>{date ? formatDate(date) : '—'}</strong>
              </div>
              <div>
                <span className="book-summary-lbl">Time</span>
                <strong>{time || '—'}</strong>
              </div>
              <div>
                <span className="book-summary-lbl">Guests</span>
                <strong>{people.length}</strong>
              </div>
            </div>

            <div className="book-summary-line">
              {people.map((p, idx) => (
                <div key={p.id} className="book-summary-person">
                  <div className="book-summary-person-name">{p.name || `Guest ${idx + 1}`}</div>
                  {p.services.length === 0 && <div className="book-summary-empty">No services selected</div>}
                  {p.services.map(sid => {
                    const s = BOOK_SERVICES.find(x => x.id === sid);
                    return (
                      <div key={sid} className="book-summary-svc">
                        <span>{s.name}</span>
                        <span className="book-summary-svc-meta">{s.duration}</span>
                      </div>
                    );
                  })}
                </div>
              ))}
            </div>

            <div className="book-summary-quote">
              <span>Final quote shared at the salon</span>
              <p>Pricing varies by length, design, and add-ons. We'll confirm before we start.</p>
            </div>

            <button
              type="submit"
              onClick={submit}
              className="btn btn-gold book-submit"
              disabled={submitting}
            >{submitting ? (needsPayment ? 'Opening payment…' : 'Submitting…') : needsPayment ? `Pay ₹${feeAmount} & Confirm` : 'Confirm Booking'}</button>

            {submitError && (
              <p className="book-summary-note" style={{ color: '#a40000', marginTop: 8 }}>{submitError}</p>
            )}
            {needsPayment
              ? <p className="book-summary-note">A ₹{feeAmount} booking deposit is charged now via Razorpay — this amount will be adjusted against your final bill at the salon.</p>
              : <p className="book-summary-note">Pay at the salon. Confirmation sent to your WhatsApp.</p>
            }
          </div>
        </aside>
      </div>
    </section>
  );
};

window.BookConfirmation = function BookConfirmation({ people, date, time, bookingRef, onReset }) {
  const ref = bookingRef || `LQ${Math.floor(100000 + Math.random() * 900000)}`;
  return (
    <section className="book-confirm">
      <div className="shell">
        <div className="book-confirm-card gold-frame">
          <div className="book-confirm-inner">
            <div className="book-confirm-icon">
              <svg width="40" height="40" viewBox="0 0 40 40" fill="none">
                <circle cx="20" cy="20" r="19" stroke="currentColor" strokeWidth="1.5"/>
                <path d="M12 20 L18 26 L28 14" stroke="currentColor" strokeWidth="1.5" fill="none"/>
              </svg>
            </div>
            <div className="script-accent" style={{ fontSize: 64, color: 'var(--gold-deep)', lineHeight: 0.8 }}>booked</div>
            <h2 className="display book-confirm-title">You're all set, {people[0].name.split(' ')[0]}.</h2>
            <p>We've sent a confirmation to your WhatsApp on +91 {people[0].mobile}. See you soon at Lacquery.</p>

            <div className="book-confirm-grid">
              <div>
                <span>Reference</span>
                <strong>{ref}</strong>
              </div>
              <div>
                <span>When</span>
                <strong>{formatDate(date)} · {time}</strong>
              </div>
              <div>
                <span>Guests</span>
                <strong>{people.length} {people.length === 1 ? 'person' : 'people'}</strong>
              </div>
              <div>
                <span>Services</span>
                <strong>{people.reduce((n, p) => n + p.services.length, 0)} booked</strong>
              </div>
            </div>

            <div className="book-confirm-actions">
              <a href="index.html" className="btn btn-primary">Back to home</a>
              <button onClick={onReset} className="btn btn-ghost">New booking</button>
            </div>

            <div className="book-confirm-foot">
              <div>
                <strong>Need to reschedule?</strong>
                <span>WhatsApp us at +91 83174 51779</span>
              </div>
              <div>
                <strong>Address</strong>
                <span>Near Shrirampura Metro, Bengaluru</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
};
