import { Fragment, useEffect, useState } from 'react'
import {
  BOOKING_STEPS,
  CHILD_STAY_RM_PER_NIGHT,
  PACKAGES,
  PACKAGES_3D2N_ONLY,
  PACKAGES_4D3N_ONLY,
  ROOM_TYPES,
} from '../constants'
import { usePosStore } from '../store/usePosStore'
import { calcBookingTotal, fmt, fmtMoney, packagePricingHeadcount } from '../utils/helpers'

const ADDONS = [
  { id: 'extra-dive', name: 'Extra Dive (per dive)', emoji: '🤿' },
  { id: 'extra-night', name: 'Extra Night',  emoji: '🌙' },
  { id: 'boat-charter', name: 'Boat Charter (per trip)',  emoji: '⛵' },
  { id: 'transport', name: 'Shuttle Transport (per pax)',  emoji: '🚌' },
  { id: 'equip-rental', name: 'Full Equipment Rental', emoji: '🎽' },
  { id: 'nitrox', name: 'Nitrox Fill',  emoji: '💨' },
]

const ROOM_TYPE_IMAGES = {
  'White House Triple': '/rooms/white-house-triple-room.webp',
  'White House Seaview': '/rooms/seaview-white-house.webp',
  'Timber Triple': '/rooms/triple-home-house.avif',
  'Timber Twin (2 single beds)': '/rooms/timber 2 single bed.avif',
  'Timber King': '/rooms/timber-king.jpg',
  'Zenith Quad': '/rooms/zenith-suite.avif',
}

const ROOM_TYPE_SUBTITLE = {
  'White House Triple': '1 King + 1 Single',
  'White House Seaview': 'Seaview Room',
  'Timber Triple': 'Deluxe Triple',
  'Timber Twin (2 single beds)': 'Twin (2 single beds)',
  'Timber King': 'Double (1 King)',
  'Zenith Quad': '1 King + 2 Singles',
}

