
import * as React from 'react';
import './index.css';
import confetti from 'canvas-confetti';
import FormField from './components/FormField.tsx';
import SelectField from './components/SelectField.tsx';
import { Button } from './components/ui/button.tsx';
// import AdminPage from './components/AdminPage.tsx'; // Disabled for public view
import { FormDataModel, ApiPostPayload, SubmissionState, N8nApiResponse, Brand, HotelUnit, ExtraItem } from './types.ts';
import { submitReservation, checkPaymentStatus } from './services/apiService.ts';
import { suiteService } from './services/suiteService.ts';
import { hotelUnitService } from './services/hotelUnitService.ts';
import { brandService } from './services/brandService.ts';
import { pricingService } from './services/pricingService.ts';
import { extraService } from './services/extraService.ts';

const MODO_FIXED = 0;

const SuccessIcon: React.FC<{ className?: string }> = ({ className }) => (
  <svg className={className} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={2} stroke="currentColor">
    <path strokeLinecap="round" strokeLinejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
  </svg>
);

const ErrorIcon: React.FC<{ className?: string }> = ({ className }) => (
  <svg className={className} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={2} stroke="currentColor">
    <path strokeLinecap="round" strokeLinejoin="round" d="M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z" />
  </svg>
);

type SelectOption = { value: string; label: string };

