// ============================================================================
// COMPOSANTS UI RÉUTILISABLES
// ============================================================================

const Button = ({ children, onClick, variant = 'primary', className = '', disabled = false, icon = null, id = '' }) => {
    const variants = {
        primary: 'btn-primary text-white',
        secondary: 'bg-gray-200 text-gray-800 hover:bg-gray-300',
        danger: 'bg-red-500 text-white hover:bg-red-600',
        success: 'bg-green-500 text-white hover:bg-green-600'
    };

    return (
        <button
            id={id}
            onClick={onClick}
            disabled={disabled}
            className={`sm-button sm-button-${variant} px-6 py-3 rounded-lg font-semibold ${variants[variant]} ${disabled ? 'opacity-50 cursor-not-allowed' : ''} ${className}`}
        >
            {icon && <i className={`fas ${icon} mr-2`}></i>}
            {children}
        </button>
    );
};

const Input = ({ label, type = 'text', value, onChange, placeholder = '', required = false, icon = null, id = '' }) => {
    const inputId = id || `sm-input-${label?.toLowerCase().replace(/\s+/g, '-')}`;
    
    return (
        <div className="sm-input-group mb-4">
            {label && (
                <label htmlFor={inputId} className="sm-input-label block text-gray-700 font-medium mb-2">
                    {label} {required && <span className="text-red-500">*</span>}
                </label>
            )}
            <div className="sm-input-wrapper relative">
                {icon && (
                    <i className={`sm-input-icon fas ${icon} absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400`}></i>
                )}
                <input
                    id={inputId}
                    type={type}
                    value={value}
                    onChange={(e) => onChange(e.target.value)}
                    placeholder={placeholder}
                    required={required}
                    className={`sm-input w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-transparent ${icon ? 'pl-10' : ''}`}
                />
            </div>
        </div>
    );
};

const Select = ({ label, value, onChange, options, children, required = false, id = '', icon = '' }) => {
    const selectId = id || `sm-select-${label?.toLowerCase().replace(/\s+/g, '-')}`;
    
    return (
        <div className="sm-select-group mb-4">
            {label && (
                <label htmlFor={selectId} className="sm-select-label block text-gray-700 font-medium mb-2">
                    {icon && <i className={`fas ${icon} mr-2`}></i>}
                    {label} {required && <span className="text-red-500">*</span>}
                </label>
            )}
            <select
                id={selectId}
                value={value}
                onChange={(e) => onChange(e.target.value)}
                required={required}
                className="sm-select w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-transparent"
            >
                {options ? (
                    options.map(opt => (
                        <option key={opt.value} value={opt.value}>{opt.label}</option>
                    ))
                ) : (
                    children
                )}
            </select>
        </div>
    );
};

const Card = ({ children, className = '', title = null, id = '' }) => {
    return (
        <div id={id} className={`sm-card card p-6 ${className}`}>
            {title && <h3 className="sm-card-title text-xl font-bold mb-4">{title}</h3>}
            <div className="sm-card-content">
                {children}
            </div>
        </div>
    );
};

const Modal = ({ isOpen, onClose, title, children, size = 'md', id = '' }) => {
    // Fermer avec la touche ESC
    useEffect(() => {
        if (!isOpen) return;
        
        const handleEscape = (e) => {
            if (e.key === 'Escape') {
                console.log('🔑 [Modal] Touche ESC détectée, fermeture du modal');
                onClose();
            }
        };
        
        document.addEventListener('keydown', handleEscape);
        return () => document.removeEventListener('keydown', handleEscape);
    }, [isOpen, onClose]);
    
    if (!isOpen) return null;

    const sizes = {
        sm: 'max-w-md',
        md: 'max-w-2xl',
        lg: 'max-w-4xl',
        xl: 'max-w-6xl'
    };

    return (
        <div id={id} className="sm-modal fixed inset-0 z-50 flex items-center justify-center p-4">
            <div className="sm-modal-backdrop modal-backdrop fixed inset-0" onClick={onClose}></div>
            <div className={`sm-modal-content card ${sizes[size]} w-full max-h-[90vh] overflow-y-auto relative z-10 slide-in-up`}>
                <div className="sm-modal-header flex items-center justify-between mb-6">
                    <h2 className="sm-modal-title text-2xl font-bold">{title}</h2>
                    <button onClick={onClose} className="sm-modal-close text-gray-400 hover:text-gray-600">
                        <i className="fas fa-times text-2xl"></i>
                    </button>
                </div>
                <div className="sm-modal-body">
                    {children}
                </div>
            </div>
        </div>
    );
};

const Loader = ({ id = 'sm-loader' }) => (
    <div id={id} className="sm-loader flex items-center justify-center py-12">
        <div className="loader"></div>
    </div>
);

const EmptyState = ({ icon, title, message, action = null, id = 'sm-empty-state' }) => (
    <div id={id} className="sm-empty-state text-center py-12">
        <i className={`sm-empty-icon fas ${icon} text-6xl text-gray-300 mb-4`}></i>
        <h3 className="sm-empty-title text-xl font-semibold text-gray-700 mb-2">{title}</h3>
        <p className="sm-empty-message text-gray-500 mb-6">{message}</p>
        {action && <div className="sm-empty-action">{action}</div>}
    </div>
);

// ============================================================================
// PAGE DE LOGIN
// ============================================================================

