import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

import '../../../core/constants/design_system.dart';
import '../../../data/datasources/establishment_remote_data_source.dart';
import '../../../domain/entities/establishment.dart';
import '../../widgets/animated_widgets.dart';
import '../../widgets/custom_snackbar.dart';
import '../../widgets/modern_empty_state.dart';
import '../../widgets/shimmer_loading.dart';

/// Écran des établissements avec recherche et filtres.
class EstablishmentsScreen extends StatefulWidget {
  const EstablishmentsScreen({super.key});

  @override
  State<EstablishmentsScreen> createState() => _EstablishmentsScreenState();
}

class _EstablishmentsScreenState extends State<EstablishmentsScreen> {
  final EstablishmentRemoteDataSource _dataSource = EstablishmentRemoteDataSource(http.Client());
  final TextEditingController _searchController = TextEditingController();

  List<Establishment> _establishments = [];
  List<Establishment> _filteredEstablishments = [];
  bool _isLoading = false;
  String? _errorMessage;

  // Filtres
  EstablishmentType? _selectedType;
  PriceRange? _selectedPriceRange;
  String? _selectedCity;
  final List<String> _availableCities = [];

  @override
  void initState() {
    super.initState();
    _loadEstablishments();
    _searchController.addListener(_onSearchChanged);
  }

  @override
  void dispose() {
    _searchController.dispose();
    super.dispose();
  }

  Future<void> _loadEstablishments() async {
    setState(() {
      _isLoading = true;
      _errorMessage = null;
    });

    try {
      final models = await _dataSource.getAllEstablishments();
      if (mounted) {
        setState(() {
          _establishments = models.map((m) => m.toEntity()).toList();
          _filteredEstablishments = _establishments;

          // Extraire les villes uniques
          final cities = _establishments.map((e) => e.city).toSet().toList();
          _availableCities.clear();
          _availableCities.addAll(cities);

          _isLoading = false;
        });
      }
    } catch (e) {
      if (mounted) {
        setState(() {
          _errorMessage = e.toString();
          _isLoading = false;
        });
      }
    }
  }

  void _onSearchChanged() {
    _applyFilters();
  }

  void _applyFilters() {
    final query = _searchController.text.toLowerCase();

    setState(() {
      _filteredEstablishments = _establishments.where((establishment) {
        // Filtre par recherche (nom ou ville)
        final matchesSearch = query.isEmpty ||
            establishment.name.toLowerCase().contains(query) ||
            establishment.city.toLowerCase().contains(query);

        // Filtre par type
        final matchesType = _selectedType == null || establishment.type == _selectedType;

        // Filtre par prix
        final matchesPrice = _selectedPriceRange == null || establishment.priceRange == _selectedPriceRange;

        // Filtre par ville
        final matchesCity = _selectedCity == null || establishment.city == _selectedCity;

        return matchesSearch && matchesType && matchesPrice && matchesCity;
      }).toList();
    });
  }

  void _clearFilters() {
    setState(() {
      _selectedType = null;
      _selectedPriceRange = null;
      _selectedCity = null;
      _searchController.clear();
      _applyFilters();
    });
  }

