import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:geolocator/geolocator.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'dart:ui' as ui;
import 'package:flutter_dotenv/flutter_dotenv.dart';

class MapContent extends StatefulWidget {
  final String? initialSearchQuery;
  const MapContent({super.key, this.initialSearchQuery});

  @override
  State<MapContent> createState() => _MapContentState();
}

class _MapContentState extends State<MapContent> {
  GoogleMapController? _mapController;
  LatLng _initialPosition = const LatLng(48.8566, 2.3522);
  final TextEditingController _searchController = TextEditingController();
  bool _isLoadingLocation = false;
  bool _isSearching = false;
  Position? _currentPosition;
  
  final Set<Marker> _markers = {};
  final Set<Circle> _circles = {};
  
  List<PlaceSuggestion> _suggestions = [];
  
  static final String _apiKey = dotenv.env['GOOGLE_MAPS_API_KEY'] ?? '';

  @override
  void initState() {
    super.initState();
    // Si une recherche initiale est fournie, la pré-remplir et lancer la recherche
    if (widget.initialSearchQuery != null && widget.initialSearchQuery!.isNotEmpty) {
      _searchController.text = widget.initialSearchQuery!;
      // Lancer la recherche automatiquement après un court délai pour laisser l'interface se charger
      Future.delayed(const Duration(milliseconds: 500), () {
        _performInitialSearch(widget.initialSearchQuery!);
      });
    } else {
      // Sinon, obtenir la position actuelle de l'utilisateur
      _getCurrentLocation();
    }
  }

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

  // Nouvelle méthode pour effectuer la recherche initiale
  Future<void> _performInitialSearch(String query) async {
    if (query.isEmpty) return;

    setState(() {
      _isSearching = true;
    });

    try {
      final url = Uri.parse(
        'https://maps.googleapis.com/maps/api/place/autocomplete/json'
        '?input=${Uri.encodeComponent(query)}'
        '&key=$_apiKey'
        '&language=fr'
      );

      final response = await http.get(url);

      if (response.statusCode == 200) {
        final data = json.decode(response.body);
        
        if (data['status'] == 'OK') {
          final predictions = data['predictions'] as List;
          
          if (predictions.isNotEmpty) {
            // Prendre automatiquement la première suggestion
            final firstPrediction = predictions.first;
            final suggestion = PlaceSuggestion(
              placeId: firstPrediction['place_id'],
              description: firstPrediction['description'],
            );
            
            // Effectuer la sélection automatique
            await _selectPlaceForInitialSearch(suggestion);
          } else {
            setState(() {
              _isSearching = false;
            });
          }
        } else {
          setState(() {
            _isSearching = false;
          });
        }
      }
    } catch (e) {
      _showError('Erreur lors de la recherche initiale: $e');
      setState(() {
        _isSearching = false;
      });
    }
  }

  // Version modifiée de _selectPlace pour la recherche initiale
  Future<void> _selectPlaceForInitialSearch(PlaceSuggestion suggestion) async {
    try {
      final url = Uri.parse(
        'https://maps.googleapis.com/maps/api/place/details/json'
        '?place_id=${suggestion.placeId}'
        '&key=$_apiKey'
        '&language=fr',
      );

      final response = await http.get(url);

      if (response.statusCode == 200) {
        final data = json.decode(response.body);
        
        if (data['status'] == 'OK') {
          final location = data['result']['geometry']['location'];
          final lat = location['lat'];
          final lng = location['lng'];
          final name = data['result']['name'];

          final newPosition = LatLng(lat, lng);

          // Ajouter un marqueur pour le lieu recherché
          setState(() {
            // Garder le marqueur de position utilisateur s'il existe
            _markers.removeWhere((m) => m.markerId.value != 'user_location');
            
            // Ajouter le nouveau marqueur de lieu
            _markers.add(
              Marker(
                markerId: MarkerId(suggestion.placeId),
                position: newPosition,
                infoWindow: InfoWindow(title: name),
              ),
            );
            _isSearching = false;
          });

          // Animer la caméra vers le lieu trouvé
          _mapController?.animateCamera(
            CameraUpdate.newLatLngZoom(newPosition, 15),
          );
        }
      }
    } catch (e) {
      _showError('Erreur lors de la sélection du lieu initial: $e');
      setState(() {
        _isSearching = false;
      });
    }
  }