const LoginPage = () => {
    const { login, register } = useAuth();
    const toast = useToast();
    const [isLogin, setIsLogin] = useState(true);
    const [loading, setLoading] = useState(false);

    // Formulaire de login
    const [loginEmail, setLoginEmail] = useState('');
    const [loginPassword, setLoginPassword] = useState('');

    // Formulaire de register
    const [regCompany, setRegCompany] = useState('');
    const [regContact, setRegContact] = useState('');
    const [regEmail, setRegEmail] = useState('');
    const [regPassword, setRegPassword] = useState('');
    const [regPhone, setRegPhone] = useState('');
    const [regAddress, setRegAddress] = useState('');

    const handleLogin = async (e) => {
        e.preventDefault();
        setLoading(true);

        const result = await login(loginEmail, loginPassword);

        if (result.success) {
            toast.success('Connexion réussie !');
        } else {
            toast.error(result.error || 'Erreur de connexion');
        }

        setLoading(false);
    };

    const handleRegister = async (e) => {
        e.preventDefault();
        setLoading(true);

        const result = await register({
            company_name: regCompany,
            contact_name: regContact,
            email: regEmail,
            password: regPassword,
            phone: regPhone,
            address: regAddress
        });

        if (result.success) {
            toast.success('Compte créé avec succès ! Vous pouvez maintenant vous connecter.');
            setIsLogin(true);
            // Pré-remplir l'email
            setLoginEmail(regEmail);
        } else {
            toast.error(result.error || 'Erreur lors de la création du compte');
        }

        setLoading(false);
    };

    return (
        <div id="sm-login-page" className="sm-login-page min-h-screen bg-gradient-to-br from-orange-500 to-red-600 flex items-center justify-center p-4">
            <div id="sm-login-card" className="sm-login-card card max-w-md w-full p-8 fade-in">
                {/* Logo */}
                <div id="sm-login-header" className="sm-login-header text-center mb-8">
                    <div className="sm-login-logo text-5xl mb-4">
                        <i className="fas fa-tv text-orange-600"></i>
                    </div>
                    <h1 className="sm-login-title text-3xl font-bold text-gray-800">SmartScreen Manager</h1>
                    <p className="sm-login-subtitle text-gray-600 mt-2">Gérez vos écrans d'affichage dynamique</p>
                </div>

                {/* Tabs */}
                <div id="sm-login-tabs" className="sm-login-tabs flex mb-6 bg-gray-100 rounded-lg p-1">
                    <button
                        id="sm-tab-login"
                        onClick={() => setIsLogin(true)}
                        className={`sm-tab sm-tab-login flex-1 py-2 rounded-md font-semibold transition-all ${isLogin ? 'bg-white shadow' : 'text-gray-600'}`}
                    >
                        Connexion
                    </button>
                    <button
                        id="sm-tab-register"
                        onClick={() => setIsLogin(false)}
                        className={`sm-tab sm-tab-register flex-1 py-2 rounded-md font-semibold transition-all ${!isLogin ? 'bg-white shadow' : 'text-gray-600'}`}
                    >
                        Inscription
                    </button>
                </div>

                {/* Formulaire de connexion */}
                {isLogin ? (
                    <form id="sm-login-form" className="sm-login-form" onSubmit={handleLogin}>
                        <Input
                            id="sm-login-email"
                            label="Email"
                            type="email"
                            value={loginEmail}
                            onChange={setLoginEmail}
                            placeholder="contact@entreprise.ch"
                            required
                            icon="fa-envelope"
                        />
                        <Input
                            id="sm-login-password"
                            label="Mot de passe"
                            type="password"
                            value={loginPassword}
                            onChange={setLoginPassword}
                            placeholder="••••••••"
                            required
                            icon="fa-lock"
                        />
                        <Button
                            id="sm-login-submit"
                            variant="primary"
                            className="w-full mt-6"
                            disabled={loading}
                        >
                            {loading ? 'Connexion...' : 'Se connecter'}
                        </Button>
                    </form>
                ) : (
                    // Formulaire d'inscription
                    <form id="sm-register-form" className="sm-register-form max-h-[500px] overflow-y-auto pr-2" onSubmit={handleRegister}>
                        <Input
                            label="Nom de l'entreprise"
                            value={regCompany}
                            onChange={setRegCompany}
                            placeholder="Ma Société SA"
                            required
                            icon="fa-building"
                        />
                        <Input
                            label="Nom du contact"
                            value={regContact}
                            onChange={setRegContact}
                            placeholder="Jean Dupont"
                            required
                            icon="fa-user"
                        />
                        <Input
                            label="Email"
                            type="email"
                            value={regEmail}
                            onChange={setRegEmail}
                            placeholder="contact@entreprise.ch"
                            required
                            icon="fa-envelope"
                        />
                        <Input
                            label="Téléphone"
                            type="tel"
                            value={regPhone}
                            onChange={setRegPhone}
                            placeholder="+41 22 123 45 67"
                            icon="fa-phone"
                        />
                        <Input
                            label="Adresse"
                            value={regAddress}
                            onChange={setRegAddress}
                            placeholder="Rue Test 1, 1200 Genève"
                            icon="fa-map-marker-alt"
                        />
                        <Input
                            label="Mot de passe"
                            type="password"
                            value={regPassword}
                            onChange={setRegPassword}
                            placeholder="Minimum 8 caractères"
                            required
                            icon="fa-lock"
                        />
                        <Button
                            variant="primary"
                            className="w-full mt-6"
                            disabled={loading}
                        >
                            {loading ? 'Création...' : 'Créer mon compte'}
                        </Button>
                    </form>
                )}

                {/* Compte de test */}
                <div className="mt-6 p-4 bg-blue-50 rounded-lg">
                    <p className="text-sm text-blue-800 font-medium mb-2">
                        <i className="fas fa-info-circle mr-2"></i>
                        Compte de test
                    </p>
                    <p className="text-xs text-blue-600">
                        Email : admin@livit.ch<br />
                        Password : password
                    </p>
                </div>
            </div>
        </div>
    );
};

// ============================================================================
// COMPOSANT SIDEBAR
// ============================================================================

