import { useState, useEffect } from 'react'
import {
  Code2, CreditCard, Globe, CalendarCheck2, Copy, CheckCheck, Save,
  ChevronLeft, ChevronRight, Star, Users, Dumbbell, Waves,
  Eye, Settings2, ArrowRight, Plus, Trash2, Check, X as XIcon,
  BedDouble, Baby, ToggleLeft, ToggleRight, ChevronDown, ChevronUp,
  Maximize2, Wifi, Tv2, Wind, Coffee, Bath, Mountain, Shirt, Shield,
  Scan, Image, Zap, AlertCircle, Loader2,
} from 'lucide-react'
import { cn } from '../lib/utils'
import { useModules } from '../contexts/ModulesContext'
import { useAuth } from '../contexts/AuthContext'
import { api, type WidgetRoom, type WidgetCategory, type WidgetRentalObject, type PaymentGateway } from '../lib/api'

// ── Widget settings type ───────────────────────────────────────────────────────

export interface FormField {
  id: string
  label: string
  type: 'text' | 'email' | 'phone' | 'textarea' | 'select'
  required: boolean
  enabled: boolean
  isCustom?: boolean
}

export interface AdditionalService {
  id: string
  name: string
  icon: string
  price: number
  unit: string
  enabled: boolean
}

export interface WidgetSettings {
  hotelName: string
  primaryColor: string
  language: 'ru' | 'en'
  showRooms: boolean
  showRental: boolean
  roomDisplayMode: 'rooms' | 'categories'
  minNights: number
  paymentTimeout: number  // minutes to wait for payment before auto-cancel
  paymentProvider: 'yukassa' | 'tinkoff' | 'cloudpayments' | 'none'
  showPromo: boolean
  allowExtraBeds: boolean
  allowChildren: boolean
  formFields: FormField[]
  additionalServices: AdditionalService[]
}

const COLORS = [
  { label: 'Индиго',    value: '#4F46E5' },
  { label: 'Изумруд',   value: '#059669' },
  { label: 'Синий',     value: '#2563EB' },
  { label: 'Фиолетовый',value: '#7C3AED' },
  { label: 'Красный',   value: '#DC2626' },
  { label: 'Янтарный',  value: '#D97706' },
  { label: 'Розовый',   value: '#DB2777' },
  { label: 'Серый',     value: '#475569' },
]

const PAYMENT_PROVIDERS = [
  { value: 'yukassa',      label: 'ЮKassa' },
  { value: 'tinkoff',      label: 'Тинькофф Pay' },
  { value: 'cloudpayments',label: 'CloudPayments' },
  { value: 'none',         label: 'Без оплаты' },
]

interface MockRoom {
  id: string
  name: string
  beds: number
  guests: number
  price: number
  area: number         // m²
  description: string
  photos: { bg: string; emoji: string; label: string }[]
  photoUrls: string[]  // real photo URLs (empty for mock rooms)
  amenities: string[]
  has3dTour: boolean
}

const MOCK_ROOMS: MockRoom[] = [
  {
    id: 'r1', name: 'Стандарт', beds: 1, guests: 2, price: 4500, area: 22,
    description: 'Уютный номер с двуспальной кроватью, современным ремонтом и всем необходимым для комфортного проживания. Вид во двор.',
    photos: [
      { bg: 'from-slate-200 to-slate-300',   emoji: '🛏️', label: 'Спальня' },
      { bg: 'from-sky-100 to-sky-200',       emoji: '🚿', label: 'Ванная' },
      { bg: 'from-amber-100 to-amber-200',   emoji: '🪟', label: 'Окно' },
    ],
    amenities: ['Wi-Fi', 'TV', 'Кондиционер', 'Фен', 'Мини-холодильник', 'Сейф'],
    photoUrls: [], has3dTour: false,
  },
  {
    id: 'r2', name: 'Комфорт', beds: 1, guests: 2, price: 6500, area: 30,
    description: 'Просторный номер с зоной отдыха, большой кроватью и улучшенной ванной комнатой. Вид на парк.',
    photos: [
      { bg: 'from-emerald-100 to-emerald-200', emoji: '🛏️', label: 'Спальня' },
      { bg: 'from-teal-100 to-teal-200',       emoji: '🛁', label: 'Ванная' },
      { bg: 'from-green-100 to-green-200',     emoji: '🌳', label: 'Вид из окна' },
      { bg: 'from-lime-100 to-lime-200',       emoji: '🛋️', label: 'Зона отдыха' },
    ],
    amenities: ['Wi-Fi', 'TV', 'Кондиционер', 'Мини-бар', 'Халат', 'Фен', 'Сейф', 'Кофемашина'],
    photoUrls: [], has3dTour: false,
  },
  {
    id: 'r3', name: 'Делюкс', beds: 2, guests: 3, price: 8900, area: 45,
    description: 'Роскошный двухкомнатный номер с панорамными окнами. Отдельная гостиная, большая ванная с джакузи. Вид на город.',
    photos: [
      { bg: 'from-violet-100 to-violet-200',  emoji: '🛏️', label: 'Спальня' },
      { bg: 'from-purple-100 to-purple-200',  emoji: '🛁', label: 'Джакузи' },
      { bg: 'from-indigo-100 to-indigo-200',  emoji: '🌆', label: 'Вид на город' },
      { bg: 'from-blue-100 to-blue-200',      emoji: '🛋️', label: 'Гостиная' },
      { bg: 'from-cyan-100 to-cyan-200',      emoji: '🍽️', label: 'Мини-кухня' },
    ],
    amenities: ['Wi-Fi', 'Smart TV', 'Кондиционер', 'Джакузи', 'Мини-бар', 'Халат', 'Тапочки', 'Кофемашина', 'Сейф', 'Балкон'],
    photoUrls: [], has3dTour: true,
  },
  {
    id: 'r4', name: 'Пентхаус', beds: 2, guests: 4, price: 15000, area: 80,
    description: 'Эксклюзивный пентхаус на верхнем этаже с панорамной террасой и видом 360°. Собственная сауна, бар, гостиная класса люкс.',
    photos: [
      { bg: 'from-amber-200 to-orange-200',  emoji: '🌇', label: 'Панорама' },
      { bg: 'from-yellow-100 to-amber-200',  emoji: '🛏️', label: 'Мастер-спальня' },
      { bg: 'from-orange-100 to-red-100',    emoji: '🧖', label: 'Сауна' },
      { bg: 'from-rose-100 to-pink-100',     emoji: '🛋️', label: 'Гостиная' },
      { bg: 'from-red-100 to-orange-100',    emoji: '🌅', label: 'Терраса' },
      { bg: 'from-amber-100 to-yellow-100',  emoji: '🍸', label: 'Бар' },
    ],
    amenities: ['Wi-Fi 1Гбит', 'Smart TV 75"', 'Кондиционер', 'Сауна', 'Мини-бар', 'Джакузи', 'Терраса', 'Дворецкий', 'Кофемашина', 'Халат', 'Тапочки', 'Сейф'],
    photoUrls: [], has3dTour: true,
  },
]

interface MockCategory {
  id: string
  name: string
  minPrice: number
  maxGuests: number
  amenities: string[]
  description: string
  photos: string[]
  availableCount: number
}

const MOCK_CATEGORIES: MockCategory[] = [
  { id: 'c1', name: 'Стандарт',  minPrice: 4500,  maxGuests: 2, availableCount: 3, photos: [],
    amenities: ['Wi-Fi', 'TV', 'Кондиционер', 'Фен'],
    description: 'Уютные номера с современным ремонтом и всем необходимым для комфортного проживания.' },
  { id: 'c2', name: 'Комфорт',   minPrice: 6500,  maxGuests: 2, availableCount: 2, photos: [],
    amenities: ['Wi-Fi', 'TV', 'Кондиционер', 'Мини-бар', 'Кофемашина'],
    description: 'Просторные номера с расширенными удобствами и зоной отдыха.' },
  { id: 'c3', name: 'Делюкс',    minPrice: 8900,  maxGuests: 3, availableCount: 1, photos: [],
    amenities: ['Wi-Fi', 'Smart TV', 'Кондиционер', 'Джакузи', 'Балкон'],
    description: 'Роскошные номера с панорамными окнами и собственным джакузи.' },
  { id: 'c4', name: 'Пентхаус',  minPrice: 15000, maxGuests: 4, availableCount: 1, photos: [],
    amenities: ['Wi-Fi 1Гбит', 'Smart TV 75"', 'Сауна', 'Терраса', 'Дворецкий'],
    description: 'Эксклюзивный пентхаус на верхнем этаже с террасой и видом 360°.' },
]

const AMENITY_ICONS: Record<string, React.ElementType> = {
  'Wi-Fi': Wifi, 'Wi-Fi 1Гбит': Wifi,
  'TV': Tv2, 'Smart TV': Tv2, 'Smart TV 75"': Tv2,
  'Кондиционер': Wind,
  'Кофемашина': Coffee,
  'Халат': Shirt, 'Тапочки': Shirt,
  'Джакузи': Bath, 'Ванная': Bath,
  'Балкон': Mountain, 'Терраса': Mountain,
  'Сейф': Shield,
}

const EXTRA_BED_PRICE = 1500

export const DEFAULT_FORM_FIELDS: FormField[] = [
  { id: 'name',    label: 'Имя и фамилия',   type: 'text',    required: true,  enabled: true },
  { id: 'email',   label: 'Email',            type: 'email',   required: true,  enabled: true },
  { id: 'phone',   label: 'Телефон',          type: 'phone',   required: true,  enabled: true },
  { id: 'comment', label: 'Пожелания',        type: 'textarea',required: false, enabled: true },
  { id: 'arrival', label: 'Время заезда',     type: 'select',  required: false, enabled: false },
]

export const DEFAULT_SERVICES: AdditionalService[] = [
  { id: 's1', name: 'Теннисный корт', icon: '🎾', price: 1200,  unit: 'ч',   enabled: true  },
  { id: 's2', name: 'Сауна',          icon: '🧖', price: 2500,  unit: 'ч',   enabled: true  },
  { id: 's3', name: 'Банкетный зал',  icon: '🎪', price: 15000, unit: 'день',enabled: false },
  { id: 's4', name: 'Трансфер',       icon: '🚗', price: 3000,  unit: 'раз', enabled: true  },
]

// ── Widget Preview Component ───────────────────────────────────────────────────