  Future<void> _getCurrentLocation() async {
    setState(() {
      _isLoadingLocation = true;
    });

    try {
      bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
      if (!serviceEnabled) {
        _showError('Veuillez activer les services de localisation');
        setState(() {
          _isLoadingLocation = false;
        });
        return;
      }

      LocationPermission permission = await Geolocator.checkPermission();
      if (permission == LocationPermission.denied) {
        permission = await Geolocator.requestPermission();
        if (permission == LocationPermission.denied) {
          _showError('Permission de localisation refusée');
          setState(() {
            _isLoadingLocation = false;
          });
          return;
        }
      }

      if (permission == LocationPermission.deniedForever) {
        _showError('Permission de localisation refusée définitivement');
        setState(() {
          _isLoadingLocation = false;
        });
        return;
      }

      Position position = await Geolocator.getCurrentPosition(
        locationSettings: const LocationSettings(
          accuracy: LocationAccuracy.high,
        ),
      );

      final newPosition = LatLng(position.latitude, position.longitude);

      setState(() {
        _currentPosition = position;
        _initialPosition = newPosition;
        _isLoadingLocation = false;
      });

      // Créer l'icône personnalisée et ajouter le marqueur
      await _addUserLocationMarker(newPosition);

      if (_mapController != null) {
        _mapController!.animateCamera(
          CameraUpdate.newLatLngZoom(_initialPosition, 15),
        );
      }
    } catch (e) {
      _showError('Erreur lors de la récupération de la position: $e');
      setState(() {
        _isLoadingLocation = false;
      });
    }
  }

  // Créer une icône personnalisée à partir de l'icône Material
  Future<BitmapDescriptor> _createCustomMarkerIcon() async {
    final pictureRecorder = ui.PictureRecorder();
    final canvas = Canvas(pictureRecorder);
    const size = 120.0;

    // Dessiner l'icône person_pin_circle en bleu
    final iconPainter = TextPainter(
      textDirection: TextDirection.ltr,
    );
    iconPainter.text = TextSpan(
      text: String.fromCharCode(Icons.person_pin_circle.codePoint),
      style: TextStyle(
        fontSize: 100,
        fontFamily: Icons.person_pin_circle.fontFamily,
        color: Colors.blue[700],
      ),
    );
    iconPainter.layout();
    iconPainter.paint(
      canvas,
      Offset(
        (size - iconPainter.width) / 2,
        0,
      ),
    );

    final picture = pictureRecorder.endRecording();
    final image = await picture.toImage(size.toInt(), size.toInt());
    final bytes = await image.toByteData(format: ui.ImageByteFormat.png);

    return BitmapDescriptor.fromBytes(bytes!.buffer.asUint8List());
  }

  // Ajouter le marqueur avec l'icône personnalisée
  Future<void> _addUserLocationMarker(LatLng position) async {
    _markers.clear();
    _circles.clear();
    
    // Ajouter un cercle de précision
    _circles.add(
      Circle(
        circleId: const CircleId('user_location_accuracy'),
        center: position,
        radius: _currentPosition?.accuracy ?? 50,
        fillColor: Colors.blue.withValues(alpha: 0.08),
        strokeColor: Colors.blue.withValues(alpha: 0.3),
        strokeWidth: 1,
      ),
    );

    // Créer l'icône personnalisée
    final icon = await _createCustomMarkerIcon();

    // Ajouter le marqueur avec l'icône
    setState(() {
      _markers.add(
        Marker(
          markerId: const MarkerId('user_location'),
          position: position,
          icon: icon,
          anchor: const Offset(0.5, 0.85), // Ancrer au bas de l'icône (le point du pin)
          infoWindow: InfoWindow(
            title: 'Ma position',
            snippet: 'Lat: ${position.latitude.toStringAsFixed(4)}, Lng: ${position.longitude.toStringAsFixed(4)}',
          ),
        ),
      );
    });
  }