const Sidebar = ({ currentView, onViewChange }) => {
    const { customer, logout } = useAuth();

    const menuItems = [
        { id: 'dashboard', icon: 'fa-home', label: 'Dashboard' },
        { id: 'configurations', icon: 'fa-cog', label: 'Configurations' },
        { id: 'screens', icon: 'fa-tv', label: 'Écrans' },
        { id: 'advertisings', icon: 'fa-image', label: 'Publicités' },
        { id: 'news', icon: 'fa-exclamation-triangle', label: 'Alertes' },
        { id: 'sliders', icon: 'fa-align-left', label: 'Messages' },
        { id: 'numbers', icon: 'fa-phone', label: 'Contacts' },
        { id: 'real_estate', icon: 'fa-building', label: 'Immobilier' },
        { id: 'concierges', icon: 'fa-key', label: 'Concierges' },
        { id: 'map', icon: 'fa-map-marked-alt', label: 'Carte' },
        { id: 'settings', icon: 'fa-user-cog', label: 'Paramètres' },
    ];

    return (
        <div id="sm-sidebar" className="sm-sidebar w-64 bg-white h-screen shadow-lg flex flex-col">
            {/* Logo */}
            <div id="sm-sidebar-header" className="sm-sidebar-header p-6 border-b">
                <h2 className="sm-sidebar-title text-2xl font-bold text-gray-800">Smart-Hall</h2>
                <p className="sm-sidebar-company text-sm text-gray-600 mt-1">{customer?.company_name}</p>
            </div>

            {/* Menu */}
            <nav id="sm-sidebar-nav" className="sm-sidebar-nav flex-1 p-4 overflow-y-auto">
                {menuItems.map(item => (
                    <button
                        key={item.id}
                        id={`sm-menu-${item.id}`}
                        onClick={() => onViewChange(item.id)}
                        className={`sm-menu-item sm-menu-${item.id} w-full flex items-center gap-3 px-4 py-3 rounded-lg mb-2 transition-all ${
                            currentView === item.id
                                ? 'sm-menu-active bg-gradient-to-r from-orange-500 to-red-600 text-white'
                                : 'text-gray-700 hover:bg-gray-100'
                        }`}
                    >
                        <i className={`sm-menu-icon fas ${item.icon} text-lg`}></i>
                        <span className="sm-menu-label font-medium">{item.label}</span>
                    </button>
                ))}
            </nav>

            {/* User info */}
            <div id="sm-sidebar-footer" className="sm-sidebar-footer p-4 border-t">
                <div className="sm-user-info flex items-center gap-3 mb-3">
                    <div className="sm-user-avatar w-10 h-10 bg-gradient-to-br from-orange-500 to-red-600 rounded-full flex items-center justify-center text-white font-bold">
                        {customer?.contact_name?.charAt(0) || 'U'}
                    </div>
                    <div className="sm-user-details flex-1 min-w-0">
                        <p className="sm-user-name font-medium text-gray-800 truncate">{customer?.contact_name}</p>
                        <p className="sm-user-email text-xs text-gray-600 truncate">{customer?.email}</p>
                    </div>
                </div>
                <button
                    id="sm-logout-btn"
                    onClick={logout}
                    className="sm-logout-btn w-full px-4 py-2 bg-gray-100 hover:bg-gray-200 rounded-lg text-gray-700 font-medium transition-all"
                >
                    <i className="fas fa-sign-out-alt mr-2"></i>
                    Déconnexion
                </button>
            </div>
        </div>
    );
};

// ============================================================================
// COMPOSANT TPG STOP SEARCH - Recherche d'arrêt TPG avec auto-complétion
// ============================================================================

