import { useState, useEffect, useRef } from 'react'
import { format, differenceInDays } from 'date-fns'
import {
  X, Mail, Calendar, Users, CreditCard, Tag, CheckCircle, XCircle,
  Printer, ScanLine, Banknote, Building2, Plus, Pencil,
  FileText, FileCheck, Receipt, IdCard, AlertTriangle,
  Trash2, Loader2, UserCheck, Baby, Search, LogIn, KeyRound,
} from 'lucide-react'
import {
  cn, BOOKING_STATUS_BADGE, BOOKING_STATUS_LABELS,
  SOURCE_COLORS, SOURCE_LABELS, formatCurrency, nightsCount,
} from '../../lib/utils'
import type { Booking, Room } from '../../types'
import { api, type BookingGuest, type BookingGuestPayload, type GuestApiType } from '../../lib/api'

const fmtDate = (iso: string) =>
  new Intl.DateTimeFormat('ru-RU', { day: 'numeric', month: 'long' }).format(new Date(iso))
import { Badge } from '../ui/Badge'
import { MOCK_DISCOUNTS } from '../../pages/DiscountsPage'

// ─── Local types ──────────────────────────────────────────────────────────────

interface PassportData {
  lastName: string; firstName: string; middleName: string
  dob: string; series: string; number: string
  issuedBy: string; issueDate: string; regAddress: string
}

interface Payment {
  id: string; date: string; amount: number
  method: 'cash' | 'card' | 'transfer'; note: string
}

type Tab = 'booking' | 'guest' | 'payment' | 'docs'

const TABS: { id: Tab; label: string }[] = [
  { id: 'booking', label: 'Бронь' },
  { id: 'guest',   label: 'Гости' },
  { id: 'payment', label: 'Оплата' },
  { id: 'docs',    label: 'Документы' },
]

const METHODS: { id: 'cash' | 'card' | 'transfer'; label: string; icon: React.ElementType }[] = [
  { id: 'cash',     label: 'Наличные', icon: Banknote },
  { id: 'card',     label: 'Карта',    icon: CreditCard },
  { id: 'transfer', label: 'Перевод',  icon: Building2 },
]

const DOCUMENTS = [
  { id: 'reg',      label: 'Регистрационная карта',  desc: 'Персональные данные гостя',       icon: IdCard,    always: true  },
  { id: 'contract', label: 'Договор на проживание',  desc: 'Договор между гостем и отелем',   icon: FileText,  always: true  },
  { id: 'invoice',  label: 'Счёт на оплату',         desc: 'Счёт для оплаты проживания',      icon: Receipt,   always: true  },
  { id: 'act',      label: 'Акт об оказании услуг',  desc: 'Закрывающий документ при выезде', icon: FileCheck, always: false },
]

// ─── Component ────────────────────────────────────────────────────────────────

interface BookingDetailPanelProps {
  booking: Booking
  room?: Room
  rooms?: Room[]
  allBookings?: Booking[]
  slug?: string
  onClose: () => void
  onUpdate: (id: string, data: Partial<Booking>) => void
  onBulkUpdate?: (updates: Array<{ id: string; data: Partial<Booking> }>) => void
}