  Future<void> _searchPlaces(String query) async {
    if (query.isEmpty) {
      setState(() {
        _suggestions = [];
      });
      return;
    }

    setState(() {
      _isSearching = true;
    });

    try {
      final url = Uri.parse(
        'https://maps.googleapis.com/maps/api/place/autocomplete/json'
        '?input=${Uri.encodeComponent(query)}'
        '&key=$_apiKey'
        '&language=fr'
      );

      final response = await http.get(url);

      if (response.statusCode == 200) {
        final data = json.decode(response.body);
        
        if (data['status'] == 'OK') {
          final predictions = data['predictions'] as List;
          
          setState(() {
            _suggestions = predictions
                .map((p) => PlaceSuggestion(
                      placeId: p['place_id'],
                      description: p['description'],
                    ))
                .toList();
            _isSearching = false;
          });
        } else {
          setState(() {
            _suggestions = [];
            _isSearching = false;
          });
        }
      }
    } catch (e) {
      _showError('Erreur lors de la recherche de lieux: $e');
      setState(() {
        _isSearching = false;
      });
    }
  }

  Future<void> _selectPlace(PlaceSuggestion suggestion) async {
    setState(() {
      _isSearching = true;
      _suggestions = [];
      _searchController.text = suggestion.description;
    });

    try {
      final url = Uri.parse(
        'https://maps.googleapis.com/maps/api/place/details/json'
        '?place_id=${suggestion.placeId}'
        '&key=$_apiKey'
        '&language=fr',
      );

      final response = await http.get(url);

      if (response.statusCode == 200) {
        final data = json.decode(response.body);
        
        if (data['status'] == 'OK') {
          final location = data['result']['geometry']['location'];
          final lat = location['lat'];
          final lng = location['lng'];
          final name = data['result']['name'];

          final newPosition = LatLng(lat, lng);

          // Ajouter un marqueur pour le lieu recherché (ne pas supprimer le marqueur de position)
          setState(() {
            // Garder le marqueur de position utilisateur
            _markers.removeWhere((m) => m.markerId.value != 'user_location');
            
            // Ajouter le nouveau marqueur de lieu
            _markers.add(
              Marker(
                markerId: MarkerId(suggestion.placeId),
                position: newPosition,
                infoWindow: InfoWindow(title: name),
              ),
            );
            _isSearching = false;
          });

          _mapController?.animateCamera(
            CameraUpdate.newLatLngZoom(newPosition, 15),
          );

          FocusScope.of(context).unfocus();
        }
      }
    } catch (e) {
      _showError('Erreur lors de la sélection du lieu: $e');
      setState(() {
        _isSearching = false;
      });
    }
  }