const TPGStopSearch = ({ label = 'Arrêt de bus le plus proche', value, onStopSelected, placeholder = 'Rechercher un arrêt TPG...', required = false }) => {
    const [searchTerm, setSearchTerm] = useState(value || '');
    const [filteredStops, setFilteredStops] = useState([]);
    const [isLoading, setIsLoading] = useState(false);
    const [showSuggestions, setShowSuggestions] = useState(false);
    const [shouldSearch, setShouldSearch] = useState(false); // Seulement rechercher si l'utilisateur tape
    const searchTimeout = React.useRef(null);
    
    // Mettre à jour le searchTerm quand value change (lors de l'édition)
    useEffect(() => {
        if (value !== undefined && value !== searchTerm) {
            setSearchTerm(value || '');
            setShowSuggestions(false);
            setFilteredStops([]);
            setShouldSearch(false); // NE PAS rechercher lors du chargement initial
        }
    }, [value]);
    
    // Rechercher les arrêts via l'API proxy avec debounce
    useEffect(() => {
        // Clear previous timeout
        if (searchTimeout.current) {
            clearTimeout(searchTimeout.current);
        }
        
        // Ne rechercher que si l'utilisateur a commencé à taper
        if (!shouldSearch) {
            return;
        }
        
        if (searchTerm.length < 2) {
            setFilteredStops([]);
            setShowSuggestions(false);
            return;
        }
        
        // Debounce la recherche de 400ms pour éviter trop de requêtes
        searchTimeout.current = setTimeout(async () => {
            setIsLoading(true);
            try {
                const data = await api.searchTPGStops(searchTerm);
                
                if (data.stops && data.stops.length > 0) {
                    // Transformer les données au format attendu
                    const transformedStops = data.stops.map(stop => ({
                        nom: stop.stopName || '',
                        code: stop.stopCode || '',
                        commune: stop.commune || 'Genève',
                        latitude: stop.coordinates ? stop.coordinates[1] : null,
                        longitude: stop.coordinates ? stop.coordinates[0] : null,
                        codesCount: stop.codes ? stop.codes.length : 1
                    }));
                    
                    setFilteredStops(transformedStops);
                    setShowSuggestions(true);
                } else {
                    setFilteredStops([]);
                    setShowSuggestions(false);
                }
            } catch (error) {
                console.error('❌ [TPGStopSearch] Erreur recherche:', error);
                setFilteredStops([]);
            } finally {
                setIsLoading(false);
            }
        }, 400);
        
        return () => {
            if (searchTimeout.current) {
                clearTimeout(searchTimeout.current);
            }
        };
    }, [searchTerm, shouldSearch]);
    
    const handleSelectStop = (stop) => {
        console.log('👆 [TPGStopSearch] handleSelectStop appelé avec:', stop);
        
        // Sécuriser les valeurs avant de les utiliser
        const safStop = {
            nom: stop.nom || '',
            code: stop.code || '',
            commune: stop.commune || 'Genève',
            latitude: stop.latitude || null,
            longitude: stop.longitude || null
        };
        
        console.log('👆 [TPGStopSearch] safStop créé:', safStop);
        console.log('👆 [TPGStopSearch] Mise à jour searchTerm avec:', safStop.nom);
        
        // Désactiver la recherche et fermer les suggestions
        setShouldSearch(false);
        setSearchTerm(safStop.nom);
        setShowSuggestions(false);
        setFilteredStops([]);
        
        console.log('👆 [TPGStopSearch] Appel onStopSelected avec:', safStop);
        onStopSelected(safStop);
    };
    
    const handleInputChange = (value) => {
        console.log('⌨️ [TPGStopSearch] handleInputChange:', value);
        setShouldSearch(true); // Activer la recherche car l'utilisateur tape
        setSearchTerm(value);
        // Si l'utilisateur efface le champ, notifier le parent
        if (!value) {
            console.log('⌨️ [TPGStopSearch] Champ effacé, notification parent');
            onStopSelected({ nom: '', code: '' });
        }
    };
    
    // Fermer les suggestions quand on clique en dehors
    useEffect(() => {
        const handleClickOutside = (e) => {
            if (!e.target.closest('.tpg-stop-search-container')) {
                setShowSuggestions(false);
            }
        };
        
        document.addEventListener('mousedown', handleClickOutside);
        return () => document.removeEventListener('mousedown', handleClickOutside);
    }, []);
    
    return (
        <div className="sm-input-group mb-4 tpg-stop-search-container" style={{ position: 'relative' }}>
            <label className="sm-input-label block text-gray-700 font-medium mb-2">
                {label} {required && <span className="text-red-500">*</span>}
            </label>
            <div className="sm-input-wrapper relative">
                <i className="sm-input-icon fas fa-bus absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
                <input
                    type="text"
                    className="sm-input w-full px-4 py-3 pl-10 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-transparent"
                    placeholder={isLoading ? 'Chargement des arrêts...' : placeholder}
                    value={searchTerm}
                    onChange={(e) => handleInputChange(e.target.value)}
                    disabled={isLoading}
                    required={required}
                />
                {isLoading && (
                    <div className="absolute right-3 top-1/2 transform -translate-y-1/2">
                        <i className="fas fa-spinner fa-spin text-gray-400"></i>
                    </div>
                )}
            </div>
            
            {/* Suggestions dropdown */}
            {showSuggestions && filteredStops.length > 0 && (
                <div
                    className="tpg-suggestions-dropdown absolute left-0 right-0 mt-1 bg-white border border-gray-300 rounded-lg shadow-lg max-h-80 overflow-y-auto z-50"
                    style={{ top: '100%' }}
                >
                    {filteredStops.map((stop, index) => (
                        <div
                            key={stop.code || `stop-${index}`}
                            className="tpg-suggestion-item px-4 py-3 cursor-pointer hover:bg-orange-50 border-b border-gray-100 last:border-b-0"
                            onClick={() => handleSelectStop(stop)}
                        >
                            <div className="flex items-start gap-3">
                                <div className="w-8 h-8 bg-orange-100 rounded-full flex items-center justify-center flex-shrink-0 mt-1">
                                    <i className="fas fa-bus text-orange-600 text-sm"></i>
                                </div>
                                <div className="flex-1 min-w-0">
                                    <div className="font-semibold text-gray-800 truncate">{stop.nom || 'Sans nom'}</div>
                                    <div className="text-xs text-gray-600 mt-1">
                                        {stop.code && (
                                            <span className="inline-block bg-gray-100 px-2 py-0.5 rounded mr-2">{stop.code}</span>
                                        )}
                                        <span className="mr-2">{stop.commune || 'Genève'}</span>
                                        {stop.codesCount > 1 && (
                                            <span className="inline-block bg-blue-100 text-blue-700 px-2 py-0.5 rounded text-xs">
                                                {stop.codesCount} quais
                                            </span>
                                        )}
                                    </div>
                                </div>
                            </div>
                        </div>
                    ))}
                </div>
            )}
            
            {/* Message si aucun résultat */}
            {showSuggestions && searchTerm.length >= 2 && filteredStops.length === 0 && !isLoading && (
                <div className="absolute left-0 right-0 mt-1 bg-white border border-gray-300 rounded-lg shadow-lg p-4 z-50">
                    <div className="text-center text-gray-500">
                        <i className="fas fa-search text-2xl mb-2"></i>
                        <p>Aucun arrêt trouvé pour "{searchTerm}"</p>
                    </div>
                </div>
            )}
        </div>
    );
};

// ============================================================================
// COMPOSANT ADDRESS AUTOCOMPLETE - API Maps SwissApp
// ============================================================================
/**
 * Composant d'autocomplétion d'adresses utilisant api.maps.swissapp.net
 * 
 * Features:
 * - Recherche avec debounce (400ms)
 * - Navigation au clavier (flèches, Enter, Escape)
 * - Géocodage automatique pour obtenir les coordonnées GPS
 * - États de chargement visuels
 * - Gestion des erreurs
 * - Responsive et accessible
 * 
 * @param {string} label - Label du champ (default: "Adresse complète")
 * @param {string} value - Valeur actuelle de l'adresse
 * @param {function} onAddressSelected - Callback appelé lors de la sélection
 *                                       Reçoit: { address, latitude, longitude, place_id }
 * @param {string} placeholder - Texte du placeholder
 * @param {boolean} required - Si le champ est obligatoire
 * 
 * @example
 * <AddressAutocomplete
 *     label="Adresse complète"
 *     value={formAddress}
 *     onAddressSelected={(data) => {
 *         setFormAddress(data.address);
 *         setFormLatitude(data.latitude);
 *         setFormLongitude(data.longitude);
 *     }}
 *     placeholder="Commencez à taper une adresse..."
 *     required
 * />
 */