export function WidgetPreview({ settings, slug, realRooms, realCategories, realRentalObjects, paymentEnabled }: {
  settings: WidgetSettings
  slug?: string
  realRooms?: WidgetRoom[]
  realCategories?: WidgetCategory[]
  realRentalObjects?: WidgetRentalObject[]
  paymentEnabled?: boolean
}) {
  const [previewTab, setPreviewTab] = useState<'rooms' | 'rental'>('rooms')
  const localDate = (offsetDays = 0) => {
    const d = new Date(); d.setDate(d.getDate() + offsetDays)
    return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`
  }
  const [checkIn,  setCheckIn]  = useState(() => localDate(0))
  const [checkOut, setCheckOut] = useState(() => localDate(1))
  const [guests,   setGuests]   = useState(2)
  const [extraBeds, setExtraBeds] = useState(0)
  const [children, setChildren] = useState(0)
  const [selected, setSelected] = useState<string | null>(null)
  const [expandedRoom, setExpandedRoom] = useState<string | null>(null)
  const [photoIndex, setPhotoIndex] = useState<Record<string, number>>({})
  const [catPhotoIndex, setCatPhotoIndex] = useState<Record<string, number>>({})
  const [step, setStep] = useState<'browse' | 'form' | 'payment' | 'success'>('browse')
  const [submitting, setSubmitting] = useState(false)
  const [confirmUrl, setConfirmUrl] = useState<string | null>(null)

  // Form state
  const [formValues, setFormValues] = useState<Record<string, string>>({})
  const [selectedServices, setSelectedServices] = useState<string[]>([])
  // Hourly service time selections: { serviceId: { date, timeFrom, timeTo } }
  const [serviceSchedule, setServiceSchedule] = useState<Record<string, { date: string; timeFrom: string; timeTo: string }>>({})
  const [bookingError, setBookingError] = useState<string | null>(null)
  const [paidViaGateway, setPaidViaGateway] = useState(false)
  // Guest lookup
  const [guestLookupTimer, setGuestLookupTimer] = useState<ReturnType<typeof setTimeout> | null>(null)
  const [guestSuggestion, setGuestSuggestion] = useState<{ first_name: string; last_name: string; middle_name?: string; phone?: string; email?: string } | null>(null)
  // Rental booking state
  const [rentalDate, setRentalDate]           = useState(() => localDate(0))
  const [rentalIsFullDay, setRentalIsFullDay] = useState(false)
  const [rentalStartHour, setRentalStartHour] = useState(10)
  const [rentalEndHour, setRentalEndHour]     = useState(12)
  const rentalObjects: WidgetRentalObject[] = realRentalObjects ?? []

  const nights = checkIn && checkOut
    ? Math.max(0, (new Date(checkOut).getTime() - new Date(checkIn).getTime()) / 86400000)
    : 0

  // Use real rooms if available, otherwise mock
  const displayRooms = realRooms && realRooms.length > 0
    ? realRooms.map(r => ({
        id: r.id, name: r.name || `Номер ${r.number}`, beds: 0,
        guests: r.maxGuests, price: r.baseRate, area: 0,
        description: r.description ?? '',
        photos: [] as { bg: string; emoji: string; label: string }[],
        photoUrls: r.photos ?? [],
        amenities: r.amenities ?? [],
        has3dTour: false,
      }))
    : MOCK_ROOMS

  // Categories mode
  const displayCategories: Array<{ id: string; name: string; minPrice: number; maxGuests: number; amenities: string[]; description: string; photos: string[]; availableCount: number }> =
    realCategories && realCategories.length > 0
      ? realCategories.map(c => ({
          ...c,
          availableCount: realRooms ? realRooms.filter(r => r.categoryId === c.id).length : 0,
        }))
      : MOCK_CATEGORIES

  const isCategoryMode = settings.roomDisplayMode === 'categories'
  const selectedRoom = !isCategoryMode ? displayRooms.find(r => r.id === selected) : undefined
  const selectedCategory = isCategoryMode ? displayCategories.find(c => c.id === selected) : undefined
  const selectedName = selectedRoom?.name ?? selectedCategory?.name
  const roomTotal = (selectedRoom ? selectedRoom.price : (selectedCategory ? selectedCategory.minPrice : 0)) * Math.max(1, nights)
  const extraTotal = extraBeds * EXTRA_BED_PRICE * Math.max(1, nights)
  const servicesTotal = selectedServices.reduce((sum, sid) => {
    const s = settings.additionalServices.find(s => s.id === sid)
    return sum + (s ? s.price : 0)
  }, 0)
  const grandTotal = roomTotal + extraTotal + servicesTotal

  const activeFields = settings.formFields.filter(f => f.enabled)
  const needsPayment = paymentEnabled ?? (settings.paymentProvider !== 'none')

  const handleBook = () => {
    if (!selected) return
    if (previewTab === 'rooms' && nights === 0) return
    setStep('form')
  }

  const handleSubmit = async () => {
    const missing = activeFields.filter(f => f.required && !formValues[f.id]?.trim())
    if (missing.length > 0) return
    setBookingError(null)

    if (slug && selected) {
      setSubmitting(true)
      try {
        if (previewTab === 'rental') {
          // Rental booking
          const obj = rentalObjects.find(o => o.id === selected)
          const rentalAmount = rentalIsFullDay
            ? obj?.pricePerDay ?? 0
            : (rentalEndHour - rentalStartHour) * (obj?.pricePerHour ?? 0)
          await api.widget.createRentalBooking(slug, {
            objectId: selected,
            date: rentalDate,
            isFullDay: rentalIsFullDay,
            startHour: rentalIsFullDay ? undefined : rentalStartHour,
            endHour:   rentalIsFullDay ? undefined : rentalEndHour,
            guestName:  formValues['name'] ?? formValues['full_name'] ?? 'Гость',
            guestEmail: formValues['email'] ?? undefined,
            guestPhone: formValues['phone'] ?? undefined,
            totalAmount: rentalAmount,
            notes: formValues['notes'] ?? formValues['comment'] ?? undefined,
          })
          setStep('success')
        } else {
          // Room booking
          const services = selectedServices
            .map(sid => settings.additionalServices.find(s => s.id === sid))
            .filter(Boolean)
            .map(s => ({ name: s!.name, price: s!.price }))

          const result = await api.widget.createBooking(slug, {
            ...(isCategoryMode ? { categoryId: selected! } : { roomId: selected! }),
            checkIn, checkOut,
            guestName: formValues['name'] ?? formValues['full_name'] ?? 'Гость',
            guestEmail: formValues['email'] ?? undefined,
            guestPhone: formValues['phone'] ?? undefined,
            adults: guests, children,
            totalAmount: grandTotal,
            notes: formValues['notes'] ?? formValues['comment'] ?? undefined,
            services,
          })
          if (result.confirmationUrl) {
            setConfirmUrl(result.confirmationUrl)
            setStep('payment')
          } else {
            setStep('success')
          }
        }
      } catch (err: any) {
        if (err?.status === 403) {
          setBookingError(err?.error ?? 'Невозможно завершить бронирование. Попробуйте позже или свяжитесь с отелем.')
        } else if (err?.status === 409) {
          setBookingError(err?.error ?? 'Выбранное время уже занято. Пожалуйста, выберите другое.')
        } else {
          setBookingError('Ошибка при создании бронирования. Попробуйте ещё раз или свяжитесь с отелем.')
        }
      } finally {
        setSubmitting(false)
      }
    } else {
      // Preview mode without real slug
      if (needsPayment && previewTab === 'rooms') {
        setStep('payment')
      } else {
        setStep('success')
      }
    }
  }

  const handlePay = () => {
    if (confirmUrl) {
      setPaidViaGateway(true)
      window.location.href = confirmUrl
    } else {
      setStep('success')
    }
  }

  const handleBack = () => {
    if (step === 'payment') { setStep('form'); return }
    setStep('browse')
    setFormValues({})
    setSelectedServices([])
    setServiceSchedule({})
    setBookingError(null)
    setGuestSuggestion(null)
    setPaidViaGateway(false)
    setConfirmUrl(null)
  }

  const doGuestLookup = (email?: string, phone?: string) => {
    if (!slug || (!email && !phone)) return
    if (guestLookupTimer) clearTimeout(guestLookupTimer)
    const t = setTimeout(async () => {
      const g = await api.widget.lookupGuest(slug, { email, phone })
      if (g && !g.is_blacklisted) setGuestSuggestion(g)
    }, 600)
    setGuestLookupTimer(t)
  }

  // ── Success screen ──
  if (step === 'success') {
    return (
      <div className="bg-white rounded-2xl shadow-2xl overflow-hidden border border-slate-200" style={{ fontFamily: 'Inter, sans-serif' }}>
        <div className="px-6 py-4 text-white" style={{ background: settings.primaryColor }}>
          <p className="font-bold text-lg">{settings.hotelName || 'Название отеля'}</p>
        </div>
        <div className="p-8 text-center space-y-3">
          <div className="w-16 h-16 rounded-full flex items-center justify-center mx-auto" style={{ background: settings.primaryColor + '20' }}>
            <Check size={32} style={{ color: settings.primaryColor }} />
          </div>
          <p className="text-lg font-bold text-slate-900">Бронирование принято!</p>
          <p className="text-sm text-slate-500">
            {paidViaGateway
              ? 'Оплата прошла успешно. Подтверждение придёт на email.'
              : needsPayment
                ? 'Бронирование принято. Менеджер свяжется с вами для оплаты.'
                : 'Оплата на месте при заезде. Подтверждение придёт на email.'}
          </p>
          <div className="bg-slate-50 rounded-xl p-4 text-left space-y-1">
            {previewTab === 'rental' ? (
              <>
                <p className="text-xs text-slate-500">Объект: <span className="font-medium text-slate-700">{rentalObjects.find(o => o.id === selected)?.name ?? selected}</span></p>
                <p className="text-xs text-slate-500">Дата: <span className="font-medium text-slate-700">{rentalDate}</span></p>
                {!rentalIsFullDay && <p className="text-xs text-slate-500">Время: <span className="font-medium text-slate-700">{rentalStartHour}:00 – {rentalEndHour}:00</span></p>}
              </>
            ) : (
              <>
                <p className="text-xs text-slate-500">{isCategoryMode ? 'Категория' : 'Номер'}: <span className="font-medium text-slate-700">{selectedName}</span></p>
                <p className="text-xs text-slate-500">Заезд: <span className="font-medium text-slate-700">{checkIn}</span></p>
                <p className="text-xs text-slate-500">Выезд: <span className="font-medium text-slate-700">{checkOut}</span></p>
                <p className="text-xs text-slate-500">Итого: <span className="font-bold text-slate-900">{grandTotal.toLocaleString('ru-RU')} ₽</span></p>
              </>
            )}
          </div>
          <button
            onClick={() => { setStep('browse'); setSelected(null); setFormValues({}) }}
            className="text-sm font-medium hover:underline"
            style={{ color: settings.primaryColor }}
          >
            Новое бронирование
          </button>
        </div>
      </div>
    )
  }

  // ── Payment screen (YooKassa redirect) ──
  if (step === 'payment') {
    return (
      <div className="bg-white rounded-2xl shadow-2xl overflow-hidden border border-slate-200" style={{ fontFamily: 'Inter, sans-serif' }}>
        <div className="px-6 py-4 text-white flex items-center gap-3" style={{ background: settings.primaryColor }}>
          <button onClick={handleBack} className="opacity-80 hover:opacity-100">
            <ChevronLeft size={18} />
          </button>
          <div>
            <p className="font-bold">{settings.language === 'ru' ? 'Оплата' : 'Payment'}</p>
            <p className="text-xs opacity-80">{selectedName} · {grandTotal.toLocaleString('ru-RU')} ₽</p>
          </div>
        </div>

        <div className="p-5 space-y-4">
          <div className="bg-slate-50 rounded-xl p-3 flex items-center justify-between">
            <span className="text-sm text-slate-600">{selectedName} · {nights} ноч.</span>
            <span className="text-base font-bold text-slate-900">{grandTotal.toLocaleString('ru-RU')} ₽</span>
          </div>
          <div className="text-center space-y-3 py-2">
            <div className="w-14 h-14 rounded-full flex items-center justify-center mx-auto bg-slate-100">
              <CreditCard size={28} className="text-slate-500" />
            </div>
            <p className="text-sm text-slate-700 font-medium">
              {settings.language === 'ru'
                ? 'Для завершения бронирования перейдите к оплате'
                : 'Please proceed to payment to confirm your booking'}
            </p>
            <p className="text-xs text-slate-400">🔒 Защищённое соединение · ЮKassa</p>
          </div>
        </div>

        <div className="px-5 pb-5">
          <button
            onClick={handlePay}
            className="w-full py-3 rounded-xl text-white font-semibold text-sm transition-opacity hover:opacity-90"
            style={{ background: settings.primaryColor }}
          >
            {settings.language === 'ru'
              ? `Оплатить · ${grandTotal.toLocaleString('ru-RU')} ₽`
              : `Pay · ${grandTotal.toLocaleString('ru-RU')} ₽`}
          </button>
        </div>
      </div>
    )
  }

  // ── Guest form screen ──
  if (step === 'form') {
    return (
      <div className="bg-white rounded-2xl shadow-2xl overflow-hidden border border-slate-200" style={{ fontFamily: 'Inter, sans-serif' }}>
        <div className="px-6 py-4 text-white flex items-center gap-3" style={{ background: settings.primaryColor }}>
          <button onClick={handleBack} className="opacity-80 hover:opacity-100">
            <ChevronLeft size={18} />
          </button>
          <div>
            <p className="font-bold">{settings.language === 'ru' ? 'Данные гостя' : 'Guest details'}</p>
            <p className="text-xs opacity-80">{selectedName} · {nights} ноч.</p>
          </div>
          {/* Step indicator */}
          <div className="ml-auto flex items-center gap-1">
            {[1, 2, needsPayment ? 3 : null].filter(Boolean).map((s, i) => (
              <div key={i} className={cn('w-2 h-2 rounded-full', step === 'form' && s === 1 ? 'bg-white' : 'bg-white/40')} />
            ))}
            <div className={cn('w-2 h-2 rounded-full', step === 'form' ? 'bg-white' : 'bg-white/40')} />
            {needsPayment && <div className="w-2 h-2 rounded-full bg-white/40" />}
          </div>
        </div>

        <div className="p-5 space-y-3 max-h-[500px] overflow-y-auto">
          {/* Summary */}
          <div className="bg-slate-50 rounded-xl p-3 space-y-1">
            <div className="flex justify-between text-xs">
              <span className="text-slate-500">{selectedName} × {nights} ноч.</span>
              <span className="font-medium">{roomTotal.toLocaleString('ru-RU')} ₽</span>
            </div>
            {extraBeds > 0 && (
              <div className="flex justify-between text-xs">
                <span className="text-slate-500">Доп. места × {extraBeds}</span>
                <span className="font-medium">{extraTotal.toLocaleString('ru-RU')} ₽</span>
              </div>
            )}
            {selectedServices.map(sid => {
              const s = settings.additionalServices.find(s => s.id === sid)
              return s ? (
                <div key={sid} className="flex justify-between text-xs">
                  <span className="text-slate-500">{s.icon} {s.name}</span>
                  <span className="font-medium">{s.price.toLocaleString('ru-RU')} ₽</span>
                </div>
              ) : null
            })}
            <div className="flex justify-between text-sm font-bold pt-1 border-t border-slate-200">
              <span>Итого</span>
              <span>{grandTotal.toLocaleString('ru-RU')} ₽</span>
            </div>
          </div>

          {/* Additional services */}
          {settings.additionalServices.filter(s => s.enabled).length > 0 && (
            <div>
              <p className="text-xs font-medium text-slate-700 mb-1.5">
                {settings.language === 'ru' ? 'Дополнительные услуги' : 'Additional services'}
              </p>
              <div className="space-y-2">
                {settings.additionalServices.filter(s => s.enabled).map(s => {
                  const isHourly = s.unit === 'ч'
                  const schedule = serviceSchedule[s.id]
                  const isSelected = selectedServices.includes(s.id)
                  return (
                    <div key={s.id} className="space-y-1.5">
                      <label className="flex items-center gap-2 cursor-pointer">
                        <input
                          type="checkbox"
                          checked={isSelected}
                          onChange={e => {
                            setSelectedServices(prev =>
                              e.target.checked ? [...prev, s.id] : prev.filter(x => x !== s.id)
                            )
                            if (!e.target.checked) {
                              setServiceSchedule(prev => { const n = {...prev}; delete n[s.id]; return n })
                            }
                          }}
                          className="rounded"
                        />
                        <span className="text-sm text-slate-700 flex-1">{s.icon} {s.name}</span>
                        <span className="text-xs text-slate-500">{s.price.toLocaleString('ru-RU')} ₽/{s.unit}</span>
                      </label>
                      {/* Hourly time picker */}
                      {isSelected && isHourly && (
                        <div className="ml-5 grid grid-cols-3 gap-2 p-2 bg-slate-50 rounded-lg border border-slate-200">
                          <div>
                            <label className="block text-[10px] text-slate-500 mb-0.5">Дата</label>
                            <input
                              type="date"
                              className="w-full text-xs border border-slate-200 rounded px-1.5 py-1 bg-white focus:outline-none"
                              value={schedule?.date ?? checkIn}
                              onChange={e => setServiceSchedule(prev => ({ ...prev, [s.id]: { ...prev[s.id], date: e.target.value, timeFrom: prev[s.id]?.timeFrom ?? '10:00', timeTo: prev[s.id]?.timeTo ?? '12:00' } }))}
                            />
                          </div>
                          <div>
                            <label className="block text-[10px] text-slate-500 mb-0.5">С</label>
                            <select
                              className="w-full text-xs border border-slate-200 rounded px-1.5 py-1 bg-white focus:outline-none"
                              value={schedule?.timeFrom ?? '10:00'}
                              onChange={e => setServiceSchedule(prev => ({ ...prev, [s.id]: { ...prev[s.id], date: prev[s.id]?.date ?? checkIn, timeFrom: e.target.value, timeTo: prev[s.id]?.timeTo ?? '12:00' } }))}
                            >
                              {Array.from({ length: 17 }, (_, i) => i + 7).map(h => (
                                <option key={h} value={`${String(h).padStart(2,'0')}:00`}>{String(h).padStart(2,'0')}:00</option>
                              ))}
                            </select>
                          </div>
                          <div>
                            <label className="block text-[10px] text-slate-500 mb-0.5">По</label>
                            <select
                              className="w-full text-xs border border-slate-200 rounded px-1.5 py-1 bg-white focus:outline-none"
                              value={schedule?.timeTo ?? '12:00'}
                              onChange={e => setServiceSchedule(prev => ({ ...prev, [s.id]: { ...prev[s.id], date: prev[s.id]?.date ?? checkIn, timeFrom: prev[s.id]?.timeFrom ?? '10:00', timeTo: e.target.value } }))}
                            >
                              {Array.from({ length: 17 }, (_, i) => i + 8).map(h => (
                                <option key={h} value={`${String(h).padStart(2,'0')}:00`}>{String(h).padStart(2,'0')}:00</option>
                              ))}
                            </select>
                          </div>
                        </div>
                      )}
                    </div>
                  )
                })}
              </div>
            </div>
          )}

          {/* Form fields */}
          {activeFields.map(field => (
            <div key={field.id}>
              <label className="block text-xs text-slate-500 mb-1">
                {field.label}{field.required && <span className="text-red-500 ml-0.5">*</span>}
              </label>
              {field.type === 'textarea' ? (
                <textarea
                  rows={2}
                  className="w-full text-sm border border-slate-200 rounded-lg px-3 py-2 focus:outline-none resize-none"
                  value={formValues[field.id] ?? ''}
                  onChange={e => setFormValues(prev => ({ ...prev, [field.id]: e.target.value }))}
                />
              ) : field.type === 'select' ? (
                <select
                  className="w-full text-sm border border-slate-200 rounded-lg px-3 py-2 focus:outline-none bg-white"
                  value={formValues[field.id] ?? ''}
                  onChange={e => setFormValues(prev => ({ ...prev, [field.id]: e.target.value }))}
                >
                  <option value="">Выбрать...</option>
                  <option>До 12:00</option>
                  <option>12:00–14:00</option>
                  <option>14:00–16:00</option>
                  <option>После 16:00</option>
                </select>
              ) : (
                <input
                  type={field.type === 'phone' ? 'tel' : field.type}
                  inputMode={field.type === 'phone' ? 'tel' : undefined}
                  placeholder={field.type === 'phone' ? '+7 (___) ___-__-__' : undefined}
                  className="w-full text-sm border border-slate-200 rounded-lg px-3 py-2 focus:outline-none"
                  value={formValues[field.id] ?? ''}
                  onChange={e => {
                    let val = e.target.value
                    if (field.type === 'phone') {
                      const digits = val.replace(/\D/g, '').slice(0, 11)
                      if (digits.length === 0) { val = '' }
                      else {
                        const d = digits.startsWith('8') ? '7' + digits.slice(1) : digits
                        const n = d.startsWith('7') ? d : '7' + d
                        val = '+7'
                        if (n.length > 1) val += ' (' + n.slice(1, 4)
                        if (n.length > 4) val += ') ' + n.slice(4, 7)
                        if (n.length > 7) val += '-' + n.slice(7, 9)
                        if (n.length > 9) val += '-' + n.slice(9, 11)
                      }
                    }
                    setFormValues(prev => ({ ...prev, [field.id]: val }))
                    if (field.id === 'email') doGuestLookup(val, formValues['phone'])
                    if (field.id === 'phone') doGuestLookup(formValues['email'], val)
                  }}
                />
              )}
            </div>
          ))}

          {/* Guest suggestion */}
          {guestSuggestion && (
            <div className="flex items-center justify-between bg-indigo-50 border border-indigo-200 rounded-xl px-3 py-2">
              <div className="text-xs text-indigo-700">
                <span className="font-medium">Гость найден: </span>
                {guestSuggestion.last_name} {guestSuggestion.first_name} {guestSuggestion.middle_name ?? ''}
              </div>
              <button
                className="text-xs font-semibold text-indigo-600 hover:text-indigo-800 ml-2 shrink-0"
                onClick={() => {
                  const g = guestSuggestion
                  const fullName = [g.last_name, g.first_name, g.middle_name].filter(Boolean).join(' ')
                  setFormValues(prev => ({
                    ...prev,
                    name: fullName,
                    full_name: fullName,
                    ...(g.email && { email: g.email }),
                    ...(g.phone && { phone: g.phone }),
                  }))
                  setGuestSuggestion(null)
                }}
              >
                Заполнить
              </button>
            </div>
          )}
        </div>

        <div className="px-5 pb-5 pt-2 space-y-2">
          {bookingError && (
            <div className="flex items-start gap-2 bg-red-50 border border-red-200 rounded-xl px-3 py-2">
              <AlertCircle size={14} className="text-red-500 mt-0.5 shrink-0" />
              <p className="text-xs text-red-700">{bookingError}</p>
            </div>
          )}
          <button
            onClick={handleSubmit}
            disabled={submitting}
            className="w-full py-3 rounded-xl text-white font-semibold text-sm transition-opacity hover:opacity-90 disabled:opacity-70 flex items-center justify-center gap-2"
            style={{ background: settings.primaryColor }}
          >
            {submitting && <Loader2 size={14} className="animate-spin" />}
            {submitting ? 'Отправляем...' : needsPayment
              ? (settings.language === 'ru' ? `Перейти к оплате · ${grandTotal.toLocaleString('ru-RU')} ₽` : `Proceed to payment · ${grandTotal.toLocaleString('ru-RU')} ₽`)
              : (settings.language === 'ru' ? `Подтвердить · ${grandTotal.toLocaleString('ru-RU')} ₽` : `Confirm · ${grandTotal.toLocaleString('ru-RU')} ₽`)}
          </button>
          {!needsPayment && (
            <p className="text-center text-xs text-slate-400">Оплата на месте при заезде</p>
          )}
        </div>
      </div>
    )
  }

  return (
    <div className="bg-white rounded-2xl shadow-2xl overflow-hidden border border-slate-200" style={{ fontFamily: 'Inter, sans-serif' }}>
      {/* Widget header */}
      <div className="px-6 py-4 text-white" style={{ background: settings.primaryColor }}>
        <p className="font-bold text-lg">{settings.hotelName || 'Название отеля'}</p>
        <p className="text-sm opacity-80">
          {settings.language === 'ru' ? 'Бронирование онлайн · Без комиссии' : 'Book directly · No fees'}
        </p>
      </div>

      {/* Tabs */}
      {settings.showRooms && settings.showRental && (
        <div className="flex border-b border-slate-200">
          {[
            ['rooms',  settings.language === 'ru' ? 'Номера'   : 'Rooms'],
            ['rental', settings.language === 'ru' ? 'Аренда'   : 'Rental'],
          ].map(([key, label]) => (
            <button
              key={key}
              onClick={() => setPreviewTab(key as any)}
              className={cn(
                'flex-1 py-3 text-sm font-medium border-b-2 transition-colors',
                previewTab === key
                  ? 'border-b-2 text-slate-900'
                  : 'border-transparent text-slate-500 hover:text-slate-700',
              )}
              style={previewTab === key ? { borderColor: settings.primaryColor, color: settings.primaryColor } : {}}
            >
              {label}
            </button>
          ))}
        </div>
      )}

      {/* Search bar */}
      {previewTab === 'rooms' && (
        <div className="px-5 py-4 bg-slate-50 border-b border-slate-200">
          <div className="grid grid-cols-2 gap-3 mb-3">
            <div>
              <label className="block text-xs text-slate-500 mb-1">
                {settings.language === 'ru' ? 'Заезд' : 'Check-in'}
              </label>
              <input
                type="date"
                value={checkIn}
                onChange={e => setCheckIn(e.target.value)}
                className="w-full text-sm border border-slate-200 rounded-lg px-2.5 py-1.5 bg-white focus:outline-none"
              />
            </div>
            <div>
              <label className="block text-xs text-slate-500 mb-1">
                {settings.language === 'ru' ? 'Выезд' : 'Check-out'}
              </label>
              <input
                type="date"
                value={checkOut}
                onChange={e => setCheckOut(e.target.value)}
                className="w-full text-sm border border-slate-200 rounded-lg px-2.5 py-1.5 bg-white focus:outline-none"
              />
            </div>
          </div>
          <div className="grid grid-cols-3 gap-2">
            <div>
              <label className="block text-xs text-slate-500 mb-1">
                {settings.language === 'ru' ? 'Взрослых' : 'Adults'}
              </label>
              <div className="flex items-center gap-1">
                <button onClick={() => setGuests(g => Math.max(1, g - 1))} className="w-6 h-6 rounded-lg border border-slate-200 flex items-center justify-center hover:bg-slate-100 text-slate-700 text-xs">−</button>
                <span className="flex-1 text-center text-sm font-medium">{guests}</span>
                <button onClick={() => setGuests(g => Math.min(8, g + 1))} className="w-6 h-6 rounded-lg border border-slate-200 flex items-center justify-center hover:bg-slate-100 text-slate-700 text-xs">+</button>
              </div>
            </div>
            {settings.allowChildren && (
              <div>
                <label className="block text-xs text-slate-500 mb-1">
                  {settings.language === 'ru' ? 'Детей' : 'Children'}
                </label>
                <div className="flex items-center gap-1">
                  <button onClick={() => setChildren(c => Math.max(0, c - 1))} className="w-6 h-6 rounded-lg border border-slate-200 flex items-center justify-center hover:bg-slate-100 text-slate-700 text-xs">−</button>
                  <span className="flex-1 text-center text-sm font-medium">{children}</span>
                  <button onClick={() => setChildren(c => Math.min(4, c + 1))} className="w-6 h-6 rounded-lg border border-slate-200 flex items-center justify-center hover:bg-slate-100 text-slate-700 text-xs">+</button>
                </div>
              </div>
            )}
            {settings.allowExtraBeds && (
              <div>
                <label className="block text-xs text-slate-500 mb-1">
                  {settings.language === 'ru' ? 'Доп. мест' : 'Extra beds'}
                </label>
                <div className="flex items-center gap-1">
                  <button onClick={() => setExtraBeds(b => Math.max(0, b - 1))} className="w-6 h-6 rounded-lg border border-slate-200 flex items-center justify-center hover:bg-slate-100 text-slate-700 text-xs">−</button>
                  <span className="flex-1 text-center text-sm font-medium">{extraBeds}</span>
                  <button onClick={() => setExtraBeds(b => Math.min(3, b + 1))} className="w-6 h-6 rounded-lg border border-slate-200 flex items-center justify-center hover:bg-slate-100 text-slate-700 text-xs">+</button>
                </div>
                {extraBeds > 0 && (
                  <p className="text-[10px] text-slate-400 text-center">{(extraBeds * EXTRA_BED_PRICE).toLocaleString('ru-RU')} ₽/ноч</p>
                )}
              </div>
            )}
          </div>
        </div>
      )}

      {/* Rooms list / Category list */}
      {previewTab === 'rooms' && isCategoryMode && (
        <div className="p-4 space-y-3 max-h-[480px] overflow-y-auto">
          {nights > 0 && (
            <p className="text-xs text-slate-500">
              {nights} {nights === 1 ? 'ночь' : nights < 5 ? 'ночи' : 'ночей'} · {guests} {settings.language === 'ru' ? 'гостей' : 'guests'}
              {children > 0 && ` · ${children} дет.`}
            </p>
          )}
          {displayCategories.map(cat => {
            const isSelected = selected === cat.id
            const curIdx = catPhotoIndex[cat.id] ?? 0
            const photos = cat.photos ?? []
            return (
              <div
                key={cat.id}
                className={cn('rounded-2xl border-2 overflow-hidden transition-all shadow-sm hover:shadow-md', isSelected ? 'border-2' : 'border-slate-200')}
                style={isSelected ? { borderColor: settings.primaryColor } : {}}
              >
                {/* Photo gallery */}
                <div className="relative w-full h-44 bg-slate-100 overflow-hidden group">
                  {photos.length > 0 ? (
                    <>
                      <img
                        src={photos[curIdx]}
                        alt={cat.name}
                        className="w-full h-full object-cover transition-transform duration-300"
                      />
                      {/* Gradient overlay */}
                      <div className="absolute inset-0 bg-gradient-to-t from-black/50 via-transparent to-transparent" />
                      {/* Nav arrows */}
                      {photos.length > 1 && (
                        <>
                          <button
                            onClick={e => { e.stopPropagation(); setCatPhotoIndex(p => ({ ...p, [cat.id]: Math.max(0, (p[cat.id] ?? 0) - 1) })) }}
                            disabled={curIdx === 0}
                            className="absolute left-2 top-1/2 -translate-y-1/2 w-7 h-7 rounded-full bg-white/80 flex items-center justify-center shadow opacity-0 group-hover:opacity-100 transition-opacity disabled:opacity-0"
                          >
                            <ChevronLeft size={14} />
                          </button>
                          <button
                            onClick={e => { e.stopPropagation(); setCatPhotoIndex(p => ({ ...p, [cat.id]: Math.min(photos.length - 1, (p[cat.id] ?? 0) + 1) })) }}
                            disabled={curIdx === photos.length - 1}
                            className="absolute right-2 top-1/2 -translate-y-1/2 w-7 h-7 rounded-full bg-white/80 flex items-center justify-center shadow opacity-0 group-hover:opacity-100 transition-opacity disabled:opacity-0"
                          >
                            <ChevronRight size={14} />
                          </button>
                          {/* Dots */}
                          <div className="absolute bottom-2 left-1/2 -translate-x-1/2 flex gap-1">
                            {photos.map((_, i) => (
                              <button
                                key={i}
                                onClick={e => { e.stopPropagation(); setCatPhotoIndex(p => ({ ...p, [cat.id]: i })) }}
                                className={cn('w-1.5 h-1.5 rounded-full transition-all', i === curIdx ? 'bg-white scale-125' : 'bg-white/50')}
                              />
                            ))}
                          </div>
                          {/* Counter */}
                          <span className="absolute top-2 right-2 text-[10px] text-white bg-black/40 rounded-full px-2 py-0.5">
                            {curIdx + 1}/{photos.length}
                          </span>
                        </>
                      )}
                      {/* Available badge */}
                      {cat.availableCount > 0 && (
                        <span className="absolute top-2 left-2 text-[10px] font-semibold text-white bg-emerald-500/90 rounded-full px-2 py-0.5">
                          {cat.availableCount} своб.
                        </span>
                      )}
                    </>
                  ) : (
                    <div className="w-full h-full flex flex-col items-center justify-center gap-2">
                      <span className="text-5xl">🛏️</span>
                      <span className="text-xs text-slate-400">Нет фото</span>
                    </div>
                  )}
                </div>

                {/* Card content */}
                <div
                  className={cn('p-3 cursor-pointer transition-colors', isSelected ? '' : 'hover:bg-slate-50')}
                  style={isSelected ? { background: settings.primaryColor + '08' } : {}}
                  onClick={() => setSelected(cat.id === selected ? null : cat.id)}
                >
                  <div className="flex items-start justify-between gap-2">
                    <div className="flex-1 min-w-0">
                      <p className="font-semibold text-slate-900 text-sm leading-tight">{cat.name}</p>
                      <div className="flex items-center gap-2 mt-0.5 flex-wrap">
                        <span className="text-xs text-slate-500 flex items-center gap-0.5">
                          <Users size={10} /> до {cat.maxGuests}
                        </span>
                        {photos.length > 0 && (
                          <span className="text-xs text-slate-400 flex items-center gap-0.5">
                            <Image size={10} /> {photos.length} фото
                          </span>
                        )}
                      </div>
                      {cat.description && (
                        <p className="text-xs text-slate-500 mt-1 line-clamp-2 leading-relaxed">{cat.description}</p>
                      )}
                    </div>
                    <div className="text-right shrink-0">
                      <p className="font-bold text-slate-900 text-base">
                        {nights > 0 ? (cat.minPrice * nights).toLocaleString('ru-RU') : cat.minPrice.toLocaleString('ru-RU')} ₽
                      </p>
                      <p className="text-[10px] text-slate-400">{nights > 0 ? `за ${nights} ноч.` : 'от/ночь'}</p>
                    </div>
                  </div>

                  {/* Amenities */}
                  {cat.amenities.length > 0 && (
                    <div className="flex flex-wrap gap-1 mt-2">
                      {cat.amenities.slice(0, 5).map(a => {
                        const Icon = AMENITY_ICONS[a]
                        return (
                          <span key={a} className="flex items-center gap-0.5 text-[10px] bg-slate-100 text-slate-500 px-1.5 py-0.5 rounded-full">
                            {Icon ? <Icon size={8} /> : null}{a}
                          </span>
                        )
                      })}
                      {cat.amenities.length > 5 && (
                        <span className="text-[10px] text-slate-400">+{cat.amenities.length - 5}</span>
                      )}
                    </div>
                  )}

                  {/* Select button */}
                  <button
                    onClick={e => { e.stopPropagation(); setSelected(cat.id === selected ? null : cat.id) }}
                    className={cn('w-full mt-3 py-2 rounded-xl text-sm font-semibold transition-colors')}
                    style={isSelected
                      ? { background: settings.primaryColor, color: '#fff' }
                      : { border: `2px solid ${settings.primaryColor}`, color: settings.primaryColor, background: 'transparent' }}
                  >
                    {isSelected ? '✓ Выбрана' : 'Выбрать категорию'}
                  </button>
                </div>
              </div>
            )
          })}
        </div>
      )}

      {previewTab === 'rooms' && !isCategoryMode && (
        <div className="p-4 space-y-3 max-h-[480px] overflow-y-auto">
          {nights > 0 && (
            <p className="text-xs text-slate-500">
              {nights} {nights === 1 ? 'ночь' : nights < 5 ? 'ночи' : 'ночей'} · {guests} {settings.language === 'ru' ? 'гостей' : 'guests'}
              {children > 0 && ` · ${children} дет.`}
            </p>
          )}
          {displayRooms.map(room => {
            const isExpanded = expandedRoom === room.id
            const isSelected = selected === room.id
            const hasRealPhotos = room.photoUrls.length > 0
            const totalPhotos = hasRealPhotos ? room.photoUrls.length : room.photos.length
            const curPhoto = Math.min(photoIndex[room.id] ?? 0, Math.max(0, totalPhotos - 1))
            const photo = room.photos[curPhoto] ?? { bg: 'from-slate-200 to-slate-300', emoji: '🛏️', label: 'Фото' }
            const curPhotoUrl = hasRealPhotos ? room.photoUrls[curPhoto] : null
            return (
              <div
                key={room.id}
                className={cn(
                  'rounded-xl border-2 overflow-hidden transition-all',
                  isSelected ? 'border-2' : 'border-slate-200',
                )}
                style={isSelected ? { borderColor: settings.primaryColor } : {}}
              >
                {/* Card header — always visible */}
                <div
                  className={cn(
                    'flex items-center gap-3 p-3 cursor-pointer transition-colors',
                    isSelected ? '' : 'hover:bg-slate-50',
                  )}
                  style={isSelected ? { background: settings.primaryColor + '08' } : {}}
                  onClick={() => setSelected(room.id === selected ? null : room.id)}
                >
                  {/* Thumbnail */}
                  {curPhotoUrl ? (
                    <img src={curPhotoUrl} alt={room.name} className="w-14 h-14 rounded-xl object-cover shrink-0" />
                  ) : (
                    <div className={cn('w-14 h-14 rounded-xl bg-gradient-to-br flex items-center justify-center text-2xl shrink-0', photo.bg)}>
                      {photo.emoji}
                    </div>
                  )}

                  <div className="flex-1 min-w-0">
                    <p className="font-semibold text-slate-900 text-sm">{room.name}</p>
                    <div className="flex items-center gap-2 mt-0.5 flex-wrap">
                      <span className="text-xs text-slate-500 flex items-center gap-0.5">
                        <Users size={10} /> до {room.guests}
                      </span>
                      {room.beds > 0 && (
                        <span className="text-xs text-slate-500 flex items-center gap-0.5">
                          <BedDouble size={10} /> {room.beds} кр.
                        </span>
                      )}
                      {room.area > 0 && (
                        <span className="text-xs text-slate-500">{room.area} м²</span>
                      )}
                    </div>
                  </div>

                  <div className="text-right shrink-0">
                    <p className="font-bold text-slate-900 text-sm">
                      {nights > 0
                        ? (room.price * nights).toLocaleString('ru-RU')
                        : room.price.toLocaleString('ru-RU')
                      } ₽
                    </p>
                    <p className="text-[10px] text-slate-400">
                      {nights > 0 ? `за ${nights} ноч.` : 'за ночь'}
                    </p>
                  </div>

                  {/* Expand toggle */}
                  <button
                    onClick={e => { e.stopPropagation(); setExpandedRoom(isExpanded ? null : room.id) }}
                    className="flex items-center gap-0.5 text-[11px] font-medium text-slate-500 hover:text-brand-600 transition-colors shrink-0 px-1.5 py-1 rounded-lg hover:bg-slate-50"
                  >
                    {isExpanded ? (
                      <>Скрыть <ChevronUp size={12} /></>
                    ) : (
                      <>{hasRealPhotos ? `${room.photoUrls.length} фото` : 'Детали'} <ChevronDown size={12} /></>
                    )}
                  </button>
                </div>

                {/* Expanded detail panel */}
                {isExpanded && (
                  <div className="border-t border-slate-100">
                    {/* Photo gallery */}
                    <div className="relative">
                      {curPhotoUrl ? (
                        <img src={curPhotoUrl} alt={room.name} className="w-full h-44 object-cover" />
                      ) : (
                        <div className={cn('h-44 bg-gradient-to-br flex items-center justify-center', photo.bg)}>
                          <span className="text-6xl">{photo.emoji}</span>
                          <span className="absolute bottom-2 left-3 text-xs text-white/90 font-medium drop-shadow">{photo.label}</span>
                        </div>
                      )}

                      {/* Photo nav */}
                      {totalPhotos > 1 && (
                        <>
                          <button
                            onClick={() => setPhotoIndex(prev => ({ ...prev, [room.id]: Math.max(0, (prev[room.id] ?? 0) - 1) }))}
                            disabled={curPhoto === 0}
                            className="absolute left-2 top-1/2 -translate-y-1/2 w-7 h-7 rounded-full bg-black/30 hover:bg-black/50 flex items-center justify-center text-white disabled:opacity-0 transition-all"
                          >
                            <ChevronLeft size={14} />
                          </button>
                          <button
                            onClick={() => setPhotoIndex(prev => ({ ...prev, [room.id]: Math.min(totalPhotos - 1, (prev[room.id] ?? 0) + 1) }))}
                            disabled={curPhoto === totalPhotos - 1}
                            className="absolute right-2 top-1/2 -translate-y-1/2 w-7 h-7 rounded-full bg-black/30 hover:bg-black/50 flex items-center justify-center text-white disabled:opacity-0 transition-all"
                          >
                            <ChevronRight size={14} />
                          </button>
                          {/* Dots */}
                          <div className="absolute bottom-2 right-3 flex gap-1">
                            {Array.from({ length: totalPhotos }).map((_, i) => (
                              <button
                                key={i}
                                onClick={() => setPhotoIndex(prev => ({ ...prev, [room.id]: i }))}
                                className={cn('w-1.5 h-1.5 rounded-full transition-all', i === curPhoto ? 'bg-white' : 'bg-white/50')}
                              />
                            ))}
                          </div>
                        </>
                      )}

                      {/* Photo count */}
                      {totalPhotos > 0 && (
                        <div className="absolute top-2 right-2 flex items-center gap-1 bg-black/30 text-white text-[10px] px-1.5 py-0.5 rounded-full">
                          <Image size={9} />
                          {curPhoto + 1}/{totalPhotos}
                        </div>
                      )}

                      {/* 3D tour badge */}
                      {room.has3dTour && (
                        <button className="absolute top-2 left-2 flex items-center gap-1 bg-indigo-600/90 hover:bg-indigo-700 text-white text-[10px] font-semibold px-2 py-1 rounded-full transition-colors">
                          <Scan size={10} />
                          3D тур
                        </button>
                      )}
                    </div>

                    {/* Thumbnail strip */}
                    {totalPhotos > 1 && (
                      <div className="flex gap-1.5 px-3 py-2 overflow-x-auto">
                        {hasRealPhotos
                          ? room.photoUrls.map((url, i) => (
                            <button
                              key={i}
                              onClick={() => setPhotoIndex(prev => ({ ...prev, [room.id]: i }))}
                              className={cn('w-12 h-9 rounded-lg overflow-hidden shrink-0 transition-all', i === curPhoto ? 'ring-2 ring-offset-1' : 'opacity-60 hover:opacity-90')}
                              style={i === curPhoto ? { '--tw-ring-color': settings.primaryColor } as any : {}}
                            >
                              <img src={url} alt="" className="w-full h-full object-cover" />
                            </button>
                          ))
                          : room.photos.map((p, i) => (
                            <button
                              key={i}
                              onClick={() => setPhotoIndex(prev => ({ ...prev, [room.id]: i }))}
                              className={cn('w-12 h-9 rounded-lg bg-gradient-to-br flex items-center justify-center text-lg shrink-0 transition-all', p.bg, i === curPhoto ? 'ring-2 ring-offset-1' : 'opacity-60 hover:opacity-90')}
                              style={i === curPhoto ? { '--tw-ring-color': settings.primaryColor } as any : {}}
                            >
                              {p.emoji}
                            </button>
                          ))
                        }
                      </div>
                    )}

                    {/* Description */}
                    <div className="px-3 pb-2">
                      <p className="text-xs text-slate-600 leading-relaxed">{room.description}</p>
                    </div>

                    {/* Amenities */}
                    <div className="px-3 pb-3">
                      <p className="text-[10px] font-semibold text-slate-500 uppercase tracking-wide mb-1.5">Удобства в номере</p>
                      <div className="flex flex-wrap gap-1.5">
                        {room.amenities.map(a => {
                          const Icon = AMENITY_ICONS[a]
                          return (
                            <span
                              key={a}
                              className="flex items-center gap-1 text-[11px] bg-slate-100 text-slate-600 px-2 py-0.5 rounded-full"
                            >
                              {Icon ? <Icon size={9} /> : null}
                              {a}
                            </span>
                          )
                        })}
                      </div>
                    </div>

                    {/* 3D tour placeholder — future feature */}
                    {!room.has3dTour && (
                      <div className="mx-3 mb-3 flex items-center gap-2 p-2.5 rounded-xl bg-indigo-50 border border-indigo-100">
                        <Maximize2 size={13} className="text-indigo-400 shrink-0" />
                        <p className="text-[11px] text-indigo-600">3D-тур для этого номера появится в ближайшее время</p>
                      </div>
                    )}

                    {/* Book button in detail panel */}
                    <div className="px-3 pb-3">
                      <button
                        onClick={() => setSelected(room.id)}
                        className={cn(
                          'w-full py-2 rounded-xl text-sm font-semibold transition-colors',
                          isSelected
                            ? 'text-white'
                            : 'border-2 bg-white',
                        )}
                        style={isSelected
                          ? { background: settings.primaryColor }
                          : { borderColor: settings.primaryColor, color: settings.primaryColor }}
                      >
                        {isSelected ? '✓ Выбран' : 'Выбрать этот номер'}
                      </button>
                    </div>
                  </div>
                )}
              </div>
            )
          })}
        </div>
      )}

      {/* Rental list */}
      {previewTab === 'rental' && (
        <div className="p-4 space-y-3">
          {rentalObjects.length === 0 ? (
            <p className="text-xs text-slate-400 text-center py-4">Объекты аренды не настроены</p>
          ) : (
            <>
              {/* Date picker for rental */}
              <div>
                <label className="block text-xs font-medium text-slate-500 mb-1">
                  {settings.language === 'ru' ? 'Дата' : 'Date'}
                </label>
                <input
                  type="date"
                  value={rentalDate}
                  min={localDate(0)}
                  onChange={e => setRentalDate(e.target.value)}
                  className="w-full text-sm border border-slate-200 rounded-lg px-3 py-2 focus:outline-none focus:ring-2"
                  style={{ '--tw-ring-color': settings.primaryColor } as React.CSSProperties}
                />
              </div>
              {/* Objects */}
              {rentalObjects.map(obj => {
                const isSelected = selected === obj.id
                const hourlyAvailable = obj.pricePerHour > 0
                const dayAvailable    = obj.pricePerDay > 0
                const hours = rentalIsFullDay ? 0 : Math.max(0, rentalEndHour - rentalStartHour)
                const price = isSelected
                  ? (rentalIsFullDay ? obj.pricePerDay : hours * obj.pricePerHour)
                  : (hourlyAvailable ? obj.pricePerHour : obj.pricePerDay)
                const priceLabel = isSelected
                  ? (rentalIsFullDay ? `${obj.pricePerDay.toLocaleString('ru-RU')} ₽/день` : `${price.toLocaleString('ru-RU')} ₽ (${hours} ч)`)
                  : (hourlyAvailable ? `${obj.pricePerHour.toLocaleString('ru-RU')} ₽/ч` : `${obj.pricePerDay.toLocaleString('ru-RU')} ₽/день`)
                return (
                  <div key={obj.id} className="rounded-xl border-2 overflow-hidden" style={isSelected ? { borderColor: settings.primaryColor } : { borderColor: '#e2e8f0' }}>
                    <div
                      onClick={() => setSelected(isSelected ? null : obj.id)}
                      className="flex items-center gap-3 p-3 cursor-pointer"
                      style={isSelected ? { background: settings.primaryColor + '0d' } : {}}
                    >
                      <div className="w-10 h-10 rounded-lg bg-slate-100 flex items-center justify-center text-xl shrink-0">{obj.icon}</div>
                      <div className="flex-1">
                        <p className="font-semibold text-slate-900 text-sm">{obj.name}</p>
                        <p className="text-xs text-slate-400">{obj.openHour}:00 – {obj.closeHour}:00</p>
                      </div>
                      <p className="font-bold text-sm text-slate-900">{priceLabel}</p>
                    </div>
                    {/* Time controls when selected */}
                    {isSelected && (
                      <div className="px-3 pb-3 pt-1 space-y-2 border-t border-slate-100">
                        {hourlyAvailable && dayAvailable && (
                          <div className="flex gap-2">
                            <button onClick={() => setRentalIsFullDay(false)} className={cn('flex-1 text-xs py-1.5 rounded-lg border font-medium transition-colors', !rentalIsFullDay ? 'text-white border-transparent' : 'bg-white text-slate-500 border-slate-200')} style={!rentalIsFullDay ? { background: settings.primaryColor } : {}}>По часам</button>
                            <button onClick={() => setRentalIsFullDay(true)}  className={cn('flex-1 text-xs py-1.5 rounded-lg border font-medium transition-colors', rentalIsFullDay  ? 'text-white border-transparent' : 'bg-white text-slate-500 border-slate-200')} style={rentalIsFullDay  ? { background: settings.primaryColor } : {}}>Весь день</button>
                          </div>
                        )}
                        {!rentalIsFullDay && hourlyAvailable && (
                          <div className="flex items-center gap-2 text-xs">
                            <span className="text-slate-500">С</span>
                            <select value={rentalStartHour} onChange={e => { const v = Number(e.target.value); setRentalStartHour(v); if (rentalEndHour <= v) setRentalEndHour(v + 1) }} className="flex-1 border border-slate-200 rounded-lg px-2 py-1.5 text-xs">
                              {Array.from({ length: obj.closeHour - obj.openHour }, (_, i) => obj.openHour + i).map(h => <option key={h} value={h}>{h}:00</option>)}
                            </select>
                            <span className="text-slate-500">до</span>
                            <select value={rentalEndHour} onChange={e => setRentalEndHour(Number(e.target.value))} className="flex-1 border border-slate-200 rounded-lg px-2 py-1.5 text-xs">
                              {Array.from({ length: obj.closeHour - obj.openHour }, (_, i) => obj.openHour + i + 1).filter(h => h > rentalStartHour).map(h => <option key={h} value={h}>{h}:00</option>)}
                            </select>
                          </div>
                        )}
                      </div>
                    )}
                  </div>
                )
              })}
            </>
          )}
        </div>
      )}

      {/* CTA */}
      <div className="px-5 pb-5">
        <button
          onClick={handleBook}
          disabled={!selected || (previewTab === 'rooms' && nights === 0)}
          className="w-full py-3 rounded-xl text-white font-semibold text-sm transition-opacity hover:opacity-90 disabled:opacity-50 disabled:cursor-not-allowed"
          style={{ background: settings.primaryColor }}
        >
          {settings.language === 'ru' ? 'Забронировать' : 'Book now'}
          {selected && nights > 0 && previewTab === 'rooms' && (() => {
            const total = grandTotal
            return total ? ` · ${total.toLocaleString('ru-RU')} ₽` : ''
          })()}
        </button>
        {(!selected || (previewTab === 'rooms' && nights === 0)) && (
          <p className="text-center text-xs text-slate-400 mt-1.5">
            {nights === 0 ? 'Выберите даты заезда и выезда' : 'Выберите номер для бронирования'}
          </p>
        )}
        {settings.showPromo && (
          <p className="text-center text-xs text-slate-400 mt-2">
            {settings.language === 'ru' ? 'Лучшая цена гарантирована' : 'Best rate guaranteed'}
          </p>
        )}
      </div>
    </div>
  )
}

// ── Main Page ──────────────────────────────────────────────────────────────────

export function BookingWidgetPage() {
  const { statuses } = useModules()
  const { user } = useAuth()
  const slug = user?.hotelSlug ?? ''
  const rentalActive = statuses['rental'] === 'active' || statuses['rental'] === 'trial'

  // Real data for preview
  const [realRooms, setRealRooms]               = useState<WidgetRoom[]>([])
  const [realCategories, setRealCategories]     = useState<WidgetCategory[]>([])
  const [realRentalObjects, setRealRentalObjects] = useState<WidgetRentalObject[]>([])
  const [gateway, setGateway]                   = useState<PaymentGateway | null>(null)
  const [gatewayLoading, setGatewayLoading]     = useState(false)

  useEffect(() => {
    if (!slug) return
    setGatewayLoading(true)
    Promise.all([
      api.widget.getConfig(slug).catch(() => null),
      api.paymentGateways.list(slug).catch(() => [] as PaymentGateway[]),
      api.hotelSettings.get(slug).catch(() => ({}) as Record<string, unknown>),
    ]).then(([config, gws, hsRaw]) => {
      const hs = hsRaw as Record<string, unknown>
      if (config?.rooms) setRealRooms(config.rooms)
      if (config?.categories) setRealCategories(config.categories)
      if (config?.rentalObjects) setRealRentalObjects(config.rentalObjects)
      const widgetGw = gws.find(g => g.isActive && g.modules?.includes('booking-widget'))
      setGateway(widgetGw ?? null)
      // Restore saved widget settings
      // Note: transformKeys() converts snake_case→camelCase in responses,
      // so widget_color → widgetColor, widget_show_rooms → widgetShowRooms, etc.
      setSettings(prev => ({
        ...prev,
        hotelName:       String((hs as any).widgetHotelName  ?? config?.hotelName ?? prev.hotelName),
        primaryColor:    String((hs as any).widgetColor       ?? prev.primaryColor),
        language:        (String((hs as any).widgetLang       ?? prev.language)) as 'ru' | 'en',
        showRooms:       (hs as any).widgetShowRooms   !== undefined ? Boolean((hs as any).widgetShowRooms)   : prev.showRooms,
        showRental:      (hs as any).widgetShowRental  !== undefined ? Boolean((hs as any).widgetShowRental)  : prev.showRental,
        roomDisplayMode: (String((hs as any).widgetRoomMode   ?? prev.roomDisplayMode)) as 'rooms' | 'categories',
        minNights:       (hs as any).widgetMinNights   !== undefined ? Number((hs as any).widgetMinNights)    : prev.minNights,
        paymentTimeout:  (hs as any).widgetPaymentTimeout !== undefined ? Number((hs as any).widgetPaymentTimeout) : prev.paymentTimeout,
        showPromo:       (hs as any).widgetShowPromo   !== undefined ? Boolean((hs as any).widgetShowPromo)   : prev.showPromo,
        allowExtraBeds:  (hs as any).widgetExtraBeds   !== undefined ? Boolean((hs as any).widgetExtraBeds)   : prev.allowExtraBeds,
        allowChildren:   (hs as any).widgetChildren    !== undefined ? Boolean((hs as any).widgetChildren)    : prev.allowChildren,
        additionalServices: (() => {
          const rentalObjs = config?.rentalObjects ?? []
          if (rentalObjs.length === 0) return prev.additionalServices
          const saved: { id: string; enabled: boolean }[] = Array.isArray((hs as any).widgetServices)
            ? (hs as any).widgetServices : []
          return rentalObjs.map(o => ({
            id: o.id,
            name: o.name,
            icon: o.icon,
            price: o.pricePerHour,
            unit: 'ч',
            enabled: saved.length > 0 ? (saved.find(s => s.id === o.id)?.enabled ?? true) : true,
          }))
        })(),
      }))
      setSettingsReady(true)
    }).finally(() => setGatewayLoading(false))
  }, [slug])

  const [settings, setSettings] = useState<WidgetSettings>({
    hotelName:       'Grand Palace Hotel',
    primaryColor:    '#4F46E5',
    language:        'ru',
    showRooms:        true,
    showRental:       rentalActive,
    roomDisplayMode:  'rooms',
    minNights:        1,
    paymentTimeout:   15,
    paymentProvider: 'yukassa',
    showPromo:       true,
    allowExtraBeds:  true,
    allowChildren:   true,
    formFields:      DEFAULT_FORM_FIELDS,
    additionalServices: DEFAULT_SERVICES,
  })
  const [copied, setCopied] = useState(false)
  const [saving, setSaving] = useState(false)
  const [codeMode, setCodeMode] = useState<'iframe' | 'floating' | 'trigger'>('iframe')
  const [widgetMaxWidth, setWidgetMaxWidth] = useState<string>('500px')
  const [triggerClass, setTriggerClass] = useState('hotelsync-book')
  const [floatBtnText, setFloatBtnText] = useState('Забронировать')
  const [saved, setSaved] = useState(false)
  const [settingsReady, setSettingsReady] = useState(false)
  const [pageTab, setPageTab] = useState<'constructor' | 'code' | 'stats'>('constructor')
  const [newFieldLabel, setNewFieldLabel] = useState('')
  const [showAddField, setShowAddField] = useState(false)
  const [showAddService, setShowAddService] = useState(false)
  const [editingServiceId, setEditingServiceId] = useState<string | null>(null)
  const [newService, setNewService] = useState<Omit<AdditionalService, 'id' | 'enabled'>>({ name: '', icon: '✨', price: 0, unit: 'раз' })

  const set = <K extends keyof WidgetSettings>(k: K, v: WidgetSettings[K]) =>
    setSettings(prev => ({ ...prev, [k]: v }))

  const doSave = async (s: WidgetSettings) => {
    if (!slug) return
    setSaving(true)
    try {
      await api.hotelSettings.update(slug, {
        widget_hotel_name:  s.hotelName,
        widget_color:       s.primaryColor,
        widget_lang:        s.language,
        widget_show_rooms:  s.showRooms,
        widget_show_rental: s.showRental,
        widget_room_mode:   s.roomDisplayMode,
        widget_min_nights:  s.minNights,
        widget_payment_timeout: s.paymentTimeout,
        widget_show_promo:  s.showPromo,
        widget_extra_beds:  s.allowExtraBeds,
        widget_children:    s.allowChildren,
        widget_services:    s.additionalServices.map(s => ({ id: s.id, enabled: s.enabled })),
      })
      setSaved(true)
      setTimeout(() => setSaved(false), 2000)
    } catch { /* ignore */ }
    finally { setSaving(false) }
  }

  const handleSaveSettings = () => doSave(settings)

  // Auto-save 1.5s after any settings change (only after initial load)
  useEffect(() => {
    if (!settingsReady) return
    const t = setTimeout(() => doSave(settings), 1500)
    return () => clearTimeout(t)
  }, [settings, settingsReady])

  const toggleService = (id: string) =>
    setSettings(prev => ({
      ...prev,
      additionalServices: prev.additionalServices.map(s =>
        s.id === id ? { ...s, enabled: !s.enabled } : s
      ),
    }))

  const addService = () => {
    if (!newService.name.trim()) return
    setSettings(prev => ({
      ...prev,
      additionalServices: [...prev.additionalServices, {
        id: `svc-${Date.now()}`,
        ...newService,
        enabled: true,
      }],
    }))
    setNewService({ name: '', icon: '✨', price: 0, unit: 'раз' })
    setShowAddService(false)
  }

  const updateService = (id: string, patch: Partial<AdditionalService>) =>
    setSettings(prev => ({
      ...prev,
      additionalServices: prev.additionalServices.map(s =>
        s.id === id ? { ...s, ...patch } : s
      ),
    }))

  const removeService = (id: string) =>
    setSettings(prev => ({
      ...prev,
      additionalServices: prev.additionalServices.filter(s => s.id !== id),
    }))

  const toggleField = (id: string, prop: 'enabled' | 'required') =>
    setSettings(prev => ({
      ...prev,
      formFields: prev.formFields.map(f =>
        f.id === id ? { ...f, [prop]: !f[prop] } : f
      ),
    }))

  const addCustomField = () => {
    if (!newFieldLabel.trim()) return
    setSettings(prev => ({
      ...prev,
      formFields: [...prev.formFields, {
        id: `custom-${Date.now()}`,
        label: newFieldLabel.trim(),
        type: 'text',
        required: false,
        enabled: true,
        isCustom: true,
      }],
    }))
    setNewFieldLabel('')
    setShowAddField(false)
  }

  const removeCustomField = (id: string) =>
    setSettings(prev => ({
      ...prev,
      formFields: prev.formFields.filter(f => f.id !== id),
    }))

  const widgetUrl = `https://app.hotelsync.ru/${slug || 'grand-palace'}/book?color=${encodeURIComponent(settings.primaryColor)}&lang=${settings.language}&mode=${settings.roomDisplayMode}&min-nights=${settings.minNights}&rental=${settings.showRental}&promo=${settings.showPromo}&extra-beds=${settings.allowExtraBeds}&children=${settings.allowChildren}`

  const iframeSnippet = widgetMaxWidth === '100%'
    ? `<iframe\n  src="${widgetUrl}"\n  width="100%"\n  height="680"\n  frameborder="0"\n  style="border-radius:16px;border:none;box-shadow:0 4px 24px rgba(0,0,0,0.10);display:block;"\n  allow="payment"\n  loading="lazy"\n></iframe>`
    : `<div style="max-width:${widgetMaxWidth};margin:0 auto;">\n  <iframe\n    src="${widgetUrl}"\n    width="100%"\n    height="680"\n    frameborder="0"\n    style="border-radius:16px;border:none;box-shadow:0 4px 24px rgba(0,0,0,0.10);"\n    allow="payment"\n    loading="lazy"\n  ></iframe>\n</div>`

  const modalScript = `(function(){
  var W='${widgetUrl}';
  var m=document.createElement('div');
  m.id='hs-modal';
  m.style.cssText='display:none;position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:99998;align-items:center;justify-content:center;padding:16px;box-sizing:border-box;';
  m.innerHTML='<div style="position:relative;width:100%;max-width:500px;max-height:90vh;overflow-y:auto;border-radius:16px;">'
    +'<button onclick="document.getElementById(\\'hs-modal\\').style.display=\\'none\\'" style="position:absolute;top:8px;right:8px;z-index:1;width:32px;height:32px;border-radius:50%;background:rgba(0,0,0,.5);color:#fff;border:none;cursor:pointer;font-size:20px;line-height:1;display:flex;align-items:center;justify-content:center;">×</button>'
    +'<iframe src="'+W+'" style="width:100%;height:680px;border:none;border-radius:16px;display:block;" allow="payment"></iframe>'
    +'</div>';
  m.addEventListener('click',function(e){if(e.target===m)m.style.display='none';});
  document.body.appendChild(m);
  window.hsOpenWidget=function(){m.style.display='flex';};
})()`

  const floatingSnippet = `<script>
${modalScript}
;(function(){
  var b=document.createElement('button');
  b.textContent='${floatBtnText}';
  b.style.cssText='position:fixed;bottom:24px;right:24px;background:${settings.primaryColor};color:#fff;border:none;padding:14px 24px;border-radius:50px;font-size:15px;font-weight:600;cursor:pointer;box-shadow:0 4px 20px rgba(0,0,0,.25);z-index:99997;transition:transform .15s,box-shadow .15s;';
  b.onmouseenter=function(){b.style.transform='scale(1.05)';b.style.boxShadow='0 6px 28px rgba(0,0,0,.35)';};
  b.onmouseleave=function(){b.style.transform='scale(1)';b.style.boxShadow='0 4px 20px rgba(0,0,0,.25)';};
  b.onclick=function(){window.hsOpenWidget();};
  document.body.appendChild(b);
})();
</script>`

  const triggerSnippet = `<script>
${modalScript}
;document.addEventListener('click',function(e){
  if(e.target.closest('.${triggerClass}')){e.preventDefault();window.hsOpenWidget();}
});
</script>`

  const activeSnippet = codeMode === 'iframe' ? iframeSnippet : codeMode === 'floating' ? floatingSnippet : triggerSnippet

  const copyCode = () => {
    navigator.clipboard.writeText(activeSnippet).catch(() => {})
    setCopied(true)
    setTimeout(() => setCopied(false), 2000)
  }

  return (
    <div className="p-4 md:p-6 space-y-5">
      {/* Header */}
      <div className="flex items-center gap-3">
        <div className="w-10 h-10 rounded-xl bg-indigo-600 flex items-center justify-center shrink-0">
          <CalendarCheck2 size={20} className="text-white" />
        </div>
        <div>
          <h1 className="text-xl font-bold text-slate-900 dark:text-slate-100">Виджет онлайн-бронирования</h1>
          <p className="text-sm text-slate-500 dark:text-slate-400">Конструктор виджета для размещения на сайте отеля</p>
        </div>
      </div>

      {/* Tabs */}
      <div className="flex gap-1 p-1 bg-slate-100 dark:bg-slate-700/50 rounded-xl w-fit">
        {([
          ['constructor', <Settings2 size={13} />, 'Конструктор'],
          ['code',        <Code2 size={13} />,     'Код установки'],
          ['stats',       <Eye size={13} />,        'Статистика'],
        ] as const).map(([key, icon, label]) => (
          <button
            key={key}
            onClick={() => setPageTab(key)}
            className={cn(
              'flex items-center gap-1.5 px-4 py-1.5 rounded-lg text-sm font-medium transition-colors',
              pageTab === key
                ? 'bg-white dark:bg-slate-800 text-slate-900 dark:text-slate-100 shadow-sm'
                : 'text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-slate-200',
            )}
          >
            {icon}{label}
          </button>
        ))}
      </div>

      {/* ── Constructor ── */}
      {pageTab === 'constructor' && (
        <div className="grid lg:grid-cols-2 gap-6">
          {/* Settings panel */}
          <div className="space-y-4">

            {/* Appearance */}
            <div className="card p-5 space-y-4">
              <h3 className="font-semibold text-slate-900 dark:text-slate-100">Внешний вид</h3>
              <div>
                <label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1.5">
                  Название отеля в виджете
                </label>
                <input
                  type="text"
                  className="input"
                  value={settings.hotelName}
                  onChange={e => set('hotelName', e.target.value)}
                  placeholder="Grand Palace Hotel"
                />
              </div>
              <div>
                <label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">
                  Основной цвет
                </label>
                <div className="flex flex-wrap gap-2">
                  {COLORS.map(c => (
                    <button
                      key={c.value}
                      onClick={() => set('primaryColor', c.value)}
                      title={c.label}
                      className={cn(
                        'w-8 h-8 rounded-full border-2 transition-transform',
                        settings.primaryColor === c.value ? 'border-slate-900 dark:border-slate-100 scale-110' : 'border-transparent',
                      )}
                      style={{ background: c.value }}
                    />
                  ))}
                  <div className="flex items-center gap-2">
                    <input
                      type="color"
                      value={settings.primaryColor}
                      onChange={e => set('primaryColor', e.target.value)}
                      className="w-8 h-8 rounded-full cursor-pointer border-0 p-0 bg-transparent"
                    />
                    <span className="text-xs text-slate-500 font-mono">{settings.primaryColor}</span>
                  </div>
                </div>
              </div>
              <div>
                <label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1.5">Язык</label>
                <div className="flex gap-2">
                  {([['ru', '🇷🇺 Русский'], ['en', '🇬🇧 English']] as const).map(([k, l]) => (
                    <button
                      key={k}
                      onClick={() => set('language', k)}
                      className={cn(
                        'px-3 py-1.5 rounded-lg text-sm font-medium border transition-colors',
                        settings.language === k
                          ? 'bg-brand-600 text-white border-brand-600'
                          : 'bg-white dark:bg-slate-700 border-slate-200 dark:border-slate-600 text-slate-700 dark:text-slate-300',
                      )}
                    >
                      {l}
                    </button>
                  ))}
                </div>
              </div>
            </div>

            {/* What to show */}
            <div className="card p-5 space-y-4">
              <h3 className="font-semibold text-slate-900 dark:text-slate-100">Что показывать</h3>
              <div className="space-y-2.5">
                <label className="flex items-center justify-between">
                  <div className="flex items-center gap-2 text-sm text-slate-700 dark:text-slate-300">
                    <CalendarCheck2 size={15} className="text-indigo-500" />
                    Бронирование номеров
                  </div>
                  <input type="checkbox" checked={settings.showRooms} onChange={e => set('showRooms', e.target.checked)} className="rounded" />
                </label>
                {settings.showRooms && (
                  <div className="ml-5 pl-3 border-l-2 border-slate-200 dark:border-slate-600">
                    <p className="text-xs text-slate-500 dark:text-slate-400 mb-1.5">Показывать по:</p>
                    <div className="flex gap-2">
                      {([['rooms', 'Номерам'], ['categories', 'Категориям']] as const).map(([k, l]) => (
                        <button
                          key={k}
                          onClick={() => set('roomDisplayMode', k)}
                          className={cn(
                            'px-2.5 py-1 text-xs rounded-lg border transition-colors',
                            settings.roomDisplayMode === k
                              ? 'bg-brand-600 text-white border-brand-600'
                              : 'bg-white dark:bg-slate-700 border-slate-200 dark:border-slate-600 text-slate-600 dark:text-slate-300',
                          )}
                        >
                          {l}
                        </button>
                      ))}
                    </div>
                  </div>
                )}
                {rentalActive && (
                  <label className="flex items-center justify-between">
                    <div className="flex items-center gap-2 text-sm text-slate-700 dark:text-slate-300">
                      <Dumbbell size={15} className="text-emerald-500" />
                      Аренда объектов
                    </div>
                    <input type="checkbox" checked={settings.showRental} onChange={e => set('showRental', e.target.checked)} className="rounded" />
                  </label>
                )}
                <label className="flex items-center justify-between">
                  <div className="flex items-center gap-2 text-sm text-slate-700 dark:text-slate-300">
                    <Star size={15} className="text-amber-500" />
                    Плашка "Лучшая цена гарантирована"
                  </div>
                  <input type="checkbox" checked={settings.showPromo} onChange={e => set('showPromo', e.target.checked)} className="rounded" />
                </label>
                <label className="flex items-center justify-between">
                  <div className="flex items-center gap-2 text-sm text-slate-700 dark:text-slate-300">
                    <BedDouble size={15} className="text-orange-500" />
                    Дополнительные места (1 500 ₽/ночь)
                  </div>
                  <input type="checkbox" checked={settings.allowExtraBeds} onChange={e => set('allowExtraBeds', e.target.checked)} className="rounded" />
                </label>
                <label className="flex items-center justify-between">
                  <div className="flex items-center gap-2 text-sm text-slate-700 dark:text-slate-300">
                    <Baby size={15} className="text-pink-500" />
                    Количество детей
                  </div>
                  <input type="checkbox" checked={settings.allowChildren} onChange={e => set('allowChildren', e.target.checked)} className="rounded" />
                </label>
              </div>
              <div>
                <label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1.5">
                  Минимальное кол-во ночей
                </label>
                <input
                  type="number" min={1} max={30} className="input w-24"
                  value={settings.minNights}
                  onChange={e => set('minNights', Math.max(1, parseInt(e.target.value) || 1))}
                />
              </div>
              <div>
                <label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1.5">
                  Время ожидания оплаты (минут)
                </label>
                <input
                  type="number" min={5} max={60} className="input w-24"
                  value={settings.paymentTimeout}
                  onChange={e => set('paymentTimeout', Math.max(5, parseInt(e.target.value) || 15))}
                />
                <p className="mt-1 text-xs text-slate-400">По умолчанию 15 мин. Если не оплачено — бронь отменяется.</p>
              </div>
            </div>

            {/* Additional services — from rental objects */}
            <div className="card p-5 space-y-3">
              <div>
                <h3 className="font-semibold text-slate-900 dark:text-slate-100">Дополнительные услуги</h3>
                <p className="text-xs text-slate-500 dark:text-slate-400 mt-0.5">
                  Объекты аренды, доступные гостю при бронировании номера. Управляйте объектами в{' '}
                  <a href={`/${slug}/rental`} className="text-brand-600 hover:underline">модуле аренды</a>.
                </p>
              </div>

              {settings.additionalServices.length === 0 ? (
                <div className="rounded-xl bg-slate-50 dark:bg-slate-700/30 p-4 text-center">
                  <p className="text-sm text-slate-500 dark:text-slate-400">Нет объектов аренды</p>
                  <a href={`/${slug}/rental`} className="text-xs text-brand-600 hover:underline mt-1 inline-block">
                    Добавить в модуле аренды →
                  </a>
                </div>
              ) : (
                <div className="space-y-1">
                  {settings.additionalServices.map(s => (
                    <div key={s.id} className="flex items-center gap-2 px-2 py-1.5 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-700/50">
                      <span className="text-base w-6 text-center">{s.icon}</span>
                      <span className="text-sm text-slate-700 dark:text-slate-300 flex-1">{s.name}</span>
                      <span className="text-xs text-slate-400">{s.price.toLocaleString('ru-RU')} ₽/{s.unit}</span>
                      <button
                        onClick={() => toggleService(s.id)}
                        className={cn('p-1 rounded-lg transition-colors', s.enabled ? 'text-brand-600' : 'text-slate-400')}
                      >
                        {s.enabled ? <ToggleRight size={20} /> : <ToggleLeft size={20} />}
                      </button>
                    </div>
                  ))}
                </div>
              )}
            </div>

            {/* Form fields */}
            <div className="card p-5 space-y-3">
              <h3 className="font-semibold text-slate-900 dark:text-slate-100">Поля формы бронирования</h3>
              <p className="text-xs text-slate-500 dark:text-slate-400">
                Настройте какие поля показывать гостю при бронировании
              </p>
              <div className="space-y-2">
                {settings.formFields.map(field => (
                  <div key={field.id} className={cn('flex items-center gap-2 p-2 rounded-lg', field.enabled ? '' : 'opacity-50')}>
                    <div className="flex-1 min-w-0">
                      <p className="text-sm text-slate-700 dark:text-slate-300">{field.label}</p>
                    </div>
                    <button
                      onClick={() => toggleField(field.id, 'required')}
                      disabled={!field.enabled}
                      className={cn(
                        'text-[10px] px-1.5 py-0.5 rounded font-medium border transition-colors',
                        field.required && field.enabled
                          ? 'bg-red-100 text-red-700 border-red-200 dark:bg-red-900/30 dark:text-red-300 dark:border-red-800'
                          : 'bg-slate-100 text-slate-500 border-slate-200 dark:bg-slate-700 dark:text-slate-400 dark:border-slate-600',
                      )}
                    >
                      {field.required ? 'обяз.' : 'необяз.'}
                    </button>
                    <button
                      onClick={() => toggleField(field.id, 'enabled')}
                      className={cn('p-1 rounded transition-colors', field.enabled ? 'text-brand-600' : 'text-slate-400')}
                    >
                      {field.enabled ? <ToggleRight size={18} /> : <ToggleLeft size={18} />}
                    </button>
                    {field.isCustom && (
                      <button onClick={() => removeCustomField(field.id)} className="p-1 text-slate-400 hover:text-red-500 transition-colors">
                        <Trash2 size={13} />
                      </button>
                    )}
                  </div>
                ))}
              </div>
              {showAddField ? (
                <div className="flex gap-2">
                  <input
                    autoFocus
                    type="text"
                    className="input flex-1 text-sm"
                    placeholder="Название поля"
                    value={newFieldLabel}
                    onChange={e => setNewFieldLabel(e.target.value)}
                    onKeyDown={e => { if (e.key === 'Enter') addCustomField(); if (e.key === 'Escape') setShowAddField(false) }}
                  />
                  <button onClick={addCustomField} disabled={!newFieldLabel.trim()} className="btn-primary px-3 disabled:opacity-50">
                    <Check size={14} />
                  </button>
                  <button onClick={() => setShowAddField(false)} className="btn-secondary px-3">
                    <XIcon size={14} />
                  </button>
                </div>
              ) : (
                <button onClick={() => setShowAddField(true)} className="flex items-center gap-1.5 text-xs text-brand-600 dark:text-brand-400 hover:underline">
                  <Plus size={12} /> Добавить поле
                </button>
              )}
            </div>

            {/* Save button */}
            <div className="flex items-center gap-3">
              <button
                onClick={handleSaveSettings}
                disabled={saving}
                className="btn-primary flex items-center gap-2"
              >
                {saving ? <Loader2 size={15} className="animate-spin" /> : <Save size={15} />}
                Сохранить
              </button>
              {saving && <span className="text-sm text-slate-400">Сохранение...</span>}
              {saved && !saving && <span className="text-sm text-emerald-600 dark:text-emerald-400">✓ Сохранено</span>}
            </div>
          </div>

          {/* Live preview */}
          <div>
            <div className="flex items-center gap-2 mb-3">
              <Eye size={14} className="text-slate-400" />
              <p className="text-sm font-medium text-slate-700 dark:text-slate-300">Предпросмотр виджета</p>
              {gatewayLoading && <Loader2 size={12} className="animate-spin text-slate-400" />}
            </div>

            {/* Gateway status banner */}
            {!gatewayLoading && slug && (
              gateway ? (
                <div className="flex items-center gap-2 mb-3 px-3 py-2 rounded-lg bg-emerald-50 dark:bg-emerald-900/20 border border-emerald-200 dark:border-emerald-700 text-xs text-emerald-700 dark:text-emerald-400">
                  <Zap size={12} className="shrink-0" />
                  Онлайн-оплата активна: <strong>{gateway.label}</strong> ({gateway.currency})
                  · {realRooms.length > 0 ? `${realRooms.length} номеров в превью` : 'данные отеля загружены'}
                </div>
              ) : (
                <div className="flex items-center gap-2 mb-3 px-3 py-2 rounded-lg bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-700 text-xs text-amber-700 dark:text-amber-400">
                  <AlertCircle size={12} className="shrink-0" />
                  Онлайн-оплата не настроена. Добавьте шлюз ЮКасса в{' '}
                  <a href="/settings/payments" className="underline font-medium">Настройки оплаты</a>
                  {' '}и укажите модуль «Онлайн-бронирование».
                </div>
              )
            )}

            <div className="p-6 rounded-2xl bg-slate-100 dark:bg-slate-700/50">
              <WidgetPreview
                settings={settings}
                slug={slug || undefined}
                realRooms={realRooms.length > 0 ? realRooms : undefined}
                realCategories={realCategories.length > 0 ? realCategories : undefined}
                realRentalObjects={realRentalObjects.length > 0 ? realRentalObjects : undefined}
                paymentEnabled={gateway ? gateway.isActive : undefined}
              />
            </div>
            <p className="text-xs text-slate-400 mt-2 text-center">Так виджет будет выглядеть на сайте отеля</p>
          </div>
        </div>
      )}

      {/* ── Code ── */}
      {pageTab === 'code' && (
        <div className="max-w-2xl space-y-5">

          {/* Install mode selector */}
          <div className="card p-5 space-y-4">
            <h3 className="font-semibold text-slate-900 dark:text-slate-100 text-sm">Способ установки</h3>
            <div className="grid grid-cols-3 gap-3">
              {([
                { key: 'iframe',    icon: Code2,        title: 'Встроенный',     desc: 'Вставить блоком на страницу' },
                { key: 'floating',  icon: Zap,          title: 'Плавающая кнопка', desc: 'Кнопка в углу сайта' },
                { key: 'trigger',   icon: Scan,         title: 'По классу',      desc: 'Клик на любой элемент сайта' },
              ] as const).map(m => (
                <button
                  key={m.key}
                  onClick={() => setCodeMode(m.key)}
                  className={cn(
                    'flex flex-col items-center gap-2 p-3 rounded-xl border-2 text-center transition-all',
                    codeMode === m.key
                      ? 'border-brand-500 bg-brand-50 dark:bg-brand-900/10'
                      : 'border-slate-200 dark:border-slate-600 hover:border-slate-300',
                  )}
                >
                  <m.icon size={18} className={codeMode === m.key ? 'text-brand-600' : 'text-slate-400'} />
                  <div>
                    <p className={cn('text-xs font-semibold', codeMode === m.key ? 'text-brand-700 dark:text-brand-400' : 'text-slate-700 dark:text-slate-300')}>{m.title}</p>
                    <p className="text-[10px] text-slate-400 mt-0.5 leading-tight">{m.desc}</p>
                  </div>
                </button>
              ))}
            </div>
          </div>

          {/* Options per mode */}
          {codeMode === 'iframe' && (
            <div className="card p-5 space-y-3">
              <h3 className="font-semibold text-slate-900 dark:text-slate-100 text-sm">Ширина виджета</h3>
              <div className="flex flex-wrap gap-2">
                {[
                  { label: 'Узкий (400px)',      value: '400px' },
                  { label: 'Стандарт (500px)',   value: '500px' },
                  { label: 'Широкий (700px)',    value: '700px' },
                  { label: 'Во всю ширину',      value: '100%' },
                ].map(opt => (
                  <button
                    key={opt.value}
                    onClick={() => setWidgetMaxWidth(opt.value)}
                    className={cn(
                      'px-3 py-1.5 rounded-lg text-xs font-medium border transition-colors',
                      widgetMaxWidth === opt.value
                        ? 'bg-brand-600 text-white border-brand-600'
                        : 'border-slate-200 text-slate-600 hover:border-brand-400 dark:border-slate-600 dark:text-slate-300',
                    )}
                  >
                    {opt.label}
                  </button>
                ))}
                <input
                  value={widgetMaxWidth}
                  onChange={e => setWidgetMaxWidth(e.target.value)}
                  className="w-24 text-xs border border-slate-200 dark:border-slate-600 rounded-lg px-2 py-1.5 bg-white dark:bg-slate-800 text-slate-700 dark:text-slate-300"
                  placeholder="700px"
                />
              </div>
              <p className="text-[11px] text-slate-400">Виджет автоматически отцентрируется на странице</p>
            </div>
          )}

          {codeMode === 'floating' && (
            <div className="card p-5 space-y-3">
              <h3 className="font-semibold text-slate-900 dark:text-slate-100 text-sm">Настройки кнопки</h3>
              <div className="flex items-center gap-3">
                <div className="flex-1">
                  <label className="text-xs text-slate-500 mb-1 block">Текст кнопки</label>
                  <input
                    value={floatBtnText}
                    onChange={e => setFloatBtnText(e.target.value)}
                    className="w-full text-sm border border-slate-200 dark:border-slate-600 rounded-lg px-3 py-1.5 bg-white dark:bg-slate-800"
                    placeholder="Забронировать"
                  />
                </div>
                <div className="shrink-0 mt-4">
                  <button
                    className="px-4 py-2 rounded-full text-sm font-semibold text-white shadow-lg"
                    style={{ background: settings.primaryColor }}
                  >
                    {floatBtnText || 'Забронировать'}
                  </button>
                </div>
              </div>
              <p className="text-[11px] text-slate-400">Кнопка появится в правом нижнем углу сайта. Цвет берётся из настроек виджета.</p>
            </div>
          )}

          {codeMode === 'trigger' && (
            <div className="card p-5 space-y-3">
              <h3 className="font-semibold text-slate-900 dark:text-slate-100 text-sm">CSS-класс триггера</h3>
              <div className="flex items-center gap-2">
                <span className="text-sm text-slate-400">.</span>
                <input
                  value={triggerClass}
                  onChange={e => setTriggerClass(e.target.value.replace(/[^a-z0-9-_]/gi, ''))}
                  className="flex-1 text-sm border border-slate-200 dark:border-slate-600 rounded-lg px-3 py-1.5 bg-white dark:bg-slate-800 font-mono"
                  placeholder="hotelsync-book"
                />
              </div>
              <p className="text-[11px] text-slate-400">
                Добавьте этот класс любой кнопке или ссылке на сайте — при клике откроется виджет:
              </p>
              <pre className="bg-slate-900 text-emerald-400 text-xs rounded-lg p-3 font-mono">{`<button class="${triggerClass || 'hotelsync-book'}">Забронировать номер</button>`}</pre>
            </div>
          )}

          {/* Code block */}
          <div className="card p-5 space-y-3">
            <div className="flex items-center justify-between">
              <div className="flex items-center gap-2">
                <Code2 size={16} className="text-indigo-500" />
                <h3 className="font-semibold text-slate-900 dark:text-slate-100 text-sm">
                  {codeMode === 'iframe' ? 'Код для вставки' : codeMode === 'floating' ? 'Скрипт плавающей кнопки' : 'Скрипт триггера по классу'}
                </h3>
              </div>
              <button
                onClick={copyCode}
                className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg border border-slate-200 dark:border-slate-600 text-xs font-medium text-slate-700 dark:text-slate-300 hover:border-brand-400 transition-colors"
              >
                {copied ? <CheckCheck size={12} className="text-emerald-600" /> : <Copy size={12} />}
                {copied ? 'Скопировано' : 'Копировать'}
              </button>
            </div>
            <pre className="bg-slate-900 text-emerald-400 text-xs rounded-xl p-4 overflow-x-auto font-mono leading-relaxed whitespace-pre-wrap break-all">
              {activeSnippet}
            </pre>
            <p className="text-[11px] text-slate-400">
              {codeMode === 'iframe'
                ? 'Вставьте в любое место страницы где должен отображаться виджет.'
                : 'Вставьте перед закрывающим тегом </body>.'}
            </p>
          </div>

          <div className="grid grid-cols-3 gap-3">
            {[
              { icon: CalendarCheck2, title: 'Мгновенное подтверждение', desc: 'Email гостю' },
              { icon: CreditCard,     title: 'Онлайн-оплата',            desc: 'ЮKassa, Тинькофф, СБП' },
              { icon: Globe,          title: 'Без комиссии OTA',          desc: 'Только ~1.5% платёжной комиссии' },
            ].map(f => (
              <div key={f.title} className="card p-4 text-center">
                <f.icon size={22} className="text-indigo-500 mx-auto mb-2" />
                <p className="font-medium text-slate-900 dark:text-slate-100 text-sm">{f.title}</p>
                <p className="text-xs text-slate-400 mt-0.5">{f.desc}</p>
              </div>
            ))}
          </div>
        </div>
      )}

      {/* ── Stats ── */}
      {pageTab === 'stats' && (
        <div className="max-w-2xl">
          <div className="grid grid-cols-3 gap-3 mb-5">
            {[
              { label: 'Бронирований через виджет', value: '—', sub: 'нет данных' },
              { label: 'Конверсия посетителей',      value: '—', sub: 'нет данных' },
              { label: 'Прямая выручка',             value: '—', sub: 'нет данных' },
            ].map(s => (
              <div key={s.label} className="card p-4 text-center">
                <p className="text-2xl font-bold text-slate-400">{s.value}</p>
                <p className="text-xs text-slate-500 dark:text-slate-400 mt-1 leading-tight">{s.label}</p>
              </div>
            ))}
          </div>
          <div className="card p-6 text-center">
            <Waves size={40} className="mx-auto mb-3 text-slate-300" />
            <p className="font-semibold text-slate-700 dark:text-slate-300">Статистика появится после установки виджета</p>
            <p className="text-sm text-slate-500 dark:text-slate-400 mt-1">
              Разместите виджет на сайте и подключите к нему первые бронирования
            </p>
            <button onClick={() => setPageTab('code')} className="btn-primary mt-4">
              <ArrowRight size={14} />
              Получить код установки
            </button>
          </div>
        </div>
      )}
    </div>
  )
}