  void _showError(String message) {
    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(message),
          backgroundColor: Colors.red,
          behavior: SnackBarBehavior.floating,
        ),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Stack(
          children: [
            // Google Maps en arrière-plan
            Positioned.fill(
              child: Padding(
                padding: const EdgeInsets.all(12.0),
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(16),
                  child: GoogleMap(
                    initialCameraPosition: CameraPosition(
                      target: _initialPosition,
                      zoom: 14,
                    ),
                    onMapCreated: (GoogleMapController controller) {
                      _mapController = controller;
                    },
                    markers: _markers,
                    circles: _circles,
                    myLocationEnabled: false,
                    myLocationButtonEnabled: false,
                    zoomControlsEnabled: false,
                    mapType: MapType.normal,
                    compassEnabled: true,
                    rotateGesturesEnabled: true,
                    scrollGesturesEnabled: true,
                    tiltGesturesEnabled: true,
                    zoomGesturesEnabled: true,
                    onTap: (_) {
                      setState(() {
                        _suggestions = [];
                      });
                      FocusScope.of(context).unfocus();
                    },
                  ),
                ),
              ),
            ),

            // Indicateur de chargement
            if (_isLoadingLocation)
              Positioned.fill(
                child: Container(
                  color: Colors.black.withValues(alpha: 0.3),
                  child: Center(
                    child: Container(
                      padding: const EdgeInsets.all(20),
                      decoration: BoxDecoration(
                        color: Colors.white,
                        borderRadius: BorderRadius.circular(12),
                        boxShadow: [
                          BoxShadow(
                            color: Colors.black.withValues(alpha: 0.1),
                            blurRadius: 10,
                            spreadRadius: 2,
                          ),
                        ],
                      ),
                      child: const Column(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          CircularProgressIndicator(),
                          SizedBox(height: 12),
                          Text(
                            'Localisation en cours...',
                            style: TextStyle(
                              fontSize: 14,
                              fontWeight: FontWeight.w500,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
              ),

            // Barre de recherche et suggestions
            Positioned(
              top: 0,
              left: 0,
              right: 0,
              child: Padding(
                padding: const EdgeInsets.all(12.0),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    // Champ de recherche
                    Container(
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(12),
                        boxShadow: [
                          BoxShadow(
                            color: Colors.black.withValues(alpha: 0.15),
                            blurRadius: 8,
                            offset: const Offset(0, 2),
                          ),
                        ],
                      ),
                      child: TextField(
                        controller: _searchController,
                        style: const TextStyle(
                          color: Colors.black87,
                          fontSize: 16,
                        ),
                        decoration: InputDecoration(
                          hintText: 'Rechercher un lieu...',
                          hintStyle: TextStyle(
                            color: Colors.grey[600],
                            fontSize: 16,
                          ),
                          prefixIcon: _isSearching
                              ? const Padding(
                                  padding: EdgeInsets.all(14.0),
                                  child: SizedBox(
                                    width: 20,
                                    height: 20,
                                    child: CircularProgressIndicator(
                                      strokeWidth: 2,
                                    ),
                                  ),
                                )
                              : Icon(Icons.search, color: Colors.grey[700]),
                          suffixIcon: _searchController.text.isNotEmpty
                              ? IconButton(
                                  icon: Icon(Icons.clear, color: Colors.grey[700]),
                                  onPressed: () {
                                    _searchController.clear();
                                    setState(() {
                                      _suggestions = [];
                                    });
                                  },
                                )
                              : null,
                          border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(12.0),
                            borderSide: BorderSide.none,
                          ),
                          filled: true,
                          fillColor: Colors.white,
                          contentPadding: const EdgeInsets.symmetric(
                            horizontal: 16,
                            vertical: 14,
                          ),
                        ),
                        onChanged: (value) {
                          // Ne pas rechercher si c'est juste le remplissage initial
                          if (widget.initialSearchQuery != null && value == widget.initialSearchQuery) {
                            return;
                          }
                          _searchPlaces(value);
                        },
                      ),
                    ),

                    // Liste des suggestions
                    if (_suggestions.isNotEmpty)
                      Container(
                        margin: const EdgeInsets.only(top: 8),
                        constraints: BoxConstraints(
                          maxHeight: MediaQuery.of(context).size.height * 0.4,
                        ),
                        decoration: BoxDecoration(
                          color: Colors.white,
                          borderRadius: BorderRadius.circular(12),
                          boxShadow: [
                            BoxShadow(
                              color: Colors.black.withValues(alpha: 0.15),
                              blurRadius: 10,
                              offset: const Offset(0, 4),
                            ),
                          ],
                        ),
                        child: ClipRRect(
                          borderRadius: BorderRadius.circular(12),
                          child: Material(
                            color: Colors.transparent,
                            child: ListView.separated(
                              shrinkWrap: true,
                              padding: EdgeInsets.zero,
                              itemCount: _suggestions.length,
                              separatorBuilder: (context, index) => Divider(
                                height: 1,
                                color: Colors.grey[300],
                              ),
                              itemBuilder: (context, index) {
                                final suggestion = _suggestions[index];
                                return InkWell(
                                  onTap: () => _selectPlace(suggestion),
                                  child: Padding(
                                    padding: const EdgeInsets.symmetric(
                                      horizontal: 16,
                                      vertical: 12,
                                    ),
                                    child: Row(
                                      children: [
                                        Icon(
                                          Icons.place,
                                          color: Colors.grey[600],
                                          size: 22,
                                        ),
                                        const SizedBox(width: 12),
                                        Expanded(
                                          child: Text(
                                            suggestion.description,
                                            style: const TextStyle(
                                              fontSize: 15,
                                              color: Colors.black87,
                                              fontWeight: FontWeight.w400,
                                            ),
                                            maxLines: 2,
                                            overflow: TextOverflow.ellipsis,
                                          ),
                                        ),
                                      ],
                                    ),
                                  ),
                                );
                              },
                            ),
                          ),
                        ),
                      ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),

      floatingActionButton: FloatingActionButton(
        onPressed: _getCurrentLocation,
        tooltip: 'Ma position',
        child: const Icon(Icons.my_location),
      ),
    );
  }
}

class PlaceSuggestion {
  final String placeId;
  final String description;

  PlaceSuggestion({
    required this.placeId,
    required this.description,
  });
}