const AddressAutocomplete = ({ 
    id = 'sm-address-autocomplete-input',
    label = 'Adresse complète', 
    value, 
    onAddressSelected, 
    placeholder = 'Commencez à taper une adresse en Suisse...', 
    required = false 
}) => {
    // ========================================================================
    // STATES
    // ========================================================================
    const [searchTerm, setSearchTerm] = useState(value || '');
    const [suggestions, setSuggestions] = useState([]);
    const [isLoading, setIsLoading] = useState(false);
    const [showSuggestions, setShowSuggestions] = useState(false);
    const [isGeocoding, setIsGeocoding] = useState(false);
    const [isUserTyping, setIsUserTyping] = useState(false);
    
    console.log('🗺️ [AddressAutocomplete] Render:', { value, searchTerm, suggestionsCount: suggestions.length, isUserTyping });
    
    // Fonction de recherche d'adresses
    const searchAddresses = async (input) => {
        console.log('🔍 [AddressAutocomplete] Recherche:', input);
        setIsLoading(true);
        try {
            const result = await api.searchAddress(input);
            console.log('📥 [AddressAutocomplete] Résultat:', result);
            if (result.success) {
                console.log('✅ [AddressAutocomplete] Suggestions:', result.suggestions.length);
                setSuggestions(result.suggestions);
                setShowSuggestions(true);
            } else {
                console.error('❌ [AddressAutocomplete] Échec:', result.error);
                setSuggestions([]);
            }
        } catch (error) {
            console.error('❌ [AddressAutocomplete] Erreur chargement:', error);
            setSuggestions([]);
        } finally {
            setIsLoading(false);
        }
    };
    
    // Mettre à jour le searchTerm quand value change (lors de l'édition)
    useEffect(() => {
        console.log('🔄 [AddressAutocomplete] value changed:', value);
        if (value !== undefined && value !== searchTerm) {
            setSearchTerm(value || '');
            // Ne pas déclencher de recherche, c'est juste un chargement initial
            setIsUserTyping(false);
        }
    }, [value]);
    
    // Rechercher les adresses avec debounce SEULEMENT si l'utilisateur tape
    useEffect(() => {
        // Ne rien faire si ce n'est pas une saisie utilisateur
        if (!isUserTyping) {
            return;
        }
        
        if (searchTerm.length < 3) {
            setSuggestions([]);
            setShowSuggestions(false);
            return;
        }
        
        // Debounce de 500ms
        const timeoutId = setTimeout(() => {
            searchAddresses(searchTerm);
        }, 500);
        
        return () => clearTimeout(timeoutId);
    }, [searchTerm, isUserTyping]);
    
    const handleSelectAddress = async (suggestion) => {
        console.log('👆 [AddressAutocomplete] Adresse sélectionnée:', suggestion);
        
        const address = suggestion.description;
        setSearchTerm(address);
        setShowSuggestions(false);
        setIsGeocoding(true);
        setIsUserTyping(false); // Désactiver le flag pour éviter une nouvelle recherche
        
        try {
            // Utiliser place_geometry avec le place_id pour obtenir les coordonnées GPS exactes
            console.log('📍 [AddressAutocomplete] Récupération des détails via place_id:', suggestion.place_id);
            const result = await api.getPlaceGeometry(suggestion.place_id);
            
            if (result.success && result.location) {
                console.log('✅ [AddressAutocomplete] Détails récupérés:', result.location);
                
                // Mettre à jour le champ avec l'adresse formatée
                const formattedAddress = result.location.formatted || address;
                setSearchTerm(formattedAddress);
                
                // Notifier le parent avec l'adresse et les coordonnées
                onAddressSelected({
                    address: formattedAddress,
                    latitude: result.location.lat,
                    longitude: result.location.lng,
                    place_id: suggestion.place_id
                });
            } else {
                console.error('❌ [AddressAutocomplete] Échec récupération détails:', result.error);
                // Notifier quand même avec juste l'adresse
                onAddressSelected({
                    address: address,
                    latitude: null,
                    longitude: null,
                    place_id: suggestion.place_id
                });
            }
        } catch (error) {
            console.error('❌ [AddressAutocomplete] Erreur récupération détails:', error);
            // Notifier quand même avec juste l'adresse
            onAddressSelected({
                address: address,
                latitude: null,
                longitude: null,
                place_id: suggestion.place_id
            });
        } finally {
            setIsGeocoding(false);
        }
    };
    
    const handleInputChange = (value) => {
        console.log('⌨️ [AddressAutocomplete] Input change (saisie utilisateur):', value);
        setSearchTerm(value);
        setIsUserTyping(true); // Marquer comme saisie utilisateur
        
        // Si l'utilisateur efface le champ, notifier le parent
        if (!value) {
            console.log('⌨️ [AddressAutocomplete] Champ effacé, notification parent');
            onAddressSelected({ address: '', latitude: null, longitude: null });
        }
    };
    
    // Fermer les suggestions quand on clique en dehors
    useEffect(() => {
        const handleClickOutside = (e) => {
            if (!e.target.closest('.address-autocomplete-container')) {
                setShowSuggestions(false);
            }
        };
        
        if (showSuggestions) {
            document.addEventListener('click', handleClickOutside);
            return () => document.removeEventListener('click', handleClickOutside);
        }
    }, [showSuggestions]);
    
    return (
        <div className="address-autocomplete-container mb-4">
            <label className="block text-gray-700 font-medium mb-2">
                <i className="fas fa-map-marker-alt mr-2"></i>
                {label}
                {required && <span className="text-red-500 ml-1">*</span>}
            </label>
            
            <div className="relative">
                <div className="relative">
                    <i className="fas fa-map-marker-alt absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
                    <input
                        id={id}
                        type="text"
                        value={searchTerm}
                        onChange={(e) => handleInputChange(e.target.value)}
                        placeholder={placeholder}
                        required={required}
                        disabled={isGeocoding}
                        className="w-full px-4 py-3 pl-10 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-transparent disabled:bg-gray-100 disabled:cursor-not-allowed"
                    />
                </div>
                
                {/* Indicateur de chargement */}
                {(isLoading || isGeocoding) && (
                    <div className="absolute right-3 top-1/2 transform -translate-y-1/2">
                        <div className="animate-spin rounded-full h-5 w-5 border-b-2 border-orange-500"></div>
                    </div>
                )}
                
                {/* Liste des suggestions */}
                {showSuggestions && suggestions.length > 0 && !isGeocoding && (
                    <div className="absolute z-50 w-full mt-1 bg-white border border-gray-300 rounded-lg shadow-lg max-h-60 overflow-y-auto">
                        {suggestions.map((suggestion, index) => (
                            <button
                                key={suggestion.place_id || index}
                                type="button"
                                onClick={() => handleSelectAddress(suggestion)}
                                className="w-full text-left px-4 py-3 hover:bg-gray-50 border-b last:border-b-0 transition-colors"
                            >
                                <div className="flex items-start gap-3">
                                    <i className="fas fa-map-marker-alt text-orange-500 mt-1"></i>
                                    <div className="flex-1 min-w-0">
                                        <p className="font-medium text-gray-800 truncate">
                                            {suggestion.main_text || suggestion.description}
                                        </p>
                                        {suggestion.secondary_text && (
                                            <p className="text-sm text-gray-600 truncate">
                                                {suggestion.secondary_text}
                                            </p>
                                        )}
                                    </div>
                                </div>
                            </button>
                        ))}
                    </div>
                )}
                
                {/* Message si aucune suggestion */}
                {showSuggestions && suggestions.length === 0 && !isLoading && searchTerm.length >= 3 && (
                    <div className="absolute z-50 w-full mt-1 bg-white border border-gray-300 rounded-lg shadow-lg p-4">
                        <p className="text-gray-500 text-center">
                            <i className="fas fa-search mr-2"></i>
                            Aucune adresse trouvée
                        </p>
                    </div>
                )}
            </div>
            
            {/* Message de géocodage */}
            {isGeocoding && (
                <p className="text-sm text-orange-600 mt-2">
                    <i className="fas fa-spinner fa-spin mr-2"></i>
                    Récupération des coordonnées GPS...
                </p>
            )}
        </div>
    );
};