  Future<void> _showFilters() async {
    await showModalBottomSheet(
      context: context,
      isScrollControlled: true,
      backgroundColor: Colors.transparent,
      builder: (context) => _FiltersBottomSheet(
        selectedType: _selectedType,
        selectedPriceRange: _selectedPriceRange,
        selectedCity: _selectedCity,
        availableCities: _availableCities,
        onApply: (type, priceRange, city) {
          setState(() {
            _selectedType = type;
            _selectedPriceRange = priceRange;
            _selectedCity = city;
          });
          _applyFilters();
        },
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final hasActiveFilters = _selectedType != null || _selectedPriceRange != null || _selectedCity != null;

    return Scaffold(
      body: Column(
        children: [
          // Barre de recherche et filtres
          Container(
            padding: const EdgeInsets.all(DesignSystem.spacingLg),
            child: Column(
              children: [
                // Champ de recherche
                TextField(
                  controller: _searchController,
                  decoration: InputDecoration(
                    hintText: 'Rechercher un établissement...',
                    prefixIcon: const Icon(Icons.search),
                    suffixIcon: _searchController.text.isNotEmpty
                        ? IconButton(
                            icon: const Icon(Icons.clear),
                            onPressed: () => _searchController.clear(),
                          )
                        : null,
                    border: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(DesignSystem.radiusMd),
                    ),
                    filled: true,
                  ),
                ),
                const SizedBox(height: DesignSystem.spacingSm),

                // Boutons de filtres
                Row(
                  children: [
                    Expanded(
                      child: OutlinedButton.icon(
                        onPressed: _showFilters,
                        icon: Icon(
                          Icons.filter_list,
                          color: hasActiveFilters ? theme.colorScheme.primary : null,
                        ),
                        label: Text(
                          hasActiveFilters ? 'Filtres actifs' : 'Filtres',
                          style: TextStyle(
                            color: hasActiveFilters ? theme.colorScheme.primary : null,
                            fontWeight: hasActiveFilters ? FontWeight.bold : null,
                          ),
                        ),
                        style: OutlinedButton.styleFrom(
                          side: BorderSide(
                            color: hasActiveFilters
                                ? theme.colorScheme.primary
                                : theme.dividerColor,
                            width: hasActiveFilters ? 2 : 1,
                          ),
                        ),
                      ),
                    ),
                    if (hasActiveFilters) ...[
                      const SizedBox(width: DesignSystem.spacingSm),
                      IconButton(
                        onPressed: _clearFilters,
                        icon: const Icon(Icons.clear_all),
                        tooltip: 'Effacer les filtres',
                      ),
                    ],
                  ],
                ),
              ],
            ),
          ),

          // Liste des établissements
          Expanded(
            child: _isLoading
                ? const SkeletonList(
                    itemCount: 6,
                    skeletonWidget: ListItemSkeleton(),
                  )
                : _errorMessage != null
                    ? _buildErrorState(theme)
                    : _filteredEstablishments.isEmpty
                        ? _buildEmptyState()
                        : RefreshIndicator(
                            onRefresh: _loadEstablishments,
                            child: ListView.builder(
                              padding: const EdgeInsets.all(DesignSystem.spacingLg),
                              itemCount: _filteredEstablishments.length,
                              itemBuilder: (context, index) {
                                return _buildEstablishmentCard(
                                  _filteredEstablishments[index],
                                );
                              },
                            ),
                          ),
          ),
        ],
      ),
    );
  }

  Widget _buildErrorState(ThemeData theme) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Icon(Icons.error_outline, size: 64, color: Colors.grey[400]),
          const SizedBox(height: DesignSystem.spacingLg),
          Text('Erreur de chargement', style: theme.textTheme.titleLarge),
          const SizedBox(height: DesignSystem.spacingSm),
          Text(_errorMessage!, style: theme.textTheme.bodyMedium, textAlign: TextAlign.center),
          const SizedBox(height: DesignSystem.spacingXl),
          ElevatedButton.icon(
            onPressed: _loadEstablishments,
            icon: const Icon(Icons.refresh),
            label: const Text('Réessayer'),
          ),
        ],
      ),
    );
  }

  Widget _buildEmptyState() {
    return ModernEmptyState(
      illustration: EmptyStateIllustration.search,
      title: 'Aucun établissement trouvé',
      description: _searchController.text.isNotEmpty || (_selectedType != null || _selectedPriceRange != null || _selectedCity != null)
          ? 'Essayez de modifier vos critères de recherche'
          : 'Aucun établissement disponible pour le moment',
    );
  }

  Widget _buildEstablishmentCard(Establishment establishment) {
    final theme = Theme.of(context);

    return FadeInWidget(
      child: AnimatedCard(
        margin: const EdgeInsets.only(bottom: DesignSystem.spacingLg),
        onTap: () {
          // TODO: Naviguer vers les détails
          context.showInfo('Détails de ${establishment.name}');
        },
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // Image
            if (establishment.imageUrl != null)
              ClipRRect(
                borderRadius: const BorderRadius.vertical(
                  top: Radius.circular(DesignSystem.radiusMd),
                ),
                child: AspectRatio(
                  aspectRatio: 16 / 9,
                  child: Image.network(
                    establishment.imageUrl!,
                    fit: BoxFit.cover,
                    errorBuilder: (context, error, stackTrace) {
                      return Container(
                        color: Colors.grey[300],
                        child: const Icon(Icons.location_city, size: 48),
                      );
                    },
                  ),
                ),
              ),

            Padding(
              padding: const EdgeInsets.all(DesignSystem.spacingLg),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  // Nom et type
                  Row(
                    children: [
                      Text(
                        establishment.type.icon,
                        style: const TextStyle(fontSize: 24),
                      ),
                      const SizedBox(width: DesignSystem.spacingSm),
                      Expanded(
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Text(
                              establishment.name,
                              style: theme.textTheme.titleMedium?.copyWith(
                                fontWeight: FontWeight.bold,
                              ),
                            ),
                            Text(
                              establishment.type.displayName,
                              style: theme.textTheme.bodySmall?.copyWith(
                                color: Colors.grey[600],
                              ),
                            ),
                          ],
                        ),
                      ),
                      if (establishment.priceRange != null)
                        Text(
                          establishment.priceRange!.symbol,
                          style: theme.textTheme.bodyLarge?.copyWith(
                            fontWeight: FontWeight.bold,
                            color: theme.colorScheme.primary,
                          ),
                        ),
                    ],
                  ),
                  const SizedBox(height: DesignSystem.spacingSm),

                  // Adresse
                  Row(
                    children: [
                      const Icon(Icons.location_on, size: 16, color: Colors.grey),
                      const SizedBox(width: 4),
                      Expanded(
                        child: Text(
                          establishment.fullAddress,
                          style: theme.textTheme.bodySmall,
                          maxLines: 1,
                          overflow: TextOverflow.ellipsis,
                        ),
                      ),
                    ],
                  ),

                  // Note
                  if (establishment.rating != null) ...[
                    const SizedBox(height: DesignSystem.spacingSm),
                    Row(
                      children: [
                        const Icon(Icons.star, size: 16, color: Colors.amber),
                        const SizedBox(width: 4),
                        Text(
                          establishment.rating!.toStringAsFixed(1),
                          style: theme.textTheme.bodySmall?.copyWith(
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                        Text(
                          ' / 5.0',
                          style: theme.textTheme.bodySmall?.copyWith(
                            color: Colors.grey[600],
                          ),
                        ),
                      ],
                    ),
                  ],
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

/// Bottom sheet pour les filtres
class _FiltersBottomSheet extends StatefulWidget {
  const _FiltersBottomSheet({
    required this.selectedType,
    required this.selectedPriceRange,
    required this.selectedCity,
    required this.availableCities,
    required this.onApply,
  });

  final EstablishmentType? selectedType;
  final PriceRange? selectedPriceRange;
  final String? selectedCity;
  final List<String> availableCities;
  final void Function(EstablishmentType?, PriceRange?, String?) onApply;

  @override
  State<_FiltersBottomSheet> createState() => _FiltersBottomSheetState();
}

class _FiltersBottomSheetState extends State<_FiltersBottomSheet> {
  late EstablishmentType? _type;
  late PriceRange? _priceRange;
  late String? _city;

  @override
  void initState() {
    super.initState();
    _type = widget.selectedType;
    _priceRange = widget.selectedPriceRange;
    _city = widget.selectedCity;
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);

    return Container(
      decoration: BoxDecoration(
        color: theme.scaffoldBackgroundColor,
        borderRadius: const BorderRadius.vertical(top: Radius.circular(DesignSystem.radiusLg)),
      ),
      padding: EdgeInsets.only(
        bottom: MediaQuery.of(context).viewInsets.bottom + DesignSystem.spacingLg,
        top: DesignSystem.spacingLg,
        left: DesignSystem.spacingLg,
        right: DesignSystem.spacingLg,
      ),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          // Handle bar
          Center(
            child: Container(
              width: 40,
              height: 4,
              margin: const EdgeInsets.only(bottom: DesignSystem.spacingLg),
              decoration: BoxDecoration(
                color: Colors.grey[300],
                borderRadius: BorderRadius.circular(2),
              ),
            ),
          ),

          Text('Filtres', style: theme.textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold)),
          const SizedBox(height: DesignSystem.spacingXl),

          // Type
          Text('Type d\'établissement', style: theme.textTheme.titleSmall),
          const SizedBox(height: DesignSystem.spacingSm),
          Wrap(
            spacing: DesignSystem.spacingSm,
            runSpacing: DesignSystem.spacingSm,
            children: EstablishmentType.values.map((type) {
              final isSelected = _type == type;
              return FilterChip(
                label: Text(type.displayName),
                selected: isSelected,
                onSelected: (selected) {
                  setState(() {
                    _type = selected ? type : null;
                  });
                },
              );
            }).toList(),
          ),
          const SizedBox(height: DesignSystem.spacingXl),

          // Prix
          Text('Fourchette de prix', style: theme.textTheme.titleSmall),
          const SizedBox(height: DesignSystem.spacingSm),
          Wrap(
            spacing: DesignSystem.spacingSm,
            children: PriceRange.values.map((price) {
              final isSelected = _priceRange == price;
              return FilterChip(
                label: Text(price.symbol),
                selected: isSelected,
                onSelected: (selected) {
                  setState(() {
                    _priceRange = selected ? price : null;
                  });
                },
              );
            }).toList(),
          ),
          const SizedBox(height: DesignSystem.spacingXl),

          // Ville
          if (widget.availableCities.isNotEmpty) ...[
            Text('Ville', style: theme.textTheme.titleSmall),
            const SizedBox(height: DesignSystem.spacingSm),
            DropdownButtonFormField<String>(
              value: _city,
              decoration: InputDecoration(
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(DesignSystem.radiusMd),
                ),
                contentPadding: const EdgeInsets.symmetric(horizontal: DesignSystem.spacingLg, vertical: DesignSystem.spacingSm),
              ),
              hint: const Text('Toutes les villes'),
              items: widget.availableCities.map((city) {
                return DropdownMenuItem(value: city, child: Text(city));
              }).toList(),
              onChanged: (value) {
                setState(() {
                  _city = value;
                });
              },
            ),
            const SizedBox(height: DesignSystem.spacingXl),
          ],

          // Boutons
          Row(
            children: [
              Expanded(
                child: OutlinedButton(
                  onPressed: () {
                    setState(() {
                      _type = null;
                      _priceRange = null;
                      _city = null;
                    });
                  },
                  child: const Text('Réinitialiser'),
                ),
              ),
              const SizedBox(width: DesignSystem.spacingLg),
              Expanded(
                child: ElevatedButton(
                  onPressed: () {
                    widget.onApply(_type, _priceRange, _city);
                    Navigator.pop(context);
                  },
                  child: const Text('Appliquer'),
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}