const App: React.FC = () => {
  const [currentView, setCurrentView] = React.useState<'reservation' | 'admin'>('reservation');
  const [view, setView] = React.useState<'form' | 'payment' | 'success' | 'expired'>('form');
  const [isDataLoading, setIsDataLoading] = React.useState(true);

  // Configuração de Título e Subtítulo (Persistência Local)
  const [appConfig, setAppConfig] = React.useState({
    title: 'Reserva Premium',
    subtitle: 'Hotel 1001 Noites Prime'
  });

  React.useEffect(() => {
    const savedConfig = localStorage.getItem('hotelAppConfig');
    if (savedConfig) {
      try {
        setAppConfig(JSON.parse(savedConfig));
      } catch (e) {
        console.error("Erro ao carregar configurações", e);
      }
    }
  }, []);

  const handleSaveConfig = (newConfig: { title: string; subtitle: string }) => {
    setAppConfig(newConfig);
    localStorage.setItem('hotelAppConfig', JSON.stringify(newConfig));
  };

  const initialFormData: FormDataModel = {
    nome: '',
    checkInDateTime: '',
    telefone: '',
    email: '',
    cpf: '',
    observacao: '',
    selectedBrand: '',
    selectedUnit: '',
    selectedCategory: '',
    stayDuration: '',
    selectedExtras: [],
  };

  const [formData, setFormData] = React.useState<FormDataModel>(initialFormData);
  const [isLoading, setIsLoading] = React.useState<boolean>(false);
  const [submissionStatus, setSubmissionStatus] = React.useState<SubmissionState | null>(null);
  const [formErrors, setFormErrors] = React.useState<Partial<Record<keyof FormDataModel, string>>>({});
  
  const [brands, setBrands] = React.useState<Brand[]>([]);
  const [units, setUnits] = React.useState<HotelUnit[]>([]);
  
  const [brandOptions, setBrandOptions] = React.useState<SelectOption[]>([]);
  const [unitOptions, setUnitOptions] = React.useState<SelectOption[]>([]);
  const [categoryOptions, setCategoryOptions] = React.useState<SelectOption[]>([]);
  const [durationOptions, setDurationOptions] = React.useState<SelectOption[]>([]);
  
  const [isCopied, setIsCopied] = React.useState(false);
  const [timeLeft, setTimeLeft] = React.useState(10 * 60);
  const [selectedCategoryImageUrls, setSelectedCategoryImageUrls] = React.useState<string[] | null>(null);
  
  const [calculatedPrice, setCalculatedPrice] = React.useState<number | null>(null);
  const [basePrice, setBasePrice] = React.useState<number | null>(null);
  const [isPriceLoading, setIsPriceLoading] = React.useState<boolean>(false);

  // Extras state
  const [availableExtras, setAvailableExtras] = React.useState<ExtraItem[]>([]);


  const txid = submissionStatus?.pix?.txid; // Extract txid for cleaner dependency management

  React.useEffect(() => {
    if (view !== 'payment' || !txid) return;

    const pollInterval = setInterval(async () => {
      try {
        const result = await checkPaymentStatus(txid);
        if (result?.status?.trim().toLowerCase() === 'pago') {
          clearInterval(pollInterval);
          setView('success');
          triggerFireworks();
        }
      } catch (err) {
        console.error("Erro ao verificar pagamento:", err);
      }
    }, 10000); // A cada 10 segundos

    return () => clearInterval(pollInterval);
  }, [txid, view]);

  React.useEffect(() => {
    if (view !== 'payment') return;

    setTimeLeft(10 * 60);
    const timer = setInterval(() => {
      setTimeLeft(prev => {
        if (prev <= 1) {
          clearInterval(timer);
          setView('expired');
          return 0;
        }
        return prev - 1;
      });
    }, 1000); // A cada 1 segundo

    return () => clearInterval(timer);
  }, [view]);

  const triggerFireworks = () => {
      const duration = 3 * 1000;
      const animationEnd = Date.now() + duration;
      const defaults = { startVelocity: 30, spread: 360, ticks: 60, zIndex: 100 };

      const randomInRange = (min: number, max: number) => Math.random() * (max - min) + min;

      const interval = window.setInterval(() => {
          const timeLeft = animationEnd - Date.now();
          if (timeLeft <= 0) return clearInterval(interval);
          const particleCount = 50 * (timeLeft / duration);
          confetti({ ...defaults, particleCount, origin: { x: randomInRange(0.1, 0.3), y: Math.random() - 0.2 } });
          confetti({ ...defaults, particleCount, origin: { x: randomInRange(0.7, 0.9), y: Math.random() - 0.2 } });
      }, 250);
  };

  const formatTime = (seconds: number) => {
    const minutes = Math.floor(seconds / 60);
    const remainingSeconds = seconds % 60;
    return `${String(minutes).padStart(2, '0')}:${String(remainingSeconds).padStart(2, '0')}`;
  };


  const loadInitialData = React.useCallback(async () => {
    setIsDataLoading(true);
    try {
      const allBrands = await brandService.getAllBrands();
      const allUnits = await hotelUnitService.getAllUnits();
      setBrands(allBrands);
      setUnits(allUnits);
      setBrandOptions(allBrands.map(b => ({ value: String(b.id), label: b.name })));
      
      const extras = await extraService.getExtras();
      setAvailableExtras(extras.filter(e => e.active).sort((a, b) => a.order - b.order));
    } catch (error) {
      console.error("Failed to load initial data:", error);
    } finally {
      setIsDataLoading(false);
    }
  }, []);

  React.useEffect(() => {
    if (currentView === 'reservation') {
      loadInitialData();
    }
  }, [currentView, loadInitialData]);

  // Atualiza Unidades e Tipos de Permanência quando a Marca muda
  React.useEffect(() => {
    if (formData.selectedBrand) {
      const brandId = parseInt(formData.selectedBrand, 10);
      const selectedBrand = brands.find(b => b.id === brandId);
      
      if (selectedBrand) {
        setUnitOptions(units.filter(u => u.brandId === brandId).map(u => ({ value: String(u.id), label: u.name })));
        setDurationOptions(selectedBrand.stay_durations.map(d => ({ value: d, label: d })));
      }
    } else {
      setUnitOptions([]);
      setCategoryOptions([]);
      setDurationOptions([]);
    }
  }, [formData.selectedBrand, brands, units]);
  
  // Atualiza Categorias de Suíte quando a Unidade muda
  React.useEffect(() => {
      if (formData.selectedUnit) {
          const unitId = parseInt(formData.selectedUnit, 10);
          const selectedUnit = units.find(u => u.id === unitId);

          if (selectedUnit?.visible_suite_categories) {
              setCategoryOptions(selectedUnit.visible_suite_categories.map(c => ({ value: c, label: c })));
          } else {
              setCategoryOptions([]); // Limpa se a unidade não tem categorias visíveis configuradas
          }
      } else {
          setCategoryOptions([]); // Limpa se nenhuma unidade está selecionada
      }
  }, [formData.selectedUnit, units]);
  
    // Atualiza a imagem da categoria quando a categoria ou unidade muda
  React.useEffect(() => {
    if (formData.selectedUnit && formData.selectedCategory) {
      const unit = units.find(u => String(u.id) === formData.selectedUnit);
      const imageInfo = unit?.suite_category_images?.find(img => img.category === formData.selectedCategory);
      setSelectedCategoryImageUrls(imageInfo?.imageUrls || null);
    } else {
      setSelectedCategoryImageUrls(null);
    }
  }, [formData.selectedCategory, formData.selectedUnit, units]);

  // Efeito para calcular o preço dinamicamente
  React.useEffect(() => {
    const calculatePrice = async () => {
        if (formData.selectedBrand && formData.selectedCategory && formData.stayDuration && formData.checkInDateTime) {
            setIsPriceLoading(true);
            setBasePrice(null);
            setCalculatedPrice(null);
            try {
                const pricingData = await pricingService.getPricingData(parseInt(formData.selectedBrand, 10));
                const dayOfWeek = new Date(formData.checkInDateTime).getDay();
                const dayRange = (dayOfWeek >= 1 && dayOfWeek <= 3) ? "SEGUNDA A QUARTA" : "QUINTA A DOMINGO";
                const price = pricingData?.[dayRange]?.[formData.selectedCategory]?.[formData.stayDuration];
                
                if (price !== undefined && price > 0) {
                    setBasePrice(price);
                } else {
                    setBasePrice(null);
                }
            } catch (error) {
                console.error("Error calculating price:", error);
                setBasePrice(null);
            } finally {
                setIsPriceLoading(false);
            }
        } else {
            setBasePrice(null);
        }
    };

    const debounceTimer = setTimeout(() => {
        calculatePrice();
    }, 300); // Debounce to avoid rapid recalculations

    return () => clearTimeout(debounceTimer);
  }, [formData.selectedBrand, formData.selectedCategory, formData.stayDuration, formData.checkInDateTime]);
  
  // Recalculate total price when Extras change or Base price changes
  React.useEffect(() => {
      if (basePrice !== null) {
          const extrasTotal = formData.selectedExtras.reduce((sum, extraId) => {
              const extra = availableExtras.find(e => e.id === extraId);
              return sum + (extra ? extra.price : 0);
          }, 0);
          setCalculatedPrice(basePrice + extrasTotal);
      } else {
          setCalculatedPrice(null);
      }
  }, [basePrice, formData.selectedExtras, availableExtras]);


  const validateForm = (): boolean => {
    const errors: Partial<Record<keyof FormDataModel, string>> = {};
    if (!formData.nome.trim()) errors.nome = "Nome completo é obrigatório.";
    if (!formData.checkInDateTime) errors.checkInDateTime = "Data e horário do check-in são obrigatórios.";
    else if (new Date(formData.checkInDateTime) <= new Date()) {
        errors.checkInDateTime = "A data de check-in deve ser futura.";
    }
    
    const cleanedTelefone = formData.telefone.replace(/\D/g, '');
    if (!cleanedTelefone || !/^\d{10,11}$/.test(cleanedTelefone)) { 
        errors.telefone = "Telefone inválido (DDD + 8 ou 9 dígitos).";
    }

    if (!formData.email.trim() || !/\S+@\S+\.\S+/.test(formData.email)) errors.email = "Formato de e-mail inválido.";

    const cleanedCpf = formData.cpf.replace(/\D/g, '');
    if (!formData.cpf.trim() || !/^\d{11}$/.test(cleanedCpf)) errors.cpf = "CPF inválido (11 dígitos).";

    if (!formData.selectedBrand) errors.selectedBrand = "Seleção de marca é obrigatória.";
    if (!formData.selectedUnit) errors.selectedUnit = "Seleção de unidade é obrigatória.";
    if (!formData.selectedCategory) errors.selectedCategory = "Seleção de categoria é obrigatória.";
    if (!formData.stayDuration) errors.stayDuration = "Seleção do tipo de permanência é obrigatória.";

    setFormErrors(errors);
    return Object.keys(errors).length === 0;
  };

  const handleTelefoneChange = (value: string): string => {
    return value.replace(/\D/g, '').replace(/(\d{2})(\d{1,5})(\d{4})/, '($1)$2-$3');
  };

  const handleChange = React.useCallback((e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {
    const { name, value } = e.target;

    if (name === 'selectedBrand') {
        setFormData(prev => ({ ...prev, selectedBrand: value, selectedUnit: '', selectedCategory: '', stayDuration: '' }));
    } else if (name === 'selectedUnit') {
        setFormData(prev => ({ ...prev, selectedUnit: value, selectedCategory: '' }));
    } else if (name === 'telefone') {
      setFormData(prev => ({ ...prev, telefone: handleTelefoneChange(value) }));
    } else {
      setFormData(prev => ({ ...prev, [name]: value }));
    }
    
    if (formErrors[name as keyof FormDataModel]) {
        setFormErrors(prev => ({ ...prev, [name]: undefined }));
    }
  }, [formErrors]);

  const toggleExtra = (extra: ExtraItem) => {
    setFormData(prev => {
        const isSelected = prev.selectedExtras.includes(extra.id);
        const newExtras = isSelected
            ? prev.selectedExtras.filter(id => id !== extra.id)
            : [...prev.selectedExtras, extra.id];
        return { ...prev, selectedExtras: newExtras };
    });
  };

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    setSubmissionStatus(null);
    if (!validateForm()) {
        setSubmissionStatus({ message: "Por favor, corrija os campos destacados.", type: 'error' });
        return;
    }

    if (calculatedPrice === null || calculatedPrice <= 0) {
      setSubmissionStatus({ message: "Não foi possível calcular o preço. Verifique se todas as opções de reserva estão preenchidas corretamente.", type: 'error' });
      return;
    }

    setIsLoading(true);
    try {
        const price = calculatedPrice;

        const selectedUnitId = parseInt(formData.selectedUnit, 10);
        if (isNaN(selectedUnitId)) {
            throw new Error("Unidade do hotel inválida selecionada.");
        }

        const selectedSuiteApiId = await suiteService.getRandomSuiteApiIdFromCategory(formData.selectedCategory, selectedUnitId);
        if (selectedSuiteApiId === null) {
          throw new Error("Nenhuma suíte disponível para a categoria e unidade selecionadas.");
        }
    
        const cleanedCpf = formData.cpf.replace(/\D/g, '');
        const cleanedTelefone = formData.telefone.replace(/\D/g, '');
        const integracaoId = `reserva-${cleanedCpf.substring(0, 9)}-${Date.now().toString().slice(-6)}`;
        const selectedBrandName = brands.find(b => b.id === parseInt(formData.selectedBrand, 10))?.name || '';
        const selectedUnitName = units.find(u => u.id === parseInt(formData.selectedUnit, 10))?.name || '';
        
        const selectedExtrasObjects = availableExtras.filter(e => formData.selectedExtras.includes(e.id));
    
        const apiPayload: ApiPostPayload = {
          account_id: 1, // TODO: Dynamic
          brand_id: parseInt(formData.selectedBrand, 10),
          unit_id: parseInt(formData.selectedUnit, 10),
          suite_id: selectedSuiteApiId,
          data_inicio: new Date(formData.checkInDateTime).toISOString(),
          nome: formData.nome,
          telefone: cleanedTelefone,
          email: formData.email,
          cpf: cleanedCpf,
          integracao_id: integracaoId,
          modo: MODO_FIXED,
          marca: selectedBrandName,
          unidade: selectedUnitName,
          categoria: formData.selectedCategory,
          permanencia: formData.stayDuration,
          valor: price / 2, // Envia apenas 50% do valor para o pagamento PIX
          observacoes: formData.observacao.trim(),
          extras_selecionados: selectedExtrasObjects
        };

        const apiResponse = await submitReservation(apiPayload);
        
        setSubmissionStatus({
            message: 'Sua reserva foi iniciada! Realize o pagamento via Pix para confirmar.',
            type: 'success',
            pix: {
                qrCodeValue: apiResponse.pixUrl,
                copyPasteCode: apiResponse.pixCopiaECola,
                txid: apiResponse.txid,
            }
        });
        setView('payment');
    } catch (error) {
      const detailedErrorMessage = error instanceof Error ? error.message : "Houve um problema desconhecido.";
      setSubmissionStatus({
        message: `Falha na solicitação: ${detailedErrorMessage}`,
        type: 'error'
      });
      console.error("API Submission Error:", error);
    } finally {
      setIsLoading(false);
    }
  };
  
  const handleCopyPix = () => {
    if (submissionStatus?.pix?.copyPasteCode) {
      navigator.clipboard.writeText(submissionStatus.pix.copyPasteCode);
      setIsCopied(true);
      setTimeout(() => setIsCopied(false), 2000);
    }
  };

  const handleResetForm = () => {
    setFormData(initialFormData);
    setSubmissionStatus(null);
    setFormErrors({});
    setIsLoading(false);
    setView('form');
  };
  
  const handleNavigateToReservation = () => {
    setCurrentView('reservation');
  };

  // Admin logic removed for public facing apps.
  // if (currentView === 'admin') { ... }

  const renderContent = () => {
    switch (view) {
        case 'success':
            return (
                <div className="text-center space-y-6 p-10 bg-[#F8FAFC] border border-[#1B3B5F]/10 rounded-3xl shadow-inner animate-fade-in">
                    <div className="mx-auto w-24 h-24 bg-green-100 rounded-full flex items-center justify-center mb-6 shadow-md">
                        <SuccessIcon className="h-12 w-12 text-green-600" />
                    </div>
                    <h2 className="text-3xl font-extrabold text-[#1B3B5F]">Pagamento Confirmado!</h2>
                    <p className="text-[#9CA3AF] text-lg">Sua reserva está 100% garantida.<br/>Enviamos os detalhes para o seu e-mail.</p>
                    <div className="pt-6">
                        <Button onClick={handleResetForm} variant="outline" className="w-full">
                            Fazer Nova Reserva
                        </Button>
                    </div>
                </div>
            );
        case 'expired':
             return (
                <div className="text-center space-y-6 p-10 bg-red-50 border border-red-100 rounded-3xl shadow-inner animate-fade-in">
                    <div className="mx-auto w-24 h-24 bg-red-100 rounded-full flex items-center justify-center mb-6 shadow-md">
                        <ErrorIcon className="h-12 w-12 text-red-600" />
                    </div>
                    <h2 className="text-3xl font-extrabold text-[#1B3B5F]">Tempo Esgotado</h2>
                    <p className="text-[#9CA3AF] text-lg">O tempo para realizar o pagamento expirou.<br/>Por favor, inicie uma nova reserva.</p>
                    <div className="pt-6">
                         <Button onClick={handleResetForm} variant="outline" className="w-full">
                            Tentar Novamente
                        </Button>
                    </div>
                </div>
            );
        case 'payment':
            return (
                <div className="text-center space-y-6 animate-fade-in">
                    <div className="p-4 bg-[#F8FAFC] rounded-2xl border border-[#1B3B5F]/10 mb-6">
                         <p className="text-[#1B3B5F] font-medium">{submissionStatus?.message}</p>
                    </div>

                    <div className="flex flex-col items-center justify-center space-y-2">
                        <p className="text-xs font-bold text-[#9CA3AF] uppercase tracking-widest">Tempo Restante</p>
                        <div className="text-4xl font-extrabold text-red-500 tabular-nums tracking-tight">
                            {formatTime(timeLeft)}
                        </div>
                    </div>

                    <div className="bg-amber-50 border border-amber-200 p-4 rounded-xl text-amber-800 text-sm flex items-center justify-center gap-2 shadow-sm">
                        <svg className="w-5 h-5 text-amber-500" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" /></svg>
                        <span>Restam apenas <strong className="font-bold">3 suítes</strong> disponíveis — garanta a sua!</span>
                    </div>

                    <div className="pt-4 pb-2 text-left">
                        <label className="block text-xs font-bold text-[#1B3B5F] uppercase tracking-wide mb-2">Código Pix Copia e Cola</label>
                        <div className="relative group">
                            <input
                                type="text"
                                readOnly
                                value={submissionStatus?.pix?.copyPasteCode || ''}
                                className="w-full bg-[#F8FAFC] border-[1.5px] border-[#1B3B5F]/20 rounded-xl p-4 pr-28 text-sm text-[#1B3B5F] font-mono focus:outline-none focus:border-[#1E90FF] focus:ring-2 focus:ring-[#1E90FF]/10 transition-all"
                            />
                            <div className="absolute right-2 top-1/2 -translate-y-1/2">
                                <Button onClick={handleCopyPix} size="sm" variant={isCopied ? "default" : "secondary"}>
                                    {isCopied ? 'Copiado!' : 'Copiar'}
                                </Button>
                            </div>
                        </div>
                    </div>
                    
                    <div className="pt-4 border-t border-[#1B3B5F]/10">
                        <Button onClick={handleResetForm} variant="ghost" className="w-full text-[#9CA3AF] hover:text-[#1B3B5F]">
                            Cancelar e Voltar
                        </Button>
                    </div>
                </div>
            );
        case 'form':
        default:
            return (
                <>
                    <div className="sm:hidden flex justify-center mb-8"> 
                        <Button onClick={() => setCurrentView('admin')} variant="secondary" size="sm" className="rounded-full px-6"> 
                            Painel Admin 
                        </Button> 
                    </div>
                    
                    {isDataLoading ? (
                      <div className="text-center py-20 flex flex-col items-center justify-center space-y-4">
                          <div className="w-8 h-8 border-4 border-[#1E90FF] border-t-transparent rounded-full animate-spin"></div>
                          <p className="text-[#9CA3AF] font-medium animate-pulse">Carregando dados...</p>
                      </div>
                    ) : (
                      <form onSubmit={handleSubmit} noValidate className="space-y-2">
                          <div className="bg-[#F8FAFC] p-6 rounded-2xl border border-[#1B3B5F]/10 mb-8 shadow-sm">
                              <h3 className="text-[#1B3B5F] font-bold text-sm uppercase tracking-wider mb-4 border-b border-[#1B3B5F]/10 pb-2">Detalhes da Estadia</h3>
                              <div className="grid grid-cols-1 gap-1">
                                  <SelectField id="selectedBrand" name="selectedBrand" label="Marca" value={formData.selectedBrand} onChange={handleChange} options={brandOptions} required placeholder="Selecione a marca" disabled={brandOptions.length === 0} instruction={brandOptions.length === 0 ? "Nenhuma marca disponível." : ""} error={!!formErrors.selectedBrand} />
                                  
                                  <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                                      <SelectField id="selectedUnit" name="selectedUnit" label="Unidade do Hotel" value={formData.selectedUnit} onChange={handleChange} options={unitOptions} required placeholder="Selecione a unidade" disabled={!formData.selectedBrand || unitOptions.length === 0} instruction={!!formData.selectedBrand && unitOptions.length === 0 ? "Nenhuma unidade para esta marca." : ""} error={!!formErrors.selectedUnit} />
                                      <SelectField id="stayDuration" name="stayDuration" label="Permanência" value={formData.stayDuration} onChange={handleChange} options={durationOptions} required placeholder="Selecione o tempo" disabled={!formData.selectedBrand} error={!!formErrors.stayDuration} />
                                  </div>

                                  <SelectField id="selectedCategory" name="selectedCategory" label="Categoria da Suíte" value={formData.selectedCategory} onChange={handleChange} options={categoryOptions} required placeholder="Selecione a categoria" disabled={!formData.selectedUnit || categoryOptions.length === 0} instruction={!!formData.selectedUnit && categoryOptions.length === 0 ? "Nenhuma categoria disponível para esta unidade." : ""} error={!!formErrors.selectedCategory} />
                                  
                                  <FormField id="checkInDateTime" name="checkInDateTime" label="Data e Horário do Check-in" type="datetime-local" value={formData.checkInDateTime} onChange={handleChange} required error={!!formErrors.checkInDateTime} />
                              </div>
                          </div>
                          
                          {selectedCategoryImageUrls && selectedCategoryImageUrls.length > 0 && (
                            <div className="mb-8 animate-fade-in grid grid-cols-1 sm:grid-cols-2 gap-4">
                                {selectedCategoryImageUrls.map((url, index) => (
                                    url && (
                                      <a href={url} target="_blank" rel="noopener noreferrer" key={index} className="block group relative overflow-hidden rounded-2xl shadow-md hover:shadow-xl transition-all duration-300">
                                        <div className="absolute inset-0 bg-[#0A1A2F]/20 group-hover:bg-transparent transition-colors z-10" />
                                        <img 
                                            src={url} 
                                            alt={`Imagem ${index + 1}`}
                                            className="w-full h-48 object-cover transform group-hover:scale-110 transition-transform duration-700 ease-out" 
                                        />
                                      </a>
                                    )
                                ))}
                            </div>
                          )}

                          {/* Seção de Extras */}
                          {basePrice !== null && availableExtras.length > 0 && (
                              <div className="mb-8 animate-fade-in">
                                  <h3 className="text-[#1B3B5F] font-bold text-sm uppercase tracking-wider mb-2">Adicione algo especial à sua experiência</h3>
                                  <div className="grid grid-cols-1 gap-4 mt-4">
                                      {availableExtras.map(extra => {
                                          const isSelected = formData.selectedExtras.includes(extra.id);
                                          return (
                                              <div
                                                  key={extra.id}
                                                  onClick={() => toggleExtra(extra)}
                                                  className={`
                                                    cursor-pointer transition-all duration-200
                                                    p-4 rounded-2xl shadow-md
                                                    border ${isSelected ? 'border-[#1E90FF] shadow-[0_0_15px_#1E90FF55]' : 'border-[#1B3B5F]'}
                                                    bg-[#0A1A2F]/80 backdrop-blur-sm
                                                    hover:scale-[1.02] hover:border-[#1E90FF]
                                                  `}
                                              >
                                                  {extra.image && <img src={extra.image} className="rounded-xl w-full h-40 object-cover mb-3" alt={extra.title} />}

                                                  <div className="flex justify-between items-start">
                                                      <h3 className="text-white font-semibold text-lg">{extra.title}</h3>

                                                      {extra.tag && (
                                                          <span className="px-3 py-1 text-xs rounded-full bg-[#1E90FF] text-white">
                                                              {extra.tag}
                                                          </span>
                                                      )}
                                                  </div>

                                                  <p className="text-gray-300 text-sm mt-1">{extra.description}</p>

                                                  <div className="mt-3 text-[#1E90FF] font-bold text-xl">
                                                      {new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(extra.price)}
                                                  </div>
                                              </div>
                                          );
                                      })}
                                  </div>
                              </div>
                          )}

                          <div className="my-8">
                            {isPriceLoading && (
                                <div className="text-center p-6 bg-[#F8FAFC] rounded-2xl border border-[#1B3B5F]/10">
                                    <div className="w-6 h-6 border-2 border-[#1E90FF] border-t-transparent rounded-full animate-spin mx-auto mb-2"></div>
                                    <p className="text-sm text-[#9CA3AF]">Calculando valor...</p>
                                </div>
                            )}
                            {!isPriceLoading && calculatedPrice !== null && (
                                <div className="relative overflow-hidden p-6 bg-[#F8FAFC] border-[1.5px] border-[#1E90FF]/20 rounded-2xl animate-fade-in shadow-lg shadow-[#1E90FF]/5">
                                    <div className="absolute top-0 right-0 bg-[#1E90FF] text-white text-[10px] font-bold px-3 py-1 rounded-bl-lg">PREÇO ESTIMADO</div>
                                    
                                    <div className="space-y-4">
                                        <div className="flex justify-between items-center text-sm text-[#1B3B5F]">
                                            <span className="font-medium">Valor Total da Reserva</span>
                                            <span className="font-bold text-lg">{new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(calculatedPrice)}</span>
                                        </div>
                                        {formData.selectedExtras.length > 0 && (
                                            <div className="flex justify-between items-center text-xs text-[#9CA3AF]">
                                                <span>(Suíte + Extras)</span>
                                            </div>
                                        )}
                                        <div className="flex justify-between items-center text-sm text-[#9CA3AF]">
                                            <span>Pagar no check-in</span>
                                            <span className="font-medium">{new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(calculatedPrice / 2)}</span>
                                        </div>
                                        <div className="pt-4 border-t border-[#1B3B5F]/10 flex justify-between items-end">
                                            <div>
                                                <p className="text-xs font-bold text-[#1E90FF] uppercase tracking-wider mb-1">Entrada via Pix (50%)</p>
                                                <p className="text-[#9CA3AF] text-xs">Necessário para confirmar</p>
                                            </div>
                                            <span className="text-3xl font-extrabold text-[#1B3B5F] tracking-tight">
                                                {new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(calculatedPrice / 2)}
                                            </span>
                                        </div>
                                    </div>
                                </div>
                            )}
                          </div>
                          
                          <div className="bg-[#F8FAFC] p-6 rounded-2xl border border-[#1B3B5F]/10 mb-8 shadow-sm">
                              <h3 className="text-[#1B3B5F] font-bold text-sm uppercase tracking-wider mb-4 border-b border-[#1B3B5F]/10 pb-2">Seus Dados</h3>
                              <div className="space-y-1">
                                  <FormField id="nome" name="nome" label="Nome Completo" value={formData.nome} onChange={handleChange} required placeholder="Como no documento" autoComplete="name" error={!!formErrors.nome} />
                                  
                                  <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                                      <FormField id="telefone" name="telefone" label="Telefone / WhatsApp" type="tel" value={formData.telefone} onChange={handleChange} required placeholder="(99) 99999-9999" autoComplete="tel" error={!!formErrors.telefone} />
                                      <FormField id="cpf" name="cpf" label="CPF" type="text" value={formData.cpf} onChange={handleChange} required placeholder="Apenas números" autoComplete="off" error={!!formErrors.cpf} />
                                  </div>

                                  <FormField id="email" name="email" label="E-mail" type="email" value={formData.email} onChange={handleChange} required placeholder="seu@email.com" autoComplete="email" error={!!formErrors.email} />
                                  
                                  <FormField id="observacao" name="observacao" label="Observação (Opcional)" fieldType="textarea" value={formData.observacao} onChange={handleChange} placeholder="Alguma preferência especial?" rows={2} />
                              </div>
                          </div>

                          {submissionStatus?.type === 'error' && (
                              <div className="p-4 mb-6 rounded-xl text-sm flex items-center bg-red-50 text-red-700 border border-red-100" role="alert">
                                <ErrorIcon className="h-5 w-5 mr-3 flex-shrink-0" />
                                {submissionStatus.message}
                              </div>
                          )}

                          <Button type="submit" isLoading={isLoading} disabled={isLoading || isDataLoading} size="lg" className="w-full text-lg shadow-xl shadow-[#1E90FF]/30 hover:shadow-[#1E90FF]/50 transition-all duration-300">
                              {isLoading ? 'Processando...' : 'Confirmar e Pagar Reserva'}
                          </Button>
                      </form>
                    )}
                </>
            );
    }
  };

  return (
    <div className="min-h-screen py-10 px-4 sm:px-6 lg:px-8 flex flex-col items-center justify-center">
      <div className="w-full max-w-3xl bg-white rounded-[2rem] shadow-2xl overflow-hidden border border-white/10 relative">
        {/* Decorative Top Accent */}
        <div className="absolute top-0 left-0 w-full h-2 bg-gradient-to-r from-[#1B3B5F] to-[#1E90FF]"></div>
        
        <div className="p-8 sm:p-12">
            <div className="flex justify-between items-start mb-10 border-b border-[#1B3B5F]/10 pb-6">
            <div className="space-y-1">
                <h1 className="text-2xl sm:text-3xl font-extrabold text-[#1B3B5F] tracking-tight">
                    {view === 'payment' ? 'Pagamento Seguro' : 
                    view === 'success' ? 'Reserva Confirmada' :
                    view === 'expired' ? 'Tempo Esgotado' :
                    appConfig.title}
                </h1>
                {view === 'form' && <p className="text-[#9CA3AF] text-sm font-medium">{appConfig.subtitle}</p>}
            </div>
            <Button onClick={() => setCurrentView('admin')} variant="outline" size="sm" className="hidden sm:flex rounded-full px-5 text-xs font-bold uppercase tracking-wider hover:bg-[#F8FAFC]">
                Admin
            </Button>
            </div>
            {renderContent()}
        </div>
      </div>
      
      <footer className="text-center text-xs font-medium text-[#1E90FF]/60 mt-8">
        &copy; {new Date().getFullYear()} {appConfig.title} &bull; Experiência Exclusiva
      </footer>
    </div>
  );
};

export default App;