// ============================================================================
// COMPOSANT D'AUTOCOMPLÉTION DE VILLE POUR MÉTÉO
// ============================================================================

const CityAutocomplete = ({ 
    id = 'sm-city-autocomplete-input',
    label = 'Ville pour la météo', 
    value, 
    onChange,
    placeholder = 'Recherchez une ville en Suisse...', 
    required = false 
}) => {
    const [searchTerm, setSearchTerm] = useState(value || '');
    const [suggestions, setSuggestions] = useState([]);
    const [isLoading, setIsLoading] = useState(false);
    const [showSuggestions, setShowSuggestions] = useState(false);
    const [isUserTyping, setIsUserTyping] = useState(false);
    
    // Fonction de recherche de villes
    const searchCities = async (input) => {
        console.log('🏙️ [CityAutocomplete] Recherche ville:', input);
        setIsLoading(true);
        try {
            const result = await api.searchAddress(input);
            console.log('📥 [CityAutocomplete] Résultat:', result);
            
            if (result.success && result.suggestions) {
                // Filtrer pour ne garder que les villes (locality)
                const cities = result.suggestions.filter(s => 
                    s.types && (s.types.includes('locality') || s.types.includes('administrative_area_level_3'))
                );
                console.log('✅ [CityAutocomplete] Villes filtrées:', cities.length);
                setSuggestions(cities);
                setShowSuggestions(cities.length > 0);
            } else {
                setSuggestions([]);
            }
        } catch (error) {
            console.error('❌ [CityAutocomplete] Erreur:', error);
            setSuggestions([]);
        } finally {
            setIsLoading(false);
        }
    };
    
    // Mettre à jour le searchTerm quand value change
    useEffect(() => {
        if (value !== undefined && value !== searchTerm) {
            setSearchTerm(value || '');
            setIsUserTyping(false);
        }
    }, [value]);
    
    // Rechercher avec debounce SEULEMENT si l'utilisateur tape
    useEffect(() => {
        if (!isUserTyping) return;
        
        if (searchTerm.length < 2) {
            setSuggestions([]);
            setShowSuggestions(false);
            return;
        }
        
        const timeoutId = setTimeout(() => {
            searchCities(searchTerm);
        }, 500);
        
        return () => clearTimeout(timeoutId);
    }, [searchTerm, isUserTyping]);
    
    const handleSelectCity = (suggestion) => {
        console.log('👆 [CityAutocomplete] Ville sélectionnée:', suggestion);
        
        const cityName = suggestion.structured_formatting?.main_text || suggestion.description;
        setSearchTerm(cityName);
        setShowSuggestions(false);
        setIsUserTyping(false);
        
        // Notifier le parent
        if (onChange) {
            onChange(cityName);
        }
    };
    
    const handleInputChange = (val) => {
        console.log('⌨️ [CityAutocomplete] Saisie:', val);
        setSearchTerm(val);
        setIsUserTyping(true);
        
        if (!val && onChange) {
            onChange('');
        }
    };
    
    // Fermer les suggestions au clic extérieur
    useEffect(() => {
        const handleClickOutside = (e) => {
            if (!e.target.closest('.city-autocomplete-container')) {
                setShowSuggestions(false);
            }
        };
        
        if (showSuggestions) {
            document.addEventListener('click', handleClickOutside);
            return () => document.removeEventListener('click', handleClickOutside);
        }
    }, [showSuggestions]);
    
    return (
        <div className="city-autocomplete-container mb-4">
            <label className="block text-gray-700 font-medium mb-2">
                <i className="fas fa-cloud-sun mr-2"></i>
                {label}
                {required && <span className="text-red-500 ml-1">*</span>}
            </label>
            
            <div className="relative">
                <div className="relative">
                    <i className="fas fa-city absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
                    <input
                        id={id}
                        type="text"
                        value={searchTerm}
                        onChange={(e) => handleInputChange(e.target.value)}
                        placeholder={placeholder}
                        required={required}
                        className="w-full px-4 py-3 pl-10 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-transparent"
                    />
                </div>
                
                {/* Indicateur de chargement */}
                {isLoading && (
                    <div className="absolute right-3 top-1/2 transform -translate-y-1/2">
                        <div className="animate-spin rounded-full h-5 w-5 border-b-2 border-orange-500"></div>
                    </div>
                )}
                
                {/* Liste des suggestions */}
                {showSuggestions && suggestions.length > 0 && (
                    <div className="absolute z-50 w-full mt-1 bg-white border border-gray-300 rounded-lg shadow-lg max-h-60 overflow-y-auto">
                        {suggestions.map((suggestion, index) => (
                            <button
                                key={suggestion.place_id || index}
                                type="button"
                                onClick={() => handleSelectCity(suggestion)}
                                className="w-full text-left px-4 py-3 hover:bg-gray-50 border-b last:border-b-0 transition-colors"
                            >
                                <div className="flex items-start gap-3">
                                    <i className="fas fa-city text-blue-500 mt-1"></i>
                                    <div className="flex-1 min-w-0">
                                        <p className="font-medium text-gray-800 truncate">
                                            {suggestion.structured_formatting?.main_text || suggestion.description}
                                        </p>
                                        {suggestion.structured_formatting?.secondary_text && (
                                            <p className="text-sm text-gray-500 truncate">
                                                {suggestion.structured_formatting.secondary_text}
                                            </p>
                                        )}
                                    </div>
                                </div>
                            </button>
                        ))}
                    </div>
                )}
                
                {/* Pas de résultat */}
                {showSuggestions && suggestions.length === 0 && !isLoading && searchTerm.length >= 2 && (
                    <div className="absolute z-50 w-full mt-1 bg-white border border-gray-300 rounded-lg shadow-lg p-4">
                        <p className="text-gray-500 text-center text-sm">
                            <i className="fas fa-search mr-2"></i>
                            Aucune ville trouvée
                        </p>
                    </div>
                )}
            </div>
        </div>
    );
};