export default function BookingFlow() {
  const bkStep = usePosStore((s) => s.bkStep)
  const bkData = usePosStore((s) => s.bkData)
  const rooms = usePosStore((s) => s.rooms)
  const patchBkData = usePosStore((s) => s.patchBkData)
  const resetBooking = usePosStore((s) => s.resetBooking)
  const setBkStep = usePosStore((s) => s.setBkStep)
  const advanceBkStep = usePosStore((s) => s.advanceBkStep)
  const prevBkStep = usePosStore((s) => s.prevBkStep)
  const toggleAddon = usePosStore((s) => s.toggleAddon)
  const validateAgent = usePosStore((s) => s.validateAgent)
  const confirmBooking = usePosStore((s) => s.confirmBooking)
  const agentValidateHtml = usePosStore((s) => s.agentValidateHtml)
  const totalPax = (bkData.pax?.adult || 1) + (bkData.pax?.kid || 0) + (bkData.pax?.elderly || 0)
  const stayDuration = (() => {
    if (!bkData.checkin || !bkData.checkout) return null
    const checkin = new Date(`${bkData.checkin}T00:00:00`)
    const checkout = new Date(`${bkData.checkout}T00:00:00`)
    if (Number.isNaN(checkin.getTime()) || Number.isNaN(checkout.getTime())) return null
    const nights = Math.round((checkout - checkin) / 86400000)
    if (nights <= 0) return null
    return { nights, days: nights + 1 }
  })()
  const is4d3nStay = stayDuration?.nights === 3
  const is3d2nStay = stayDuration?.nights === 2
  const isPackage4d3nOnly = (name) => PACKAGES_4D3N_ONLY.includes(name)
  const isPackage3d2nOnly = (name) => PACKAGES_3D2N_ONLY.includes(name)
  const checkinWeekday = bkData.checkin
    ? new Date(`${bkData.checkin}T00:00:00`).toLocaleDateString('en-MY', { weekday: 'long' })
    : ''
  const checkoutWeekday = bkData.checkout
    ? new Date(`${bkData.checkout}T00:00:00`).toLocaleDateString('en-MY', { weekday: 'long' })
    : ''
  const [paxDraft, setPaxDraft] = useState({
    adult: String(bkData.pax?.adult ?? 1),
    kid: String(bkData.pax?.kid ?? 0),
    elderly: String(bkData.pax?.elderly ?? 0),
    kidInfant: String(bkData.pax?.kidInfant ?? 0),
  })

  useEffect(() => {
    setPaxDraft({
      adult: String(bkData.pax?.adult ?? 1),
      kid: String(bkData.pax?.kid ?? 0),
      elderly: String(bkData.pax?.elderly ?? 0),
      kidInfant: String(bkData.pax?.kidInfant ?? 0),
    })
  }, [bkData.pax?.adult, bkData.pax?.kid, bkData.pax?.elderly, bkData.pax?.kidInfant])

  const handlePaxChange = (field, value) => {
    const digitsOnly = value.replace(/\D/g, '')
    const normalized = digitsOnly.replace(/^0+(?=\d)/, '')
    setPaxDraft((prev) => ({ ...prev, [field]: normalized }))
    if (normalized === '') return
    const num = Number(normalized)
    if (field === 'kid') {
      const nextKid = num
      const capInfant = Math.min(Math.max(0, bkData.pax?.kidInfant ?? 0), nextKid)
      patchBkData({ pax: { ...bkData.pax, kid: nextKid, kidInfant: capInfant } })
      if (capInfant !== (bkData.pax?.kidInfant ?? 0)) {
        setPaxDraft((prev) => ({ ...prev, kidInfant: String(capInfant) }))
      }
      return
    }
    if (field === 'kidInfant') {
      const kid = Math.max(0, bkData.pax?.kid ?? 0)
      const nextInfant = Math.min(num, kid)
      patchBkData({ pax: { ...bkData.pax, kidInfant: nextInfant } })
      return
    }
    patchBkData({ pax: { ...bkData.pax, [field]: num } })
  }

  const handlePaxBlur = (field, defaultValue) => {
    if (paxDraft[field] !== '') return
    setPaxDraft((prev) => ({ ...prev, [field]: String(defaultValue) }))
    patchBkData({ pax: { ...bkData.pax, [field]: defaultValue } })
  }

  const getPaxPackageSelections = () => {
    const fallback = bkData.packageType || 'Free & Easy'
    const current = Array.isArray(bkData.packageAssignments) ? bkData.packageAssignments : []
    return Array.from({ length: totalPax }, (_, i) => current[i] || fallback)
  }

  const toggleSplitPackages = () => {
    if (totalPax <= 1) return
    if (bkData.splitPackages) {
      const firstPackage = getPaxPackageSelections()[0] || 'Free & Easy'
      patchBkData({
        splitPackages: false,
        packageAssignments: [],
        packageType: firstPackage,
      })
      return
    }
    const initialAssignments = getPaxPackageSelections()
    patchBkData({
      splitPackages: true,
      packageAssignments: initialAssignments,
      packageType: initialAssignments.every((p) => p === initialAssignments[0])
        ? initialAssignments[0]
        : 'Mixed Package',
    })
  }

  const setPersonPackage = (index, value) => {
    const next = getPaxPackageSelections()
    next[index] = value
    const unique = [...new Set(next.filter(Boolean))]
    patchBkData({
      splitPackages: true,
      packageAssignments: next,
      packageType: unique.length === 1 ? unique[0] : 'Mixed Package',
    })
  }

  const resetAllSelections = () => {
    resetBooking()
    setBkStep(0)
    patchBkData({
      checkin: '',
      checkout: '',
      packageType: undefined,
      splitPackages: false,
      packageAssignments: [],
      course: undefined,
      room: undefined,
      roomRate: null,
      pricingMeta: null,
      addons: [],
      fees: null,
      agentCode: '',
      voucher: '',
      agent: null,
      guestName: '',
      phone: '',
      email: '',
      ic: '',
      remarks: '',
    })
  }

  const stepper = (
    <div className="stepper">
      {BOOKING_STEPS.map((s, i) => {
        const cls = i < bkStep ? 'done' : i === bkStep ? 'active' : ''
        return (
          <Fragment key={s.label}>
            {i > 0 && <div className="step-line" />}
            <div className={`step ${cls}`}>
              <div className="step-num">{i < bkStep ? '✓' : i + 1}</div>
              <div className="step-label">{s.label}</div>
            </div>
          </Fragment>
        )
      })}
    </div>
  )

  const nav = (extra = null) => (
    <div className="flex gap8 mt16 jb">
      <button type="button" className="btn btn-ghost" disabled={bkStep === 0} onClick={() => prevBkStep()}>
        ← Back
      </button>
      {extra}
      <button type="button" className="btn btn-primary" onClick={() => advanceBkStep()}>
        Next →
      </button>
    </div>
  )

  let body = null
  if (bkStep === 0) {
    body = (
      <div className="card">
        <div className="card-title">📅👥 Step 1: Stay Details & Pax</div>
        <div className="form-row">
          <div className="fgroup">
            <label className="lbl">Check-in Date</label>
            <input
              type="date"
              value={bkData.checkin || ''}
              onChange={(e) => patchBkData({ checkin: e.target.value })}
            />
            {checkinWeekday && (
              <div className="text-muted" style={{ fontSize: '0.78rem', marginTop: 4 }}>
                {checkinWeekday}
              </div>
            )}
          </div>
          <div className="fgroup">
            <label className="lbl">Check-out Date</label>
            <input
              type="date"
              value={bkData.checkout || ''}
              onChange={(e) => patchBkData({ checkout: e.target.value })}
            />
            {checkoutWeekday && (
              <div className="text-muted" style={{ fontSize: '0.78rem', marginTop: 4 }}>
                {checkoutWeekday}
              </div>
            )}
          </div>
        </div>
        {stayDuration && (
          <div
            className="alert alert-info mt8"
            style={{ display: 'inline-block', width: 'fit-content', paddingRight: 14 }}
          >
            Stay Duration: <strong>{stayDuration.days} days / {stayDuration.nights} nights</strong>
          </div>
        )}
        <div className="fgroup mb16">
          <label className="lbl">Guest Nationality</label>
          <select
            value={bkData.nationality}
            onChange={(e) => patchBkData({ nationality: e.target.value })}
          >
            <option>Malaysian</option>
            <option>Foreigner</option>
          </select>
        </div>
        <div className="form-row r3">
          <div className="fgroup">
            <label className="lbl">Adults</label>
            <input
              type="text"
              inputMode="numeric"
              pattern="[0-9]*"
              value={paxDraft.adult}
              onFocus={() => setPaxDraft((prev) => ({ ...prev, adult: '' }))}
              onChange={(e) => handlePaxChange('adult', e.target.value)}
              onBlur={() => handlePaxBlur('adult', 1)}
            />
          </div>
          <div className="fgroup">
            <label className="lbl">Children (age 3-12)</label>
            <input
              type="text"
              inputMode="numeric"
              pattern="[0-9]*"
              value={paxDraft.kid}
              onFocus={() => setPaxDraft((prev) => ({ ...prev, kid: '' }))}
              onChange={(e) => handlePaxChange('kid', e.target.value)}
              onBlur={() => handlePaxBlur('kid', 0)}
            />
            <div className="text-muted" style={{ fontSize: '0.72rem', marginTop: 4 }}>
              Ages 3–12: RM{CHILD_STAY_RM_PER_NIGHT}/child/night (check-in date). Under 3 free — set below.
            </div>
          </div>
          <div className="fgroup">
            <label className="lbl">Elderly (senior)</label>
            <input
              type="text"
              inputMode="numeric"
              pattern="[0-9]*"
              value={paxDraft.elderly}
              onFocus={() => setPaxDraft((prev) => ({ ...prev, elderly: '' }))}
              onChange={(e) => handlePaxChange('elderly', e.target.value)}
              onBlur={() => handlePaxBlur('elderly', 0)}
            />
          </div>
        </div>

        <div
          className="alert alert-info"
          style={{ display: 'inline-block', width: 'fit-content', paddingRight: 14 }}
        >
          Total Pax:{' '}
          <strong>
            {(bkData.pax?.adult || 1) + (bkData.pax?.kid || 0) + (bkData.pax?.elderly || 0)}
          </strong>{' '}
          — room capacity uses everyone; package DB tier uses adults + elderly only; children via child stay fee
        </div>
        {nav()}
      </div>
    )
  } else if (bkStep === 1) {
    body = (
      <div className="card">
        <div className="flex ac jb">
          <div className="card-title" style={{ marginBottom: 0 }}>🎁 Step 2: Select Package</div>
          {totalPax > 1 && (
            <button
              type="button"
              className={`btn btn-sm ${bkData.splitPackages ? 'btn-primary' : 'btn-ghost'}`}
              onClick={toggleSplitPackages}
            >
              {bkData.splitPackages ? 'Single Package for All' : 'Split by Person'}
            </button>
          )}
        </div>
        <div className="mb16" />
        <div className="alert alert-info" style={{ marginBottom: 12 }}>
          <strong>Note:</strong> Set Step 1 dates to match the course stay length.
          <div style={{ marginTop: 8, marginBottom: 6 }}>
            <strong>4 days 3 nights</strong> (3 nights) only:
          </div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
            <div>
              1){' '}
              <code>SSI Open Water Scuba Diver</code>
            </div>
            <div>
              2){' '}
              <code>PADI Open Water Scuba Diver</code>
            </div>
            <div>
              3){' '}
              <code>SSI EFR &amp; React Right / EFR &amp; Rescue Scuba Diver</code>
            </div>
            <div>
              4){' '}
              <code>PADI EFR &amp; React Right / EFR &amp; Rescue Scuba Diver</code>
            </div>
          </div>
          <div style={{ marginTop: 10, marginBottom: 6 }}>
            <strong>3 days 2 nights</strong> (2 nights) only:
          </div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
            <div>
              5){' '}
              <code>SSI Advanced Adventurer / Advanced Open Water Scuba Diver</code>
            </div>
            <div>
              6){' '}
              <code>PADI Advanced Adventurer / Advanced Open Water Scuba Diver</code>
            </div>
          </div>
        </div>
        <div className="g2 mb16">
          {Object.entries(PACKAGES).map(([k, v]) => {
            const locked4d3n = isPackage4d3nOnly(k) && !is4d3nStay
            const locked3d2n = isPackage3d2nOnly(k) && !is3d2nStay
            const durationLocked = locked4d3n || locked3d2n
            const durationTitle = locked4d3n
              ? 'This package requires 4 days 3 nights (3 nights).'
              : locked3d2n
                ? 'This package requires 3 days 2 nights (2 nights).'
                : undefined
            return (
            <button
              key={k}
              type="button"
              disabled={durationLocked}
              title={durationTitle}
              className={`room-card${bkData.packageType === k ? ' available picked' : ''}${durationLocked ? ' blocked' : ''}`}
              onClick={() =>
                patchBkData({
                  packageType: k,
                  ...(bkData.splitPackages
                    ? { packageAssignments: Array.from({ length: totalPax }, () => k) }
                    : {}),
                })
              }
              style={{ textAlign: 'left', padding: 16 }}
            >
              <div className="fw6">{k}</div>
              <div className="text-muted" style={{ fontSize: '0.75rem', marginTop: 4 }}>
                {v.desc}
              </div>
              <div style={{ marginTop: 8 }}>
                {v.includes.map((i) => (
                  <span key={i} className="pill pill-teal" style={{ marginRight: 4, marginBottom: 4 }}>
                    {i}
                  </span>
                ))}
              </div>
            </button>
            )
          })}
        </div>
        {bkData.splitPackages && totalPax > 1 && (
          <div className="card mb16">
            <div className="section-label">Select package per person</div>
            <div className="form-row r1">
              {getPaxPackageSelections().map((pkg, idx) => (
                <div key={`person-package-${idx}`} className="fgroup">
                  <label className="lbl">Person {idx + 1}</label>
                  <select
                    value={pkg}
                    onChange={(e) => setPersonPackage(idx, e.target.value)}
                  >
                    {Object.keys(PACKAGES).map((name) => {
                      const opt4 = isPackage4d3nOnly(name) && !is4d3nStay
                      const opt3 = isPackage3d2nOnly(name) && !is3d2nStay
                      const optLocked = opt4 || opt3
                      const suffix = opt4 ? ' (4D3N only)' : opt3 ? ' (3D2N only)' : ''
                      return (
                        <option key={name} value={name} disabled={optLocked}>
                          {name}
                          {suffix}
                        </option>
                      )
                    })}
                  </select>
                </div>
              ))}
            </div>
            <div className="alert alert-info mt8" style={{ marginBottom: 0 }}>
              Selected mode: <strong>{bkData.packageType || 'Not selected'}</strong>
            </div>
          </div>
        )}
        {nav()}
      </div>
    )
  } else if (bkStep === 2) {
    const selectedRoom = rooms.find((r) => r.id === bkData.room)
    const requiredAdults = Math.max(1, bkData.pax?.adult || 1)
    const selectedRoomType = ROOM_TYPES.find((t) => t.type === selectedRoom?.type)
    const selectedRoomMax = selectedRoomType?.maxPax || 0
    body = (
      <div className="card">
        <div className="card-title">🏠 Step 3: Select Room</div>
        <div className="room-choice-grid mb16">
          {ROOM_TYPES.filter((typeCfg) => typeCfg.maxPax >= requiredAdults).map((typeCfg) => {
            const availableRooms = rooms.filter(
              (r) => r.status === 'available' && r.type === typeCfg.type
            )
            const selectedForType = selectedRoom?.type === typeCfg.type
            const selectedRoomId = selectedForType && availableRooms.some((r) => r.id === selectedRoom?.id)
              ? selectedRoom?.id || ''
              : ''
            return (
              <div key={typeCfg.code} className={`room-choice-card${selectedForType ? ' picked' : ''}`}>
                <img
                  src={ROOM_TYPE_IMAGES[typeCfg.type]}
                  alt={typeCfg.type}
                  className="room-choice-image"
                  loading="lazy"
                />
                <div className="room-choice-title">{typeCfg.type}</div>
                <div className="room-choice-subtitle">{ROOM_TYPE_SUBTITLE[typeCfg.type] || 'Room Type'}</div>
                <div className="form-row r1 mt8" style={{ marginBottom: 8 }}>
                  <div className="fgroup">
                    <label className="lbl">Available Rooms</label>
                    <select
                      value={selectedRoomId}
                      disabled={!availableRooms.length}
                      onChange={(e) =>
                        patchBkData({
                          room: e.target.value || undefined,
                          roomRate: null,
                          pricingMeta: null,
                        })
                      }
                    >
                      <option value="">Select room...</option>
                      {availableRooms.map((room) => (
                        <option key={room.id} value={room.id}>
                          {room.id}
                        </option>
                      ))}
                    </select>
                  </div>
                </div>
                <button
                  type="button"
                  className="btn btn-primary btn-sm room-select-btn"
                  disabled={!selectedRoomId}
                  onClick={() =>
                    patchBkData({
                      room: selectedRoomId,
                      roomRate: null,
                      pricingMeta: null,
                    })
                  }
                >
                  {selectedForType && selectedRoomId ? `Selected ${selectedRoomId}` : 'Select Room'}
                </button>
                <div className="room-choice-meta">
                  Max {typeCfg.maxPax} pax • Available now: {availableRooms.length}
                </div>
              </div>
            )
          })}
        </div>
        {selectedRoom && selectedRoomMax >= requiredAdults ? (
          <div className="alert alert-success mt8">Selected room: {selectedRoom.id} ({selectedRoom.type})</div>
        ) : selectedRoom ? (
          <div className="alert alert-warn mt8">
            Selected room max {selectedRoomMax} pax only. Please choose a room that supports {requiredAdults} adults.
          </div>
        ) : (
          <div className="alert alert-warn mt8">Please choose a room type to continue.</div>
        )}
        <div className="alert alert-info mt8">
          Price will be fetched from database (packagepricing) after you click Next.
        </div>
        {nav()}
      </div>
    )
  } else if (bkStep === 3) {
    const rr = bkData.roomRate || 280
    body = (
      <div className="card">
        <div className="card-title">➕ Step 4: Add-ons & Extras</div>
        <div className="g2 mb16">
          {ADDONS.map((a) => {
            const price = a.priceKey === 'roomRate' ? rr : a.price
            const sel = bkData.addons?.find((x) => x.id === a.id)
            return (
              <button
                key={a.id}
                type="button"
                className={`room-card${sel ? ' available picked' : ''}`}
                onClick={() =>
                  toggleAddon({
                    id: a.id,
                    name: a.name,
                    price,
                  })
                }
                style={{ textAlign: 'left', padding: 12 }}
              >
                <div className="flex ac gap8">
                  <span style={{ fontSize: '1.3rem' }}>{a.emoji}</span>
                  <div>
                    <div className="fw6" style={{ fontSize: '0.82rem' }}>
                      {a.name}
                    </div>
                    <div className="text-gold" style={{ fontSize: '0.75rem' }}>
                      RM {price}
                    </div>
                  </div>
                  {sel && (
                    <span className="pill pill-teal" style={{ marginLeft: 'auto' }}>
                      ✓ Added
                    </span>
                  )}
                </div>
              </button>
            )
          })}
        </div>
        {nav()}
      </div>
    )
  } else if (bkStep === 4) {
    const f = bkData.fees
    const n = f?.nights || 1
    const days = n + 1
    const totalPax = f?.totalPax || (bkData.pax?.adult || 1) + (bkData.pax?.kid || 0) + (bkData.pax?.elderly || 0)
    const packagePaxForPackageLine = f?.packagePricingPax ?? packagePricingHeadcount(bkData.pax)
    const baseRate = f?.baseRate || 280
    const ws = f?.weekendSurcharge || 0
    const selectedRoom = rooms.find((r) => r.id === bkData.room) || null
    const selectedRoomType = selectedRoom?.type || null
    const serviceChargePreview =
      ((f?.packageSubtotal || baseRate * packagePaxForPackageLine) +
        ws +
        (f?.boatFee || 0) +
        (f?.tourismTax || 0) +
        (f?.gratuity || 0) +
        (f?.childStayFee || 0)) *
      0.1
    const mixedQuotes = Array.isArray(bkData?.pricingMeta?.quotesByPackage)
      ? bkData.pricingMeta.quotesByPackage
      : []
    body = (
      <div className="card">
        <div className="card-title">🤝💸 Step 5: Agent / Voucher & Fees</div>
        <div className="form-row">
          <div className="fgroup">
            <label className="lbl">Agent Code</label>
            <input
              type="text"
              placeholder="e.g. DISC10"
              value={bkData.agentCode || ''}
              onChange={(e) =>
                patchBkData({ agentCode: e.target.value.toUpperCase(), agent: null })
              }
            />
          </div>
          <div className="fgroup">
            <label className="lbl">Voucher / Promo Code</label>
            <input
              type="text"
              value={bkData.voucher || ''}
              onChange={(e) => patchBkData({ voucher: e.target.value.toUpperCase() })}
            />
          </div>
        </div>
        {agentValidateHtml === 'success' && bkData.agent && (
          <div className="alert alert-success mt8">
            ✅ Agent found: <strong>{bkData.agent.name}</strong> — Commission: {bkData.agent.rate}
            {bkData.agent.type === 'percent' ? '%' : ' RM'}
          </div>
        )}
        {agentValidateHtml === 'warn' && (
          <div className="alert alert-warn mt8">⚠ Agent code not found</div>
        )}
        <button type="button" className="btn btn-ghost btn-sm mt8" onClick={() => validateAgent()}>
          Validate Code
        </button>
        <div className="mb16" />
        <div className="invoice invoice-summary-clear">
          <div className="inv-section-title">Auto-calculated</div>
          <div className="inv-row sub">
            <span>Stay Duration</span>
            <span>
              {days}D{n}N
            </span>
          </div>
          <div className="inv-row sub">
            <span>Room & Pax</span>
            <span>
              {(selectedRoom?.id || '-')}{selectedRoomType ? ` (${selectedRoomType})` : ''} • {totalPax} pax
            </span>
          </div>
          <div className="inv-row">
            <span>
              {mixedQuotes.length
                ? `Package (mixed by person selection${selectedRoomType ? ` - ${selectedRoomType}` : ''})`
                : `Package (${packagePaxForPackageLine} pax × RM${baseRate}${selectedRoomType ? ` - ${selectedRoomType}` : ''})`}
            </span>
            <span>{fmtMoney(f?.packageSubtotal || baseRate * packagePaxForPackageLine)}</span>
          </div>
          {mixedQuotes.map((q) => (
            <div key={`step6-${q.packageName}`} className="inv-row sub">
              <span>
                ↪ {q.packageName} ({q.count} pax × {fmtMoney(q.unitRate)})
                {q.roomType ? ` - ${q.roomType}` : ''}
              </span>
              <span>{fmtMoney(q.subtotal)}</span>
            </div>
          ))}
          {ws > 0 ? (
            <div className="inv-row sub">
              <span>↪ Weekend Surcharge (Fri & Sat)</span>
              <span>+{fmtMoney(ws)}</span>
            </div>
          ) : null}
          {f?.boatFee ? (
            <div className="inv-row sub">
              <span>↪ Boat Fee (RM135 per adult)</span>
              <span>+{fmtMoney(f.boatFee)}</span>
            </div>
          ) : null}
          {f?.childStayFee ? (
            <div className="inv-row sub">
              <span>
                ↪ Child stay (ages 3–12, RM{CHILD_STAY_RM_PER_NIGHT}/child/night × {f.childrenCharged312 ?? '—'}{' '}
                children × {n} night{n === 1 ? '' : 's'})
              </span>
              <span>+{fmtMoney(f.childStayFee)}</span>
            </div>
          ) : null}
          <div className="inv-row sub">
            <span>↪ Tourism Tax (Foreigner only)</span>
            <span>+{fmtMoney(f?.tourismTax || 0)}</span>
          </div>
          <div className="inv-row sub">
            <span>↪ Gratuity (RM 5 per person)</span>
            <span>+{fmtMoney(f?.gratuity || 0)}</span>
          </div>
          <div className="inv-row sub">
            <span>↪ Service Charge (10%)</span>
            <span>+{fmtMoney(serviceChargePreview)}</span>
          </div>
        </div>
        <div className="alert alert-info mt8">Surcharges are applied automatically.</div>
        {nav()}
      </div>
    )
  } else if (bkStep === 5) {
    const t = calcBookingTotal(bkData)
    const totalPax = (bkData.pax?.adult || 1) + (bkData.pax?.kid || 0) + (bkData.pax?.elderly || 0)
    const room = rooms.find((r) => r.id === bkData.room)
    const mixedQuotes = Array.isArray(bkData?.pricingMeta?.quotesByPackage)
      ? bkData.pricingMeta.quotesByPackage
      : []
    body = (
      <div className="card">
        <div className="card-title">📋 Step 6: Booking Summary</div>
        <div className="invoice invoice-summary-clear">
          <div className="inv-header">
            <div>
              <div className="inv-logo">The One Tenggol Island Resort</div>
              <div className="text-muted" style={{ fontSize: '0.72rem', marginTop: 2 }}>
                Booking Summary
              </div>
            </div>
            <div className="inv-meta">{new Date().toLocaleDateString('en-MY')}</div>
          </div>
          <hr className="inv-divider" />
          <div className="g2" style={{ fontSize: '0.8rem', marginBottom: 12 }}>
            <div>
              <div className="text-muted">Nationality</div>
              <div>{bkData.nationality}</div>
            </div>
            <div>
              <div className="text-muted">Total Pax</div>
              <div>
                {totalPax} ({bkData.pax?.adult}A {bkData.pax?.kid}C {bkData.pax?.elderly}E)
                {(bkData.pax?.kid || 0) > 0 ? (
                  <div className="text-muted" style={{ fontSize: '0.72rem', marginTop: 2 }}>
                    Children: {bkData.pax?.kidInfant ?? 0} under 3 (free),{' '}
                    {Math.max(0, (bkData.pax?.kid || 0) - Math.min(bkData.pax?.kidInfant ?? 0, bkData.pax?.kid || 0))}{' '}
                    at child nightly rate
                  </div>
                ) : null}
              </div>
            </div>
            <div>
              <div className="text-muted">Package</div>
              <div>{bkData.packageType || 'Not selected'}</div>
            </div>
            <div>
              <div className="text-muted">Room</div>
              <div>{room ? `${room.id} (${room.type})` : 'Not selected'}</div>
            </div>
            <div>
              <div className="text-muted">Stay</div>
              <div>
                {fmt(bkData.checkin)} → {fmt(bkData.checkout)} ({t.n} nights)
              </div>
            </div>
          </div>
          <hr className="inv-divider" />
          <div className="inv-section-title">Charges</div>
          <div className="inv-row">
            <span>
              {mixedQuotes.length
                ? 'Package (mixed by person selection)'
                : `Package (${t.packagePricingPax} pax × RM${t.baseRate})`}
            </span>
            <span>{fmtMoney(t.base)}</span>
          </div>
          {mixedQuotes.map((q) => (
            <div key={`step8-${q.packageName}`} className="inv-row sub">
              <span>
                {q.packageName} ({q.count} pax × {fmtMoney(q.unitRate)})
                {q.roomType ? ` - ${q.roomType}` : ''}
              </span>
              <span>{fmtMoney(q.subtotal)}</span>
            </div>
          ))}
          {t.ws ? (
            <div className="inv-row sub">
              <span>Weekend Surcharge</span>
              <span>+{fmtMoney(t.ws)}</span>
            </div>
          ) : null}
          {t.boat ? (
            <div className="inv-row sub">
              <span>Boat Fee (RM135 per adult)</span>
              <span>+{fmtMoney(t.boat)}</span>
            </div>
          ) : null}
          {t.tt ? (
            <div className="inv-row sub">
              <span>Tourism Tax (Foreigner only)</span>
              <span>+{fmtMoney(t.tt)}</span>
            </div>
          ) : null}
          {t.grat ? (
            <div className="inv-row sub">
              <span>Gratuity</span>
              <span>+{fmtMoney(t.grat)}</span>
            </div>
          ) : null}
          {t.childStayFee ? (
            <div className="inv-row sub">
              <span>
                Child stay (3–12 yrs, RM{CHILD_STAY_RM_PER_NIGHT}/child/night × {t.n} night{t.n === 1 ? '' : 's'})
              </span>
              <span>+{fmtMoney(t.childStayFee)}</span>
            </div>
          ) : null}
          <div className="inv-row sub">
            <span>Service Charge (10%)</span>
            <span>+{fmtMoney(t.serviceCharge)}</span>
          </div>
          {(bkData.addons || []).map((a) => (
            <div key={a.id} className="inv-row sub">
              <span>{a.name}</span>
              <span>+{fmtMoney(a.price)}</span>
            </div>
          ))}
          {t.agentDisc ? (
            <div className="inv-row sub text-green">
              <span>Agent Discount ({bkData.agent?.code})</span>
              <span>-{fmtMoney(t.agentDisc)}</span>
            </div>
          ) : null}
          <div className="inv-row total inv-row-total-clear">
            <span>Total Amount</span>
            <span>{fmtMoney(t.total)}</span>
          </div>
        </div>
        <div className="fgroup mt12">
          <label className="lbl">Guest Name *</label>
          <input
            type="text"
            value={bkData.guestName || ''}
            onChange={(e) => patchBkData({ guestName: e.target.value })}
            placeholder="Full name"
          />
        </div>
        <div className="form-row mt8">
          <div className="fgroup">
            <label className="lbl">Phone</label>
            <input
              type="text"
              value={bkData.phone || ''}
              onChange={(e) => patchBkData({ phone: e.target.value })}
            />
          </div>
          <div className="fgroup">
            <label className="lbl">Email</label>
            <input
              type="text"
              value={bkData.email || ''}
              onChange={(e) => patchBkData({ email: e.target.value })}
            />
          </div>
        </div>
        <div className="form-row mt8">
          <div className="fgroup">
            <label className="lbl">IC / Passport</label>
            <input
              type="text"
              value={bkData.ic || ''}
              onChange={(e) => patchBkData({ ic: e.target.value })}
            />
          </div>
          <div className="fgroup">
            <label className="lbl">Remarks</label>
            <input
              type="text"
              value={bkData.remarks || ''}
              onChange={(e) => patchBkData({ remarks: e.target.value })}
            />
          </div>
        </div>
        {nav()}
      </div>
    )
  } else if (bkStep === 6) {
    const t = calcBookingTotal(bkData)
    body = (
      <div className="card">
        <div className="card-title">💳 Step 7: Payment</div>
        <div className="g2">
          <div>
            <div className="fgroup mb16">
              <label className="lbl">Payment Method</label>
              <select
                value={bkData.payMethod}
                onChange={(e) => patchBkData({ payMethod: e.target.value })}
              >
                <option value="cash">💵 Cash</option>
                <option value="fpx">🏦 FPX / Online Banking</option>
                <option value="card">💳 Credit / Debit Card</option>
                <option value="wallet">👛 Guest Wallet</option>
                <option value="deposit-only">📥 Deposit Only</option>
              </select>
            </div>
            <div className="fgroup mb16">
              <label className="lbl">Amount Paid (RM)</label>
              <input
                type="number"
                value={bkData.amountPaid ?? t.total}
                onChange={(e) => patchBkData({ amountPaid: +e.target.value })}
              />
            </div>
            <div className="fgroup mb16">
              <label className="lbl">Deposit / Balance</label>
              <input
                type="number"
                placeholder="0 = full payment"
                onChange={(e) => patchBkData({ deposit: +e.target.value })}
              />
            </div>
          </div>
          <div className="invoice">
            <div className="inv-row">
              <span>Room Charges</span>
              <span>{fmtMoney(t.base + t.ws)}</span>
            </div>
            <div className="inv-row">
              <span>Fees, child stay &amp; service (10%)</span>
              <span>{fmtMoney(t.boat + t.tt + t.grat + (t.childStayFee || 0) + t.serviceCharge)}</span>
            </div>
            <div className="inv-row">
              <span>Add-ons</span>
              <span>{fmtMoney(t.addonsTotal)}</span>
            </div>
            {t.agentDisc ? (
              <div className="inv-row">
                <span>Agent Discount</span>
                <span className="text-green">-{fmtMoney(t.agentDisc)}</span>
              </div>
            ) : null}
            <div className="inv-row total">
              <span>GRAND TOTAL</span>
              <span>{fmtMoney(t.total)}</span>
            </div>
          </div>
        </div>
        <div className="flex gap8 mt16">
          <button type="button" className="btn btn-ghost" onClick={() => prevBkStep()}>
            ← Back
          </button>
          <button type="button" className="btn btn-success" style={{ flex: 1 }} onClick={() => confirmBooking()}>
            ✅ Confirm Booking & Generate Invoice
          </button>
        </div>
      </div>
    )
  }

  return (
    <>
      <div className="page-header">
        <div>
          <div className="page-title">
            New <span>Booking</span>
          </div>
          <div className="page-sub">Follow the steps to create a booking</div>
        </div>
        <button type="button" className="btn btn-ghost btn-sm" onClick={() => resetAllSelections()}>
          🔄 Reset All
        </button>
      </div>
      {stepper}
      {body}
    </>
  )
}