export function BookingDetailPanel({ booking, room, rooms, allBookings, slug, onClose, onUpdate, onBulkUpdate }: BookingDetailPanelProps) {
  const [tab, setTab] = useState<Tab>('booking')

  // ── Multi-guest state ────────────────────────────────────────────────────
  const [bgGuests, setBgGuests]         = useState<BookingGuest[]>([])
  const [bgLoading, setBgLoading]       = useState(false)
  const [bgLoaded, setBgLoaded]         = useState(false)
  const [requireDocs, setRequireDocs]   = useState(false)
  const [showGuestForm, setShowGuestForm] = useState(false)
  const [editingBg, setEditingBg]       = useState<BookingGuest | null>(null)
  const [bgForm, setBgForm]             = useState<BookingGuestPayload>({})
  const [bgSaving, setBgSaving]         = useState(false)
  // Autocomplete
  const [acQuery, setAcQuery]           = useState('')
  const [acResults, setAcResults]       = useState<GuestApiType[]>([])
  const [acLoading, setAcLoading]       = useState(false)
  const acTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
  const acWrapRef  = useRef<HTMLDivElement | null>(null)

  // Hotel timing settings (for early/late fee warnings)
  const [hotelCheckInTime,      setHotelCheckInTime]      = useState('14:00')
  const [hotelCheckOutTime,     setHotelCheckOutTime]     = useState('12:00')
  const [earlyCheckinEnabled,   setEarlyCheckinEnabled]   = useState(false)
  const [lateCheckoutEnabled,   setLateCheckoutEnabled]   = useState(false)
  const [hotelTimingsLoaded,    setHotelTimingsLoaded]    = useState(false)

  useEffect(() => {
    if (!slug || hotelTimingsLoaded) return
    api.hotelSettings.get(slug)
      .then(s => {
        const st = s as Record<string, unknown>
        if (st.check_in_time)  setHotelCheckInTime(String(st.check_in_time).slice(0, 5))
        if (st.check_out_time) setHotelCheckOutTime(String(st.check_out_time).slice(0, 5))
        setEarlyCheckinEnabled(Boolean(st.early_checkin_enabled))
        setLateCheckoutEnabled(Boolean(st.late_checkout_enabled))
        setHotelTimingsLoaded(true)
      })
      .catch(console.error)
  }, [slug, hotelTimingsLoaded])

  // Load booking guests + settings when tab is activated
  useEffect(() => {
    if (tab !== 'guest' || !slug || bgLoaded) return
    setBgLoading(true)
    Promise.all([
      api.bookingGuests.list(slug, booking.id),
      api.hotelSettings.get(slug).catch(() => ({})),
    ])
      .then(([guests, settings]) => {
        setBgGuests(guests)
        setRequireDocs(Boolean((settings as { require_guest_docs?: boolean }).require_guest_docs))
        setBgLoaded(true)
        // Auto-open add form pre-filled with booking FIO when no guests yet
        if (guests.length === 0 && booking.status !== 'cancelled') {
          const parts = (booking.guestName ?? '').split(' ')
          setBgForm({
            last_name:   parts[0] ?? '',
            first_name:  parts[1] ?? '',
            middle_name: parts.slice(2).join(' ') || undefined,
            is_main:     true,
          })
          setShowGuestForm(true)
        }
      })
      .catch(console.error)
      .finally(() => setBgLoading(false))
  }, [tab, slug, booking.id, bgLoaded])

  // Reset when booking changes
  useEffect(() => {
    setBgLoaded(false)
    setBgGuests([])
    setShowGuestForm(false)
    setEditingBg(null)
    setBgForm({})
    setEarlyOutOpen(false)
    setEarlyOutDate(booking.checkOut.slice(0, 10))
    setEarlyOpen(false)
  }, [booking.id])

  // Parse ФИО string into form fields
  const parseFio = (val: string) => {
    const parts = val.trim().split(/\s+/)
    return { last_name: parts[0] ?? '', first_name: parts[1] ?? '', middle_name: parts.slice(2).join(' ') || undefined }
  }

  // Debounced guest autocomplete
  const handleAcInput = (val: string) => {
    setAcQuery(val)
    setBgForm(f => ({ ...f, ...parseFio(val) }))
    if (acTimerRef.current) clearTimeout(acTimerRef.current)
    if (val.length < 2 || !slug) { setAcResults([]); return }
    acTimerRef.current = setTimeout(() => {
      setAcLoading(true)
      api.guests.list(slug, val)
        .then(setAcResults)
        .catch(() => setAcResults([]))
        .finally(() => setAcLoading(false))
    }, 300)
  }

  const selectAcGuest = (g: GuestApiType) => {
    const fullName = [g.lastName, g.firstName, g.middleName].filter(Boolean).join(' ')
    setBgForm(f => ({
      ...f,
      first_name:           g.firstName,
      last_name:            g.lastName,
      middle_name:          g.middleName ?? undefined,
      birth_date:           g.birthDate ?? undefined,
      passport_series:      g.passportSeries ?? undefined,
      passport_number:      g.passportNumber ?? undefined,
      passport_issued_by:   g.passportIssuedBy ?? undefined,
      passport_issue_date:  g.passportIssueDate ?? undefined,
      nationality:          g.nationality ?? undefined,
    }))
    setAcQuery(fullName)
    setAcResults([])
  }

  const passportTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)

  const handlePassportInput = (field: 'passport_series' | 'passport_number', val: string) => {
    setBgForm(f => ({ ...f, [field]: val }))
    if (passportTimerRef.current) clearTimeout(passportTimerRef.current)
    const series  = field === 'passport_series' ? val : (bgForm.passport_series ?? '')
    const number  = field === 'passport_number'  ? val : (bgForm.passport_number  ?? '')
    const query   = (series + number).trim()
    if (query.length < 4 || !slug) return
    passportTimerRef.current = setTimeout(() => {
      api.guests.list(slug, undefined, query)
        .then(results => {
          if (results.length === 1) selectAcGuest(results[0])
        })
        .catch(() => {/* ignore */})
    }, 400)
  }

  const openAddForm = () => {
    setEditingBg(null)
    setBgForm({ is_main: bgGuests.length === 0 })
    setAcQuery('')
    setAcResults([])
    setShowGuestForm(true)
  }

  const openEditForm = (bg: BookingGuest) => {
    setEditingBg(bg)
    setBgForm({
      first_name:       bg.firstName,
      last_name:        bg.lastName,
      middle_name:      bg.middleName ?? undefined,
      birth_date:       bg.birthDate?.slice(0, 10) ?? undefined,
      is_child:         bg.isChild,
      is_main:          bg.isMain,
      passport_series:  bg.passportSeries ?? undefined,
      passport_number:  bg.passportNumber ?? undefined,
      passport_issued_by: bg.passportIssuedBy ?? undefined,
      passport_issue_date: bg.passportIssueDate?.slice(0, 10) ?? undefined,
      nationality:      bg.nationality ?? undefined,
    })
    setAcQuery([bg.lastName, bg.firstName, bg.middleName].filter(Boolean).join(' '))
    setAcResults([])
    setShowGuestForm(true)
  }

  const cancelGuestForm = () => {
    setShowGuestForm(false)
    setEditingBg(null)
    setBgForm({})
    setAcResults([])
    setAcQuery('')
  }

  const saveGuest = async () => {
    if (!slug || !bgForm.first_name?.trim() || !bgForm.last_name?.trim()) {
      showToast('Введите имя и фамилию')
      return
    }
    setBgSaving(true)
    try {
      if (editingBg) {
        const updated = await api.bookingGuests.update(slug, booking.id, editingBg.id, bgForm)
        setBgGuests(prev => prev.map(g => g.id === editingBg.id ? updated : g))
      } else {
        const added = await api.bookingGuests.add(slug, booking.id, bgForm)
        setBgGuests(prev => [...prev, added])
      }
      cancelGuestForm()
    } catch {
      showToast('Ошибка при сохранении гостя')
    } finally {
      setBgSaving(false)
    }
  }

  const removeGuest = async (id: string) => {
    if (!slug) return
    try {
      await api.bookingGuests.remove(slug, booking.id, id)
      setBgGuests(prev => prev.filter(g => g.id !== id))
    } catch {
      showToast('Ошибка при удалении гостя')
    }
  }

  const adultsWithoutDocs = bgGuests.filter(g => !g.isChild && (!g.passportSeries || !g.passportNumber))

  // ── Date editing ─────────────────────────────────────────────────────────
  const [editDates, setEditDates] = useState(false)
  const [newCheckIn, setNewCheckIn]   = useState(booking.checkIn)
  const [newCheckOut, setNewCheckOut] = useState(booking.checkOut)
  const [newRoomId, setNewRoomId]     = useState(booking.roomId)
  const [conflictBooking, setConflictBooking]         = useState<Booking | null>(null)
  const [conflictResolveRoomId, setConflictResolveRoomId] = useState('')

  const canEditDates = booking.status === 'confirmed' || booking.status === 'inquiry'
  const canRelocate  = booking.status === 'checked_in'

  const today = format(new Date(), 'yyyy-MM-dd')
  const checkInDate = booking.checkIn.slice(0, 10)
  const checkOutDate = booking.checkOut.slice(0, 10)
  const canEarlyCheckIn = booking.status === 'confirmed' && checkInDate > today

  const [relocating, setRelocating] = useState(false)
  const [relocateRoomId, setRelocateRoomId] = useState(booking.roomId)

  const [earlyOpen, setEarlyOpen]           = useState(false)
  const [earlyNewCheckOut, setEarlyNewCheckOut] = useState(checkOutDate)
  const [earlyRoomId, setEarlyRoomId]       = useState(booking.roomId)
  const [earlySaving, setEarlySaving]       = useState(false)

  const [earlyOutOpen, setEarlyOutOpen]         = useState(false)
  const [earlyOutDate, setEarlyOutDate]         = useState(checkOutDate)
  const [earlyOutMethod, setEarlyOutMethod]     = useState<'cash' | 'card' | 'transfer'>('cash')
  const [earlyOutSaving, setEarlyOutSaving]     = useState(false)

  const [cardIssuing, setCardIssuing]           = useState(false)

  const freeRoomsForRelocate = (rooms ?? []).filter(r =>
    r.id !== booking.roomId &&
    !(allBookings ?? []).some(b =>
      b.id !== booking.id &&
      b.roomId === r.id &&
      b.status !== 'cancelled' && b.status !== 'no_show' && b.status !== 'checked_out' &&
      b.checkIn < booking.checkOut && b.checkOut > booking.checkIn,
    ),
  )

  const handleRelocate = () => {
    if (!relocateRoomId || relocateRoomId === booking.roomId) return
    onUpdate(booking.id, { roomId: relocateRoomId })
    setRelocating(false)
  }

  const handleEarlyCheckIn = async () => {
    if (earlyNewCheckOut <= today) { showToast('Дата выезда должна быть позже сегодня'); return }
    setEarlySaving(true)
    try {
      await onUpdate(booking.id, {
        checkIn: today,
        checkOut: earlyNewCheckOut,
        roomId: earlyRoomId,
        status: 'checked_in',
      })
      setEarlyOpen(false)
      showToast('Гость заселён досрочно')
    } finally {
      setEarlySaving(false)
    }
  }

  const handleEarlyCheckOut = async () => {
    if (earlyOutDate > booking.checkOut) { showToast('Дата не может быть позже плановой'); return }
    setEarlyOutSaving(true)
    try {
      const origNights   = differenceInDays(new Date(booking.checkOut), new Date(booking.checkIn))
      const actualNights = differenceInDays(new Date(earlyOutDate), new Date(booking.checkIn))
      const refundNights = origNights - actualNights
      if (refundNights > 0) {
        const refundAmt = Math.round(refundNights * booking.totalAmount / origNights)
        setPayments(prev => [...prev, {
          id: `refund-${Date.now()}`,
          date: new Date().toLocaleDateString('ru-RU'),
          amount: -refundAmt,
          method: earlyOutMethod,
          note: `Возврат за ${refundNights} неиспользованных ${refundNights === 1 ? 'ночь' : refundNights < 5 ? 'ночи' : 'ночей'}`,
        }])
      }
      await onUpdate(booking.id, { checkOut: earlyOutDate, status: 'checked_out' })
      setEarlyOutOpen(false)
      showToast('Гость выселен')
    } finally {
      setEarlyOutSaving(false)
    }
  }

  const findConflict = (ci: string, co: string, rid: string): Booking | null =>
    (allBookings ?? []).find(b =>
      b.id !== booking.id &&
      b.roomId === rid &&
      b.status !== 'cancelled' &&
      b.status !== 'no_show' &&
      b.status !== 'checked_out' &&
      b.checkIn < co && b.checkOut > ci,
    ) ?? null

  const handleSaveDates = () => {
    if (newCheckIn >= newCheckOut) { showToast('Дата выезда должна быть позже заезда'); return }
    const conflict = findConflict(newCheckIn, newCheckOut, newRoomId)
    if (conflict) { setConflictBooking(conflict); setConflictResolveRoomId(''); return }
    onUpdate(booking.id, { checkIn: newCheckIn, checkOut: newCheckOut, roomId: newRoomId })
  }

  const handleForceUpdate = () =>
    onUpdate(booking.id, { checkIn: newCheckIn, checkOut: newCheckOut, roomId: newRoomId })

  const handleResolveWithRoomSwap = () => {
    if (!conflictBooking || !onBulkUpdate || !conflictResolveRoomId) return
    if (findConflict(conflictBooking.checkIn, conflictBooking.checkOut, conflictResolveRoomId)) {
      showToast('Выбранный номер тоже занят на эти даты')
      return
    }
    onBulkUpdate([
      { id: booking.id, data: { checkIn: newCheckIn, checkOut: newCheckOut, roomId: newRoomId } },
      { id: conflictBooking.id, data: { roomId: conflictResolveRoomId } },
    ])
  }

  const handleIssueCard = async () => {
    if (!slug || cardIssuing) return
    setCardIssuing(true)
    try {
      const r = await api.ttlock.issueCard(slug, booking.id)
      showToast(`✓ Ключ выдан (${r.roomName})`)
    } catch (e) {
      const msg = e instanceof Error ? e.message : 'Ошибка выдачи ключа'
      showToast(`✗ ${msg}`)
    } finally {
      setCardIssuing(false)
    }
  }

  // Passport data
  const nameParts = booking.guestName.split(' ')
  const [passport, setPassport] = useState<PassportData>({
    lastName: nameParts[0] ?? '', firstName: nameParts[1] ?? '', middleName: nameParts[2] ?? '',
    dob: '', series: '', number: '', issuedBy: '', issueDate: '', regAddress: '',
  })
  const setP = <K extends keyof PassportData>(k: K, v: PassportData[K]) =>
    setPassport(prev => ({ ...prev, [k]: v }))

  // Payments
  const [payments, setPayments] = useState<Payment[]>(() =>
    booking.paidAmount > 0
      ? [{ id: 'init', date: booking.createdAt, amount: booking.paidAmount, method: 'card', note: 'Предоплата при бронировании' }]
      : []
  )
  const [showPayForm, setShowPayForm] = useState(false)
  const [payAmount, setPayAmount]     = useState('')
  const [payMethod, setPayMethod]     = useState<'cash' | 'card' | 'transfer'>('cash')
  const [payNote,   setPayNote]       = useState('')

  // Discount
  const [discountId, setDiscountId] = useState('')

  // Toast
  const [toast, setToast] = useState('')
  const showToast = (msg: string) => { setToast(msg); setTimeout(() => setToast(''), 2500) }

  // Calculations
  const nights       = nightsCount(booking.checkIn, booking.checkOut)
  const baseTotal    = booking.totalAmount
  const activeDiscs  = MOCK_DISCOUNTS.filter(d => d.isActive)
  const selDiscount  = activeDiscs.find(d => d.id === discountId)
  const discountAmt  = selDiscount
    ? selDiscount.valueType === 'percent'
      ? Math.round(baseTotal * Math.min(100, selDiscount.value) / 100)
      : Math.min(baseTotal, selDiscount.value)
    : 0
  const finalTotal = baseTotal - discountAmt
  const totalPaid  = payments.reduce((s, p) => s + p.amount, 0)
  const balance    = finalTotal - totalPaid

  const setStatus = (status: typeof booking.status) => onUpdate(booking.id, { status })

  const addPayment = () => {
    const amt = parseFloat(payAmount)
    if (!amt || amt <= 0) return
    setPayments(prev => [...prev, {
      id: `p-${Date.now()}`,
      date: new Date().toLocaleDateString('ru-RU'),
      amount: amt, method: payMethod, note: payNote,
    }])
    setPayAmount(''); setPayNote('')
    setShowPayForm(false)
    showToast(`✓ Оплата ${formatCurrency(amt)} принята`)
  }

  const printDoc = (label: string) => showToast(`🖨 «${label}» отправлен на печать`)

  const fld = 'input text-sm'
  const lbl = 'block text-xs font-medium text-slate-500 dark:text-slate-400 mb-1'

  return (
    <>
      <div className="fixed inset-0 z-40" onClick={onClose} />

      <div className="fixed right-0 top-0 bottom-0 z-50 w-full sm:w-[400px] bg-white dark:bg-slate-800 border-l border-slate-200 dark:border-slate-700 shadow-2xl flex flex-col">

        {/* Toast notification */}
        {toast && (
          <div className="absolute top-3 left-4 right-4 z-20 bg-slate-900 dark:bg-slate-700 text-white text-sm rounded-xl px-4 py-2.5 text-center shadow-lg pointer-events-none">
            {toast}
          </div>
        )}

        {/* Header */}
        <div className="px-5 pt-4 pb-3 border-b border-slate-200 dark:border-slate-700 shrink-0">
          <div className="flex items-start justify-between mb-2">
            <div>
              <h3 className="text-base font-semibold text-slate-900 dark:text-slate-100">
                {booking.guestName}
              </h3>
              <div className="flex items-center gap-2 mt-1">
                <Badge className={BOOKING_STATUS_BADGE[booking.status]}>
                  {BOOKING_STATUS_LABELS[booking.status]}
                </Badge>
                <Badge className={SOURCE_COLORS[booking.source]}>
                  {SOURCE_LABELS[booking.source]}
                </Badge>
              </div>
            </div>
            <button onClick={onClose} className="btn-ghost p-1.5 mt-0.5">
              <X size={18} />
            </button>
          </div>

          {/* Tab bar */}
          <div className="flex gap-0.5 mt-3">
            {TABS.map(t => (
              <button
                key={t.id}
                onClick={() => setTab(t.id)}
                className={cn(
                  'flex-1 py-1.5 text-xs font-medium rounded-lg transition-colors',
                  tab === t.id
                    ? 'bg-brand-600 text-white'
                    : 'text-slate-600 dark:text-slate-400 hover:bg-slate-100 dark:hover:bg-slate-700',
                )}
              >
                {t.label}
              </button>
            ))}
          </div>
        </div>

        {/* Tab content */}
        <div className="flex-1 overflow-y-auto px-5 py-4">

          {/* ── Бронь ────────────────────────────────────────────────────────── */}
          {tab === 'booking' && (
            <div className="space-y-4">
              {room && (
                <div className="rounded-xl bg-slate-50 dark:bg-slate-700/40 p-3">
                  <div className="flex items-start justify-between mb-1">
                    <p className="text-xs text-slate-500 dark:text-slate-400 font-medium">Номер</p>
                    {canRelocate && !relocating && (
                      <button
                        onClick={() => { setRelocating(true); setRelocateRoomId('') }}
                        className="flex items-center gap-1 text-xs text-amber-600 dark:text-amber-400 hover:text-amber-700 dark:hover:text-amber-300 font-medium"
                      >
                        <Pencil size={11} /> Переселить
                      </button>
                    )}
                  </div>
                  <p className="font-semibold text-slate-900 dark:text-slate-100">
                    №{room.number} — {room.type}
                  </p>
                  <p className="text-sm text-slate-500 dark:text-slate-400">
                    Этаж {room.floor} · {room.bedType} bed
                  </p>

                  {/* Форма переселения */}
                  {relocating && (
                    <div className="mt-3 space-y-2 pt-3 border-t border-slate-200 dark:border-slate-600">
                      <p className="text-xs font-medium text-amber-700 dark:text-amber-400">Переселить гостя в другой номер</p>
                      {freeRoomsForRelocate.length > 0 ? (
                        <>
                          <select
                            className="input text-sm"
                            value={relocateRoomId}
                            onChange={e => setRelocateRoomId(e.target.value)}
                          >
                            <option value="">— выберите номер —</option>
                            {freeRoomsForRelocate.map(r => (
                              <option key={r.id} value={r.id}>
                                №{r.number} — {r.type} ({r.baseRate.toLocaleString('ru-RU')} ₽/ночь)
                              </option>
                            ))}
                          </select>
                          <div className="flex gap-2">
                            <button
                              onClick={handleRelocate}
                              disabled={!relocateRoomId}
                              className="flex-1 py-1.5 rounded-lg bg-amber-500 hover:bg-amber-600 disabled:opacity-50 text-white text-xs font-semibold transition-colors"
                            >
                              Переселить
                            </button>
                            <button
                              onClick={() => setRelocating(false)}
                              className="px-3 py-1.5 rounded-lg border border-slate-200 dark:border-slate-600 text-xs text-slate-600 dark:text-slate-400 hover:bg-slate-100 dark:hover:bg-slate-700 transition-colors"
                            >
                              Отмена
                            </button>
                          </div>
                        </>
                      ) : (
                        <div className="text-xs text-slate-500 dark:text-slate-400">
                          Нет свободных номеров на эти даты
                          <button onClick={() => setRelocating(false)} className="ml-2 text-brand-600 dark:text-brand-400 underline">Закрыть</button>
                        </div>
                      )}
                    </div>
                  )}
                </div>
              )}

              {/* Early check-in banner */}
              {canEarlyCheckIn && !earlyOpen && (
                <div className="rounded-xl border border-amber-200 dark:border-amber-700 bg-amber-50 dark:bg-amber-900/20 p-3">
                  <div className="flex items-start justify-between gap-2">
                    <div className="flex items-start gap-2">
                      <LogIn size={15} className="text-amber-600 dark:text-amber-400 mt-0.5 shrink-0" />
                      <div>
                        <p className="text-xs font-semibold text-amber-800 dark:text-amber-300">Гость приехал раньше</p>
                        <p className="text-xs text-amber-700 dark:text-amber-400 mt-0.5">
                          Бронь начинается {fmtDate(booking.checkIn)}, но можно заселить сейчас
                        </p>
                      </div>
                    </div>
                    <button
                      onClick={() => { setEarlyOpen(true); setEarlyRoomId(booking.roomId); setEarlyNewCheckOut(checkOutDate) }}
                      className="shrink-0 text-xs font-semibold text-amber-700 dark:text-amber-300 bg-amber-100 dark:bg-amber-800/40 hover:bg-amber-200 dark:hover:bg-amber-700/50 px-2.5 py-1 rounded-lg transition-colors"
                    >
                      Заселить
                    </button>
                  </div>
                </div>
              )}

              {/* Early check-in form */}
              {canEarlyCheckIn && earlyOpen && (() => {
                const currentRoomFree = !((allBookings ?? []).some(b =>
                  b.id !== booking.id && b.roomId === booking.roomId &&
                  b.status !== 'cancelled' && b.status !== 'no_show' && b.status !== 'checked_out' &&
                  b.checkIn < earlyNewCheckOut && b.checkOut > today,
                ))
                const availableRooms = (rooms ?? []).filter(r =>
                  !((allBookings ?? []).some(b =>
                    b.id !== booking.id && b.roomId === r.id &&
                    b.status !== 'cancelled' && b.status !== 'no_show' && b.status !== 'checked_out' &&
                    b.checkIn < earlyNewCheckOut && b.checkOut > today,
                  )),
                )
                const extraNights = differenceInDays(new Date(booking.checkIn), new Date(today))
                const selectedRoom = (rooms ?? []).find(r => r.id === earlyRoomId)
                const origRoom     = (rooms ?? []).find(r => r.id === booking.roomId)
                const priceDiff    = selectedRoom && origRoom ? selectedRoom.baseRate - origRoom.baseRate : 0

                return (
                  <div className="rounded-xl border border-amber-300 dark:border-amber-600 bg-amber-50 dark:bg-amber-900/20 p-3 space-y-3">
                    <div className="flex items-center gap-2">
                      <LogIn size={14} className="text-amber-600 dark:text-amber-400" />
                      <p className="text-xs font-semibold text-amber-800 dark:text-amber-300">Ранний заезд</p>
                    </div>

                    {/* Room selector */}
                    {currentRoomFree ? (
                      <div className="text-xs text-green-700 dark:text-green-400 bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-700 rounded-lg px-2.5 py-2">
                        Текущий номер свободен — можно заселить без переноса
                      </div>
                    ) : (
                      <div className="space-y-1.5">
                        <p className="text-xs text-amber-700 dark:text-amber-400">
                          Текущий номер занят. Выберите свободный:
                        </p>
                        {availableRooms.length > 0 ? (
                          <select
                            className="input text-sm"
                            value={earlyRoomId}
                            onChange={e => setEarlyRoomId(e.target.value)}
                          >
                            <option value="">— выберите номер —</option>
                            {availableRooms.map(r => {
                              const diff = r.baseRate - (origRoom?.baseRate ?? 0)
                              const diffStr = diff > 0 ? ` (+${diff.toLocaleString('ru-RU')} ₽/н)` : diff < 0 ? ` (${diff.toLocaleString('ru-RU')} ₽/н)` : ''
                              return (
                                <option key={r.id} value={r.id}>
                                  №{r.number} — {r.type}{diffStr}
                                </option>
                              )
                            })}
                          </select>
                        ) : (
                          <p className="text-xs text-red-600 dark:text-red-400">Нет свободных номеров</p>
                        )}
                      </div>
                    )}

                    {/* Checkout date */}
                    <div>
                      <label className={lbl}>Дата выезда</label>
                      <input
                        type="date"
                        className="input text-sm"
                        value={earlyNewCheckOut}
                        min={today}
                        max={booking.checkOut}
                        onChange={e => setEarlyNewCheckOut(e.target.value)}
                      />
                    </div>

                    {/* Extra nights info */}
                    {earlyNewCheckOut > today && (
                      <div className="text-xs text-slate-500 dark:text-slate-400 space-y-0.5">
                        <p>Заезд сегодня → доп. {extraNights} {extraNights === 1 ? 'ночь' : extraNights < 5 ? 'ночи' : 'ночей'}</p>
                        {priceDiff !== 0 && selectedRoom && (
                          <p className={priceDiff > 0 ? 'text-red-600 dark:text-red-400' : 'text-green-600 dark:text-green-400'}>
                            Разница в стоимости: {priceDiff > 0 ? '+' : ''}{priceDiff.toLocaleString('ru-RU')} ₽/ночь
                          </p>
                        )}
                      </div>
                    )}

                    <div className="flex gap-2">
                      <button
                        onClick={() => setEarlyOpen(false)}
                        className="btn-secondary flex-1 justify-center text-xs py-1.5"
                      >
                        Отмена
                      </button>
                      <button
                        onClick={handleEarlyCheckIn}
                        disabled={earlySaving || (!currentRoomFree && !earlyRoomId) || availableRooms.length === 0}
                        className="flex-1 py-1.5 rounded-lg bg-amber-500 hover:bg-amber-600 disabled:opacity-50 disabled:cursor-not-allowed text-white text-xs font-semibold transition-colors flex items-center justify-center gap-1"
                      >
                        {earlySaving ? <Loader2 size={12} className="animate-spin" /> : <LogIn size={12} />}
                        Заселить сейчас
                      </button>
                    </div>
                  </div>
                )
              })()}

              {/* Dates — read or edit mode */}
              <div>
                <div className="flex items-center justify-between mb-2">
                  <p className="text-xs text-slate-500 dark:text-slate-400 font-medium flex items-center gap-1">
                    <Calendar size={12} /> Даты проживания
                  </p>
                  {!editDates && canEditDates && (
                    <button
                      onClick={() => { setEditDates(true); setConflictBooking(null) }}
                      className="flex items-center gap-1 text-xs text-brand-600 dark:text-brand-400 hover:text-brand-700 dark:hover:text-brand-300 font-medium"
                    >
                      <Pencil size={11} /> Изменить
                    </button>
                  )}
                </div>

                {editDates ? (
                  <div className="space-y-3 p-3 rounded-xl border border-brand-200 dark:border-brand-700 bg-brand-50/30 dark:bg-brand-900/10">
                    <div className="grid grid-cols-2 gap-3">
                      <div>
                        <label className={lbl}>Заезд</label>
                        <input type="date" className="input text-sm" value={newCheckIn}
                          onChange={e => { setNewCheckIn(e.target.value); setConflictBooking(null) }} />
                      </div>
                      <div>
                        <label className={lbl}>Выезд</label>
                        <input type="date" className="input text-sm" value={newCheckOut} min={newCheckIn}
                          onChange={e => { setNewCheckOut(e.target.value); setConflictBooking(null) }} />
                      </div>
                    </div>

                    {rooms && rooms.length > 1 && (
                      <div>
                        <label className={lbl}>Номер</label>
                        <select className="input text-sm" value={newRoomId}
                          onChange={e => { setNewRoomId(e.target.value); setConflictBooking(null) }}>
                          {rooms.map(r => (
                            <option key={r.id} value={r.id}>№{r.number} — {r.type}</option>
                          ))}
                        </select>
                      </div>
                    )}

                    {/* Conflict warning */}
                    {conflictBooking && (
                      <div className="rounded-xl border border-red-200 dark:border-red-700 bg-red-50 dark:bg-red-900/20 p-3 space-y-2">
                        <div className="flex items-start gap-2 text-red-700 dark:text-red-400 text-xs font-medium">
                          <AlertTriangle size={13} className="shrink-0 mt-0.5" />
                          <span>
                            Номер занят: {conflictBooking.guestName},&nbsp;
                            {fmtDate(conflictBooking.checkIn)} – {fmtDate(conflictBooking.checkOut)}
                          </span>
                        </div>
                        {conflictBooking.status !== 'checked_in' && onBulkUpdate && rooms && (
                          <div className="space-y-1.5">
                            <p className="text-xs text-red-600 dark:text-red-400">
                              Переместить {conflictBooking.guestName} в другой номер:
                            </p>
                            <select className="input text-sm" value={conflictResolveRoomId}
                              onChange={e => setConflictResolveRoomId(e.target.value)}>
                              <option value="">— выберите номер —</option>
                              {rooms.filter(r => r.id !== newRoomId).map(r => (
                                <option key={r.id} value={r.id}>№{r.number} — {r.type}</option>
                              ))}
                            </select>
                            <button
                              disabled={!conflictResolveRoomId}
                              onClick={handleResolveWithRoomSwap}
                              className="w-full btn-primary text-xs py-1.5 justify-center disabled:opacity-50 disabled:cursor-not-allowed"
                            >
                              Переместить и сохранить
                            </button>
                          </div>
                        )}
                        <button onClick={handleForceUpdate}
                          className="w-full btn-secondary text-xs py-1.5 justify-center text-red-600 dark:text-red-400 border-red-200 dark:border-red-700">
                          Сохранить принудительно
                        </button>
                      </div>
                    )}

                    <div className="flex gap-2">
                      <button
                        onClick={() => { setEditDates(false); setConflictBooking(null) }}
                        className="btn-secondary flex-1 justify-center text-sm py-1.5"
                      >
                        Отмена
                      </button>
                      {!conflictBooking && (
                        <button onClick={handleSaveDates}
                          className="btn-primary flex-1 justify-center text-sm py-1.5">
                          Сохранить
                        </button>
                      )}
                    </div>
                  </div>
                ) : (
                  <div className="grid grid-cols-2 gap-3">
                    <div>
                      <p className="text-xs text-slate-500 dark:text-slate-400 font-medium mb-1">Заезд</p>
                      <p className="text-sm font-semibold text-slate-900 dark:text-slate-100">
                        {fmtDate(booking.checkIn)}
                      </p>
                    </div>
                    <div>
                      <p className="text-xs text-slate-500 dark:text-slate-400 font-medium mb-1">Выезд</p>
                      <p className="text-sm font-semibold text-slate-900 dark:text-slate-100">
                        {fmtDate(booking.checkOut)}
                      </p>
                    </div>
                  </div>
                )}
                {!editDates && (
                  <p className="text-xs text-slate-500 dark:text-slate-400 mt-1">
                    {nights} {nights === 1 ? 'ночь' : nights < 5 ? 'ночи' : 'ночей'}
                  </p>
                )}
              </div>

              <div>
                <p className="text-xs text-slate-500 dark:text-slate-400 font-medium flex items-center gap-1 mb-1">
                  <Users size={12} /> Гости
                </p>
                <p className="text-sm text-slate-900 dark:text-slate-100">
                  {booking.adults} взр.{booking.children > 0 ? ` · ${booking.children} дет.` : ''}
                </p>
              </div>

              {booking.guestEmail && (
                <div className="space-y-1.5">
                  <p className="text-xs text-slate-500 dark:text-slate-400 font-medium">Контакты</p>
                  <div className="flex items-center gap-2 text-sm text-slate-700 dark:text-slate-300">
                    <Mail size={13} className="text-slate-400" />
                    {booking.guestEmail}
                  </div>
                </div>
              )}

              {booking.notes && (
                <div>
                  <p className="text-xs text-slate-500 dark:text-slate-400 font-medium flex items-center gap-1 mb-1">
                    <Tag size={12} /> Примечания
                  </p>
                  <p className="text-sm text-slate-700 dark:text-slate-300 bg-slate-50 dark:bg-slate-700/40 rounded-lg p-2.5">
                    {booking.notes}
                  </p>
                </div>
              )}

              {booking.channelBookingId && (
                <div>
                  <p className="text-xs text-slate-500 mb-0.5">ID канала</p>
                  <code className="text-xs text-brand-600 dark:text-brand-400 bg-brand-50 dark:bg-brand-900/20 px-2 py-1 rounded">
                    {booking.channelBookingId}
                  </code>
                </div>
              )}
            </div>
          )}

          {/* ── Гости ────────────────────────────────────────────────────────── */}
          {tab === 'guest' && slug && (
            <div className="space-y-3">
              {/* Require-docs warning */}
              {requireDocs && adultsWithoutDocs.length > 0 && (
                <div className="flex items-start gap-2 rounded-lg bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-700 p-2.5 text-xs text-amber-700 dark:text-amber-400">
                  <AlertTriangle size={13} className="shrink-0 mt-0.5" />
                  <span>У {adultsWithoutDocs.length} взрослого(-ых) не заполнены паспортные данные</span>
                </div>
              )}

              {/* Loading */}
              {bgLoading && (
                <div className="flex items-center justify-center py-6">
                  <Loader2 size={20} className="animate-spin text-slate-400" />
                </div>
              )}

              {/* Guest list */}
              {!bgLoading && bgGuests.map(bg => (
                <div key={bg.id} className="rounded-xl border border-slate-200 dark:border-slate-600 p-3">
                  <div className="flex items-start justify-between gap-2">
                    <div className="flex-1 min-w-0">
                      <div className="flex items-center gap-1.5 flex-wrap">
                        <span className="text-sm font-medium text-slate-900 dark:text-slate-100">
                          {bg.lastName} {bg.firstName}{bg.middleName ? ` ${bg.middleName}` : ''}
                        </span>
                        {bg.isMain && (
                          <span className="flex items-center gap-0.5 px-1.5 py-0.5 rounded-md text-xs bg-brand-100 text-brand-700 dark:bg-brand-900/30 dark:text-brand-400">
                            <UserCheck size={10} /> Главный
                          </span>
                        )}
                        {bg.isChild && (
                          <span className="flex items-center gap-0.5 px-1.5 py-0.5 rounded-md text-xs bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400">
                            <Baby size={10} /> Ребёнок
                          </span>
                        )}
                      </div>
                      {bg.passportSeries && bg.passportNumber ? (
                        <p className="text-xs text-slate-400 font-mono mt-0.5">
                          {bg.passportSeries} {bg.passportNumber}
                        </p>
                      ) : !bg.isChild && requireDocs ? (
                        <p className="text-xs text-amber-500 mt-0.5">Паспорт не заполнен</p>
                      ) : null}
                      {bg.birthDate && (
                        <p className="text-xs text-slate-400 mt-0.5">
                          {new Date(bg.birthDate).toLocaleDateString('ru-RU')}
                        </p>
                      )}
                    </div>
                    <div className="flex gap-1 shrink-0">
                      <button
                        onClick={() => openEditForm(bg)}
                        className="p-1.5 rounded-lg text-slate-400 hover:text-brand-600 hover:bg-brand-50 dark:hover:bg-brand-900/20 transition-colors"
                      >
                        <Pencil size={13} />
                      </button>
                      <button
                        onClick={() => removeGuest(bg.id)}
                        className="p-1.5 rounded-lg text-slate-400 hover:text-red-500 hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors"
                      >
                        <Trash2 size={13} />
                      </button>
                    </div>
                  </div>
                </div>
              ))}

              {/* Empty state */}
              {!bgLoading && bgGuests.length === 0 && !showGuestForm && (
                <p className="text-xs text-center text-slate-400 py-4">Гости не добавлены</p>
              )}

              {/* Add guest form */}
              {showGuestForm && (
                <div className="rounded-xl border border-brand-200 dark:border-brand-700 bg-brand-50/30 dark:bg-brand-900/10 p-3 space-y-3">
                  <p className="text-xs font-semibold text-brand-700 dark:text-brand-400">
                    {editingBg ? 'Редактировать гостя' : 'Добавить гостя'}
                  </p>

                  {/* ФИО with autocomplete */}
                  <div ref={acWrapRef} className="relative">
                    <label className={lbl}>ФИО *</label>
                    <div className="relative">
                      <input
                        className={fld}
                        value={acQuery}
                        onChange={e => handleAcInput(e.target.value)}
                        placeholder="Иванов Иван Иванович"
                        autoComplete="off"
                      />
                      {acLoading && (
                        <Loader2 size={12} className="absolute right-2.5 top-1/2 -translate-y-1/2 animate-spin text-slate-400" />
                      )}
                    </div>
                    {acResults.length > 0 && (
                      <div className="absolute z-20 left-0 right-0 mt-1 bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-600 rounded-xl shadow-lg overflow-hidden max-h-48 overflow-y-auto">
                        {acResults.map(g => (
                          <button
                            key={g.id}
                            type="button"
                            onClick={() => selectAcGuest(g)}
                            className="w-full text-left px-3 py-2 hover:bg-brand-50 dark:hover:bg-brand-900/20 transition-colors"
                          >
                            <div className="flex items-center gap-2">
                              <Search size={11} className="text-slate-400 shrink-0" />
                              <div>
                                <p className="text-sm font-medium text-slate-900 dark:text-slate-100">
                                  {[g.lastName, g.firstName, g.middleName].filter(Boolean).join(' ')}
                                </p>
                                {(g.passportSeries || g.passportNumber) && (
                                  <p className="text-xs text-slate-400 font-mono">
                                    {[g.passportSeries, g.passportNumber].filter(Boolean).join(' ')}
                                  </p>
                                )}
                              </div>
                            </div>
                          </button>
                        ))}
                      </div>
                    )}
                  </div>

                  {/* Birth date + flags */}
                  <div className="grid grid-cols-2 gap-2">
                    <div>
                      <label className={lbl}>Дата рождения</label>
                      <input type="date" className={fld} value={bgForm.birth_date ?? ''} onChange={e => setBgForm(f => ({ ...f, birth_date: e.target.value }))} />
                    </div>
                    <div className="flex flex-col gap-2 pt-4">
                      <label className="flex items-center gap-2 cursor-pointer">
                        <input type="checkbox" checked={bgForm.is_child ?? false} onChange={e => setBgForm(f => ({ ...f, is_child: e.target.checked }))} className="rounded" />
                        <span className="text-xs text-slate-600 dark:text-slate-400">Ребёнок (до 16 лет)</span>
                      </label>
                      <label className="flex items-center gap-2 cursor-pointer">
                        <input type="checkbox" checked={bgForm.is_main ?? false} onChange={e => setBgForm(f => ({ ...f, is_main: e.target.checked }))} className="rounded" />
                        <span className="text-xs text-slate-600 dark:text-slate-400">Главный гость</span>
                      </label>
                    </div>
                  </div>

                  {/* Passport (adults only) */}
                  {!bgForm.is_child && (
                    <div className="space-y-2 pt-2 border-t border-brand-100 dark:border-brand-800">
                      <p className="text-xs font-semibold text-slate-500 dark:text-slate-400">Паспорт</p>
                      <div className="grid grid-cols-2 gap-2">
                        <div>
                          <label className={lbl}>Серия</label>
                          <input className={`${fld} font-mono uppercase`} value={bgForm.passport_series ?? ''} onChange={e => handlePassportInput('passport_series', e.target.value.toUpperCase())} placeholder="4510" maxLength={10} />
                        </div>
                        <div>
                          <label className={lbl}>Номер</label>
                          <input className={`${fld} font-mono`} value={bgForm.passport_number ?? ''} onChange={e => handlePassportInput('passport_number', e.target.value)} placeholder="123456" maxLength={10} />
                        </div>
                      </div>
                      <div>
                        <label className={lbl}>Кем выдан</label>
                        <input className={fld} value={bgForm.passport_issued_by ?? ''} onChange={e => setBgForm(f => ({ ...f, passport_issued_by: e.target.value }))} placeholder="УФМС России по г. Москве" />
                      </div>
                      <div>
                        <label className={lbl}>Дата выдачи</label>
                        <input type="date" className={fld} value={bgForm.passport_issue_date ?? ''} onChange={e => setBgForm(f => ({ ...f, passport_issue_date: e.target.value }))} />
                      </div>
                    </div>
                  )}

                  {/* Scan + save/cancel */}
                  <button
                    onClick={() => showToast('Для сканирования подключите RFID/OCR сканер')}
                    className="w-full flex items-center justify-center gap-2 py-2 rounded-xl border border-dashed border-brand-300 dark:border-brand-700 text-brand-600 dark:text-brand-400 text-xs font-medium hover:bg-brand-50 dark:hover:bg-brand-900/20 transition-colors"
                  >
                    <ScanLine size={13} /> Сканировать паспорт
                  </button>

                  <div className="flex gap-2">
                    <button onClick={cancelGuestForm} className="btn-secondary flex-1 justify-center text-sm py-1.5">Отмена</button>
                    <button onClick={saveGuest} disabled={bgSaving} className="btn-primary flex-1 justify-center text-sm py-1.5">
                      {bgSaving ? <Loader2 size={13} className="animate-spin" /> : null}
                      {editingBg ? 'Сохранить' : 'Добавить'}
                    </button>
                  </div>
                </div>
              )}

              {/* Add button */}
              {!showGuestForm && (
                <button
                  onClick={openAddForm}
                  className="w-full flex items-center justify-center gap-2 py-2.5 rounded-xl border-2 border-dashed border-slate-200 dark:border-slate-600 text-slate-500 dark:text-slate-400 text-sm font-medium hover:border-brand-300 dark:hover:border-brand-700 hover:text-brand-600 dark:hover:text-brand-400 hover:bg-brand-50 dark:hover:bg-brand-900/20 transition-colors"
                >
                  <Plus size={15} /> Добавить гостя
                </button>
              )}
            </div>
          )}

          {/* Fallback Гость tab (no slug — old static form) */}
          {tab === 'guest' && !slug && (
            <div className="space-y-3">
              <div className="grid grid-cols-1 gap-3">
                <div>
                  <label className={lbl}>Фамилия</label>
                  <input className={fld} value={passport.lastName}   onChange={e => setP('lastName',   e.target.value)} placeholder="Иванов" />
                </div>
                <div className="grid grid-cols-2 gap-3">
                  <div>
                    <label className={lbl}>Имя</label>
                    <input className={fld} value={passport.firstName}  onChange={e => setP('firstName',  e.target.value)} placeholder="Иван" />
                  </div>
                  <div>
                    <label className={lbl}>Отчество</label>
                    <input className={fld} value={passport.middleName} onChange={e => setP('middleName', e.target.value)} placeholder="Иванович" />
                  </div>
                </div>
                <div>
                  <label className={lbl}>Дата рождения</label>
                  <input type="date" className={fld} value={passport.dob} onChange={e => setP('dob', e.target.value)} />
                </div>
              </div>
              <div className="pt-2 border-t border-slate-100 dark:border-slate-700">
                <p className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-3">Паспорт</p>
                <div className="space-y-3">
                  <div className="grid grid-cols-2 gap-3">
                    <div>
                      <label className={lbl}>Серия</label>
                      <input className={fld} value={passport.series} onChange={e => setP('series', e.target.value)} placeholder="4510" maxLength={4} />
                    </div>
                    <div>
                      <label className={lbl}>Номер</label>
                      <input className={fld} value={passport.number} onChange={e => setP('number', e.target.value)} placeholder="123456" maxLength={6} />
                    </div>
                  </div>
                  <div>
                    <label className={lbl}>Кем выдан</label>
                    <input className={fld} value={passport.issuedBy}   onChange={e => setP('issuedBy',   e.target.value)} placeholder="УФМС России по г. Москве" />
                  </div>
                  <div>
                    <label className={lbl}>Дата выдачи</label>
                    <input type="date" className={fld} value={passport.issueDate} onChange={e => setP('issueDate', e.target.value)} />
                  </div>
                  <div>
                    <label className={lbl}>Адрес регистрации</label>
                    <input className={fld} value={passport.regAddress} onChange={e => setP('regAddress', e.target.value)} placeholder="г. Москва, ул. Примерная, д. 1" />
                  </div>
                </div>
              </div>
              <button
                onClick={() => showToast('Для сканирования подключите RFID/OCR сканер')}
                className="w-full flex items-center justify-center gap-2 py-2.5 rounded-xl border-2 border-dashed border-brand-300 dark:border-brand-700 text-brand-600 dark:text-brand-400 text-sm font-medium hover:bg-brand-50 dark:hover:bg-brand-900/20 transition-colors"
              >
                <ScanLine size={16} /> Сканировать паспорт
              </button>
              <button
                onClick={() => showToast('✓ Данные гостя сохранены')}
                className="w-full btn-primary justify-center"
              >
                Сохранить данные
              </button>
            </div>
          )}

          {/* ── Оплата ───────────────────────────────────────────────────────── */}
          {tab === 'payment' && (
            <div className="space-y-4">
              {/* Discount selector */}
              <div>
                <label className={lbl}>Скидка</label>
                <select className="input text-sm" value={discountId} onChange={e => setDiscountId(e.target.value)}>
                  <option value="">— Без скидки —</option>
                  {activeDiscs.map(d => (
                    <option key={d.id} value={d.id}>
                      {d.name} ({d.valueType === 'percent' ? `${d.value}%` : formatCurrency(d.value)})
                    </option>
                  ))}
                </select>
              </div>

              {/* Breakdown */}
              <div className="rounded-xl border border-slate-200 dark:border-slate-600 divide-y divide-slate-200 dark:divide-slate-600 text-sm">
                <div className="flex justify-between px-3 py-2">
                  <span className="text-slate-500 dark:text-slate-400">Стоимость</span>
                  <span className="font-medium text-slate-900 dark:text-slate-100">{formatCurrency(baseTotal)}</span>
                </div>
                {discountAmt > 0 && (
                  <div className="flex justify-between px-3 py-2">
                    <span className="text-slate-500 dark:text-slate-400">Скидка «{selDiscount?.name}»</span>
                    <span className="font-medium text-emerald-600 dark:text-emerald-400">−{formatCurrency(discountAmt)}</span>
                  </div>
                )}
                <div className="flex justify-between px-3 py-2 font-semibold">
                  <span className="text-slate-700 dark:text-slate-300">Итого</span>
                  <span className="text-slate-900 dark:text-slate-100">{formatCurrency(finalTotal)}</span>
                </div>
                <div className="flex justify-between px-3 py-2">
                  <span className="text-slate-500 dark:text-slate-400">Оплачено</span>
                  <span className="font-medium text-emerald-600 dark:text-emerald-400">{formatCurrency(totalPaid)}</span>
                </div>
                <div className={cn(
                  'flex justify-between px-3 py-2 font-bold',
                  balance > 0 ? 'text-red-600 dark:text-red-400' : 'text-emerald-600 dark:text-emerald-400',
                )}>
                  <span>{balance > 0 ? 'Остаток' : 'Переплата'}</span>
                  <span>{balance > 0 ? formatCurrency(balance) : `+${formatCurrency(-balance)}`}</span>
                </div>
              </div>

              {/* Accept payment */}
              {!showPayForm ? (
                <button
                  onClick={() => { setPayAmount(balance > 0 ? String(balance) : ''); setShowPayForm(true) }}
                  className="w-full btn-primary justify-center"
                  disabled={balance <= 0}
                >
                  <Plus size={15} /> Принять оплату
                </button>
              ) : (
                <div className="rounded-xl border border-brand-200 dark:border-brand-700 p-3 space-y-3 bg-brand-50/40 dark:bg-brand-900/10">
                  <p className="text-xs font-semibold text-brand-700 dark:text-brand-400">Новый платёж</p>
                  <div>
                    <label className={lbl}>Сумма, ₽</label>
                    <input type="number" className="input text-sm" value={payAmount}
                      onChange={e => setPayAmount(e.target.value)} placeholder="0" min="0" />
                  </div>
                  <div>
                    <label className={lbl}>Способ оплаты</label>
                    <div className="grid grid-cols-3 gap-1.5">
                      {METHODS.map(m => (
                        <button
                          key={m.id} type="button" onClick={() => setPayMethod(m.id)}
                          className={cn(
                            'flex flex-col items-center gap-1 py-2 rounded-lg border text-xs font-medium transition-colors',
                            payMethod === m.id
                              ? 'bg-brand-600 border-brand-600 text-white'
                              : 'bg-white dark:bg-slate-700 border-slate-200 dark:border-slate-600 text-slate-600 dark:text-slate-300',
                          )}
                        >
                          <m.icon size={14} /> {m.label}
                        </button>
                      ))}
                    </div>
                  </div>
                  <div>
                    <label className={lbl}>Комментарий</label>
                    <input className="input text-sm" value={payNote}
                      onChange={e => setPayNote(e.target.value)} placeholder="Необязательно" />
                  </div>
                  <div className="flex gap-2">
                    <button onClick={() => setShowPayForm(false)} className="btn-secondary flex-1 justify-center text-sm py-2">Отмена</button>
                    <button onClick={addPayment} disabled={!payAmount || parseFloat(payAmount) <= 0}
                      className="btn-primary flex-1 justify-center text-sm py-2">Принять</button>
                  </div>
                </div>
              )}

              {/* Payment history */}
              {payments.length > 0 && (
                <div>
                  <p className={lbl + ' mt-1'}>История платежей</p>
                  <div className="space-y-1.5">
                    {payments.map(p => {
                      const M = METHODS.find(m => m.id === p.method)!
                      return (
                        <div key={p.id} className="flex items-center gap-2 text-sm px-2.5 py-2 rounded-lg bg-slate-50 dark:bg-slate-700/40">
                          <M.icon size={13} className="text-slate-400 shrink-0" />
                          <span className="text-slate-400 text-xs shrink-0">{p.date}</span>
                          <span className="flex-1 text-slate-600 dark:text-slate-300 text-xs truncate">{p.note || M.label}</span>
                          <span className="font-semibold text-emerald-600 dark:text-emerald-400 shrink-0">{formatCurrency(p.amount)}</span>
                        </div>
                      )
                    })}
                  </div>
                </div>
              )}
            </div>
          )}

          {/* ── Документы ────────────────────────────────────────────────────── */}
          {tab === 'docs' && (
            <div className="space-y-2">
              <p className="text-xs text-slate-500 dark:text-slate-400 mb-3">
                Распечатайте документы для гостя
              </p>
              {DOCUMENTS
                .filter(d => d.always || booking.status === 'checked_in' || booking.status === 'checked_out')
                .map(doc => (
                  <div key={doc.id} className="flex items-center gap-3 p-3 rounded-xl border border-slate-200 dark:border-slate-600 hover:border-brand-300 dark:hover:border-brand-600 transition-colors">
                    <div className="w-9 h-9 rounded-lg bg-slate-100 dark:bg-slate-700 flex items-center justify-center shrink-0">
                      <doc.icon size={17} className="text-slate-500 dark:text-slate-400" />
                    </div>
                    <div className="flex-1 min-w-0">
                      <p className="text-sm font-medium text-slate-900 dark:text-slate-100">{doc.label}</p>
                      <p className="text-xs text-slate-500 dark:text-slate-400">{doc.desc}</p>
                    </div>
                    <button
                      onClick={() => printDoc(doc.label)}
                      className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-brand-600 text-white text-xs font-medium hover:bg-brand-700 transition-colors shrink-0"
                    >
                      <Printer size={12} /> Печать
                    </button>
                  </div>
                ))
              }
              <div className="pt-3 mt-1 border-t border-slate-100 dark:border-slate-700">
                <button
                  onClick={() => showToast('🖨 Комплект документов отправлен на печать')}
                  className="w-full btn-primary justify-center"
                >
                  <Printer size={15} /> Напечатать комплект
                </button>
                <p className="text-xs text-center text-slate-400 dark:text-slate-500 mt-1.5">
                  Состав комплекта настраивается в разделе «Документы»
                </p>
              </div>
            </div>
          )}
        </div>

        {/* Footer */}
        <div className="shrink-0 px-5 py-4 border-t border-slate-200 dark:border-slate-700 space-y-2">
          {balance > 0 && booking.status === 'confirmed' && (
            <div className="flex items-center gap-2 p-2.5 rounded-xl bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-700">
              <AlertTriangle size={14} className="text-amber-500 shrink-0" />
              <p className="text-xs text-amber-700 dark:text-amber-400">
                Долг {formatCurrency(balance)} — получите оплату перед заселением
              </p>
            </div>
          )}

          {booking.status === 'confirmed' && checkInDate <= today && (() => {
            const nowTime = format(new Date(), 'HH:mm')
            const isEarlyArrival = earlyCheckinEnabled && nowTime < hotelCheckInTime && (room?.earlyCheckinFee ?? 0) > 0
            return (
              <>
                {isEarlyArrival && (
                  <div className="flex items-center gap-2 p-2.5 rounded-xl bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-700">
                    <AlertTriangle size={14} className="text-blue-500 shrink-0" />
                    <p className="text-xs text-blue-700 dark:text-blue-400">
                      Ранний заезд (до {hotelCheckInTime}) — доп. оплата {formatCurrency(room!.earlyCheckinFee!)}
                    </p>
                  </div>
                )}
                <button
                  onClick={() => {
                    if (isEarlyArrival) {
                      setPayments(prev => [...prev, {
                        id: `early-${Date.now()}`,
                        date: new Date().toLocaleDateString('ru-RU'),
                        amount: room!.earlyCheckinFee!,
                        method: 'cash' as const,
                        note: `Ранний заезд (заезд до ${hotelCheckInTime})`,
                      }])
                    }
                    setStatus('checked_in')
                  }}
                  className="w-full btn-primary justify-center"
                >
                  <CheckCircle size={15} /> {isEarlyArrival ? `Заселить (+ ${formatCurrency(room!.earlyCheckinFee!)})` : 'Заселить'}
                </button>
                {slug && (
                  <button
                    onClick={handleIssueCard}
                    disabled={cardIssuing}
                    className="w-full btn-secondary justify-center flex items-center gap-2"
                    title="Записать карту-ключ для гостя"
                  >
                    {cardIssuing ? <Loader2 size={15} className="animate-spin" /> : <KeyRound size={15} />}
                    Выдать ключ (TTLock)
                  </button>
                )}
              </>
            )
          })()}
          {booking.status === 'checked_in' && !earlyOutOpen && (() => {
            const nowTime = format(new Date(), 'HH:mm')
            const isLateCheckout = lateCheckoutEnabled && nowTime > hotelCheckOutTime && (room?.lateCheckoutFee ?? 0) > 0
            return (
              <>
                {isLateCheckout && (
                  <div className="flex items-center gap-2 p-2.5 rounded-xl bg-orange-50 dark:bg-orange-900/20 border border-orange-200 dark:border-orange-700">
                    <AlertTriangle size={14} className="text-orange-500 shrink-0" />
                    <p className="text-xs text-orange-700 dark:text-orange-400">
                      Поздний выезд (после {hotelCheckOutTime}) — доп. оплата {formatCurrency(room!.lateCheckoutFee!)}
                    </p>
                  </div>
                )}
                <button
                  onClick={() => {
                    if (isLateCheckout) {
                      setPayments(prev => [...prev, {
                        id: `late-${Date.now()}`,
                        date: new Date().toLocaleDateString('ru-RU'),
                        amount: room!.lateCheckoutFee!,
                        method: 'cash' as const,
                        note: `Поздний выезд (выезд после ${hotelCheckOutTime})`,
                      }])
                    }
                    setEarlyOutOpen(true)
                    setEarlyOutDate(checkOutDate)
                  }}
                  className="w-full btn-primary justify-center bg-emerald-600 hover:bg-emerald-700"
                >
                  <CheckCircle size={15} /> {isLateCheckout ? `Выселить (+ ${formatCurrency(room!.lateCheckoutFee!)})` : 'Выселить'}
                </button>
                {slug && (
                  <button
                    onClick={handleIssueCard}
                    disabled={cardIssuing}
                    className="w-full btn-secondary justify-center flex items-center gap-2"
                    title="Выдать дубликат карты-ключа"
                  >
                    {cardIssuing ? <Loader2 size={15} className="animate-spin" /> : <KeyRound size={15} />}
                    Выдать ключ (TTLock)
                  </button>
                )}
              </>
            )
          })()}
          {booking.status === 'checked_in' && earlyOutOpen && (() => {
            const origNights   = differenceInDays(new Date(booking.checkOut), new Date(booking.checkIn))
            const actualNights = Math.max(1, differenceInDays(new Date(earlyOutDate), new Date(booking.checkIn)))
            const refundNights = origNights - actualNights
            const refundAmt    = refundNights > 0 ? Math.round(refundNights * booking.totalAmount / origNights) : 0
            return (
              <div className="rounded-xl border border-emerald-200 dark:border-emerald-700 bg-emerald-50 dark:bg-emerald-900/20 p-3 space-y-3">
                <p className="text-xs font-semibold text-emerald-800 dark:text-emerald-300 flex items-center gap-1.5">
                  <CheckCircle size={13} /> Выселение гостя
                </p>
                <div>
                  <label className={lbl}>Дата выезда</label>
                  <input
                    type="date"
                    className="input text-sm"
                    value={earlyOutDate}
                    min={booking.checkIn}
                    max={booking.checkOut}
                    onChange={e => setEarlyOutDate(e.target.value)}
                  />
                </div>
                {refundNights > 0 && (
                  <div className="rounded-lg bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-700 p-2.5 space-y-2">
                    <p className="text-xs font-medium text-amber-800 dark:text-amber-300">
                      Возврат за {refundNights} {refundNights === 1 ? 'ночь' : refundNights < 5 ? 'ночи' : 'ночей'}: {formatCurrency(refundAmt)}
                    </p>
                    <div className="flex gap-1.5">
                      {METHODS.map(m => (
                        <button
                          key={m.id}
                          onClick={() => setEarlyOutMethod(m.id)}
                          className={cn(
                            'flex-1 py-1 rounded-lg text-xs font-medium border transition-colors',
                            earlyOutMethod === m.id
                              ? 'bg-amber-500 border-amber-500 text-white'
                              : 'border-amber-200 dark:border-amber-700 text-amber-700 dark:text-amber-400 hover:bg-amber-100 dark:hover:bg-amber-800/30',
                          )}
                        >
                          {m.label}
                        </button>
                      ))}
                    </div>
                    <p className="text-[11px] text-amber-600 dark:text-amber-400">
                      Выдайте гостю {formatCurrency(refundAmt)} {earlyOutMethod === 'cash' ? 'наличными' : earlyOutMethod === 'card' ? 'на карту' : 'переводом'}
                    </p>
                  </div>
                )}
                {refundNights <= 0 && (
                  <p className="text-xs text-slate-500 dark:text-slate-400">Возврат не требуется</p>
                )}
                <div className="flex gap-2">
                  <button
                    onClick={() => setEarlyOutOpen(false)}
                    className="btn-secondary flex-1 justify-center text-xs py-1.5"
                  >
                    Отмена
                  </button>
                  <button
                    onClick={handleEarlyCheckOut}
                    disabled={earlyOutSaving}
                    className="flex-1 py-1.5 rounded-lg bg-emerald-600 hover:bg-emerald-700 disabled:opacity-50 text-white text-xs font-semibold transition-colors flex items-center justify-center gap-1"
                  >
                    {earlyOutSaving ? <Loader2 size={12} className="animate-spin" /> : <CheckCircle size={12} />}
                    Подтвердить выезд
                  </button>
                </div>
              </div>
            )
          })()}
          {(booking.status === 'confirmed' || booking.status === 'inquiry') && (
            <button
              onClick={() => setStatus('cancelled')}
              className="w-full btn-secondary justify-center text-red-600 dark:text-red-400 border-red-200 dark:border-red-800 hover:bg-red-50 dark:hover:bg-red-900/20"
            >
              <XCircle size={15} /> Отменить
            </button>
          )}

          <p className="text-xs text-center text-slate-400 dark:text-slate-500">
            ID: {booking.id} · Создано: {booking.createdAt}
          </p>
        </div>
      </div>
    </>
  )
}