// ============================================================================
// COMPOSANT CONTENT CARD - Affichage d'un élément de contenu (pub, alerte, etc.)
// ============================================================================

const ContentCard = ({ 
    type, 
    title, 
    description, 
    source, 
    readOnly = false, 
    onEdit, 
    onDelete, 
    onViewConfig,
    data = {}
}) => {
    const icons = {
        advertising: 'fa-image',
        alert: 'fa-exclamation-triangle',
        message: 'fa-comment',
        contact: 'fa-phone',
        slider: 'fa-align-left',
        number: 'fa-phone-square'
    };

    const typeLabels = {
        advertising: 'Publicité',
        alert: 'Alerte',
        message: 'Message',
        contact: 'Contact',
        slider: 'Message défilant',
        number: 'Numéro d\'urgence'
    };

    const colors = {
        config: 'bg-gray-50 border-gray-300 text-gray-700',
        screen: 'bg-orange-50 border-orange-300 text-orange-900'
    };

    return (
        <div className={`p-4 rounded-lg border-2 ${colors[source]} flex items-center gap-4 transition-all hover:shadow-md`}>
            {/* Icône du type */}
            <div className="text-2xl flex-shrink-0">
                <i className={`fas ${icons[type]}`}></i>
            </div>

            {/* Contenu */}
            <div className="flex-1 min-w-0">
                <div className="flex items-center gap-2 mb-1">
                    <h5 className="font-bold truncate">{title}</h5>
                    <span className="text-xs px-2 py-1 rounded-full bg-white bg-opacity-50">
                        {typeLabels[type] || type}
                    </span>
                </div>
                {description && (
                    <p className="text-sm text-gray-600 truncate">{description}</p>
                )}
                <p className="text-xs text-gray-500 mt-1">
                    {source === 'config' ? (
                        <span className="flex items-center gap-1">
                            <i className="fas fa-cog"></i>
                            Depuis la configuration
                        </span>
                    ) : (
                        <span className="flex items-center gap-1">
                            <i className="fas fa-tv"></i>
                            Spécifique à cet écran
                        </span>
                    )}
                </p>
            </div>

            {/* Actions */}
            <div className="flex gap-2 flex-shrink-0">
                {readOnly ? (
                    <button
                        onClick={onViewConfig}
                        className="px-3 py-2 bg-gray-200 hover:bg-gray-300 text-gray-700 rounded-lg text-sm font-medium transition-all flex items-center gap-2"
                    >
                        <i className="fas fa-external-link-alt"></i>
                        Voir config
                    </button>
                ) : (
                    <>
                        <button
                            onClick={onEdit}
                            className="px-3 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded-lg text-sm font-medium transition-all"
                        >
                            <i className="fas fa-edit"></i>
                        </button>
                        <button
                            onClick={onDelete}
                            className="px-3 py-2 bg-red-500 hover:bg-red-600 text-white rounded-lg text-sm font-medium transition-all"
                        >
                            <i className="fas fa-trash"></i>
                        </button>
                    </>
                )}
            </div>
        </div>
    );
};

// ============================================================================
// COMPOSANT PREVIEW ÉCRAN - SCREENSHOT IMAGE
// ============================================================================

const ScreenPreviewModal = ({ previewUrl, onClose }) => {
    const [screenshotUrl, setScreenshotUrl] = useState('');
    const [nextScreenshotUrl, setNextScreenshotUrl] = useState('');
    const [loading, setLoading] = useState(true);
    const [refreshing, setRefreshing] = useState(false);
    const [error, setError] = useState(null);
    const [lastUpdate, setLastUpdate] = useState(new Date());
    const intervalRef = useRef(null);

    // Extraire le MD5 de l'URL
    const getMd5FromUrl = (url) => {
        const match = url.match(/md5=([a-zA-Z0-9]+)/);
        return match ? match[1] : null;
    };

    // Générer l'URL du screenshot depuis l'API
    const loadScreenshot = (isInitialLoad = false) => {
        const md5 = getMd5FromUrl(previewUrl);
        if (!md5) {
            setError('MD5 non trouvé dans l\'URL');
            return;
        }

        // Détecter l'environnement
        const isLocal = window.location.hostname.includes('local');
        const apiUrl = isLocal 
            ? 'https://local.smarthall.api:8890'
            : 'https://api.smarthall.ch';

        // Ajouter un timestamp pour éviter le cache navigateur
        const url = `${apiUrl}/screenshot.php?md5=${md5}&t=${Date.now()}`;
        
        if (isInitialLoad) {
            setLoading(true);
            setScreenshotUrl(url);
        } else {
            setRefreshing(true);
            setNextScreenshotUrl(url);
        }
        
        setLastUpdate(new Date());
    };

    // Effet au montage et rafraîchissement périodique
    useEffect(() => {
        loadScreenshot(true);

        // Rafraîchir toutes les 60 secondes (1 minute)
        intervalRef.current = setInterval(() => {
            loadScreenshot(false);
        }, 60000);

        return () => {
            if (intervalRef.current) {
                clearInterval(intervalRef.current);
            }
        };
    }, [previewUrl]);

    // Fermer avec Échap
    useEffect(() => {
        const handleEscape = (e) => {
            if (e.key === 'Escape') {
                onClose();
            }
        };
        window.addEventListener('keydown', handleEscape);
        return () => window.removeEventListener('keydown', handleEscape);
    }, [onClose]);

    return (
        <div className="fixed inset-0 z-[9999] bg-black flex items-center justify-center">
            {/* Bouton fermer */}
            <button
                onClick={onClose}
                className="absolute top-4 right-4 z-10 px-4 py-2 bg-white text-gray-800 rounded-lg hover:bg-gray-100 transition-colors flex items-center gap-2 shadow-lg"
                title="Fermer l'aperçu (Échap)"
            >
                <i className="fas fa-times"></i>
                <span>Fermer</span>
            </button>

            {/* Indicateur de rafraîchissement */}
            <div className="absolute top-4 left-4 z-10 px-4 py-2 bg-white/90 text-gray-800 rounded-lg shadow-lg flex items-center gap-2 text-sm">
                <i className={`fas fa-sync-alt ${refreshing ? 'fa-spin' : ''} text-green-500`}></i>
                <span>Capture automatique (1 min)</span>
                <span className="text-gray-500">• {lastUpdate.toLocaleTimeString('fr-CH')}</span>
            </div>

            {/* Image du screenshot - Plein écran */}
            <div className="relative w-full h-full flex items-center justify-center">
                {error ? (
                    <div className="bg-red-500/10 border-2 border-red-500 rounded-lg p-8 text-center max-w-md">
                        <i className="fas fa-exclamation-triangle text-red-500 text-4xl mb-4"></i>
                        <p className="text-red-500 font-semibold mb-2">{error}</p>
                        <p className="text-red-400 text-sm">Vérifiez que l'URL est accessible publiquement</p>
                        <p className="text-red-400 text-xs mt-2">L'API Cloudflare doit pouvoir accéder à screen.smarthall.ch</p>
                    </div>
                ) : (
                    <>
                        {/* Image principale visible */}
                        {screenshotUrl && (
                            <img
                                src={screenshotUrl}
                                alt="Aperçu de l'écran SmartScreen"
                                className="max-w-full max-h-full object-contain"
                                onLoad={() => setLoading(false)}
                                onError={() => {
                                    setLoading(false);
                                    setError('Erreur de génération du screenshot via Cloudflare API');
                                }}
                            />
                        )}
                        
                        {/* Préchargement de la nouvelle image (invisible) */}
                        {nextScreenshotUrl && (
                            <img
                                src={nextScreenshotUrl}
                                alt="Préchargement"
                                className="hidden"
                                onLoad={() => {
                                    // Remplacer l'ancienne image par la nouvelle
                                    setScreenshotUrl(nextScreenshotUrl);
                                    setNextScreenshotUrl('');
                                    setRefreshing(false);
                                }}
                                onError={() => {
                                    setNextScreenshotUrl('');
                                    setRefreshing(false);
                                }}
                            />
                        )}
                        
                        {/* Indicateur de chargement initial uniquement */}
                        {loading && (
                            <div className="absolute inset-0 flex items-center justify-center bg-black/50">
                                <div className="text-center">
                                    <i className="fas fa-spinner fa-spin text-4xl text-white mb-4"></i>
                                    <p className="text-white text-lg">Génération du screenshot...</p>
                                    <p className="text-white/70 text-sm mt-2">Cela peut prendre quelques secondes</p>
                                </div>
                            </div>
                        )}
                        
                        {/* Petit indicateur de rafraîchissement en cours (discret) */}
                        {refreshing && !loading && (
                            <div className="absolute top-20 left-4 z-10 px-3 py-1 bg-blue-500/90 text-white rounded-lg shadow-lg text-xs flex items-center gap-2">
                                <i className="fas fa-spinner fa-spin"></i>
                                <span>Rafraîchissement...</span>
                            </div>
                        )}
                    </>
                )}
            </div>

            {/* Info bas de page */}
            <div className="absolute bottom-4 left-1/2 transform -translate-x-1/2 z-10 px-4 py-2 bg-white/90 text-gray-600 rounded-lg shadow-lg text-sm flex items-center gap-4">
                <span className="flex items-center gap-2">
                    <i className="fas fa-camera text-green-500"></i>
                    <span>Capture image sécurisée • Rafraîchit toutes les minutes</span>
                </span>
                <span className="text-gray-400">|</span>
                <span className="font-mono text-xs">{getMd5FromUrl(previewUrl)}</span>
            </div>
        </div>
    );
};

// Suite dans le fichier app.jsx...

