import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:http/http.dart' as http;
import 'package:prosapp_web_app/services/api_service.dart';
import 'package:prosapp_web_app/services/maps_service.dart';

class LocationResult {
  final LatLng position;
  final String address;
  final String city;

  const LocationResult({required this.position, required this.address, required this.city});
}

class LocationPickerDialog extends StatefulWidget {
  final LatLng? initialPosition;

  const LocationPickerDialog({super.key, this.initialPosition});

  static Future<LocationResult?> show(BuildContext context, {LatLng? initialPosition}) {
    return showDialog<LocationResult>(
      context: context,
      barrierDismissible: false,
      builder: (_) => LocationPickerDialog(initialPosition: initialPosition),
    );
  }

  @override
  State<LocationPickerDialog> createState() => _LocationPickerDialogState();
}

class _LocationPickerDialogState extends State<LocationPickerDialog> {
  GoogleMapController? _mapController;
  LatLng _position = const LatLng(4.6097, -74.0817); // Bogotá por defecto
  String _address = '';
  String _city = '';
  bool _loading = true;
  bool _geocoding = false;
  bool _mapsReady = false;
  String? _mapsError;

  @override
  void initState() {
    super.initState();
    _initMaps();
  }

  Future<void> _initMaps() async {
    final ok = await MapsService.load();
    if (!mounted) return;
    if (!ok) {
      setState(() { _loading = false; _mapsError = 'Google Maps no configurado. Configura la API Key en el panel de administración.'; });
      return;
    }
    setState(() => _mapsReady = true);
    if (widget.initialPosition != null) {
      _position = widget.initialPosition!;
      _loading = false;
      _reverseGeocode(_position);
    } else {
      _detectLocation();
    }
  }

  Future<void> _detectLocation() async {
    setState(() => _loading = true);
    try {
      bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
      if (!serviceEnabled) {
        _useFallback();
        return;
      }

      LocationPermission permission = await Geolocator.checkPermission();
      if (permission == LocationPermission.denied) {
        permission = await Geolocator.requestPermission();
        if (permission == LocationPermission.denied) {
          _useFallback();
          return;
        }
      }

      if (permission == LocationPermission.deniedForever) {
        _useFallback();
        return;
      }

      final pos = await Geolocator.getCurrentPosition(
        locationSettings: const LocationSettings(accuracy: LocationAccuracy.medium, timeLimit: Duration(seconds: 8)),
      );
      _position = LatLng(pos.latitude, pos.longitude);
      await _reverseGeocode(_position);
    } catch (_) {
      _useFallback();
    } finally {
      if (mounted) setState(() => _loading = false);
    }
  }

  void _useFallback() {
    // Colombia por defecto
    _position = const LatLng(4.6097, -74.0817);
    _address = '';
    _city = '';
    if (mounted) setState(() => _loading = false);
  }

  Future<void> _reverseGeocode(LatLng pos) async {
    final keyData = await ApiService.instance.get('/settings/maps-key').catchError((_) => <String, dynamic>{});
    final apiKey = keyData['api_key'] as String? ?? '';
    if (apiKey.isEmpty) return;
    setState(() => _geocoding = true);
    try {
      final url = Uri.parse(
        'https://maps.googleapis.com/maps/api/geocode/json'
        '?latlng=${pos.latitude},${pos.longitude}'
        '&key=$apiKey'
        '&language=es',
      );
      final res = await http.get(url);
      if (res.statusCode == 200) {
        final data = jsonDecode(res.body);
        if (data['results'] != null && data['results'].isNotEmpty) {
          final result = data['results'][0];
          _address = result['formatted_address'] ?? '';
          _city = _extractCity(result['address_components'] ?? []);
        }
      }
    } catch (_) {}
    if (mounted) setState(() => _geocoding = false);
  }

  String _extractCity(List components) {
    for (final c in components) {
      final types = List<String>.from(c['types'] ?? []);
      if (types.contains('locality') || types.contains('administrative_area_level_2')) {
        return c['long_name'] ?? '';
      }
    }
    return '';
  }

  void _onMapTap(LatLng pos) {
    setState(() => _position = pos);
    _reverseGeocode(pos);
    _mapController?.animateCamera(CameraUpdate.newLatLng(pos));
  }

  @override
  Widget build(BuildContext context) {
    return Dialog(
      insetPadding: const EdgeInsets.all(16),
      child: SizedBox(
        width: 600,
        height: 520,
        child: Column(
          children: [
            // Header
            Container(
              padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
              decoration: const BoxDecoration(
                gradient: LinearGradient(colors: [Color(0xFF42A4EF), Color(0xFF1565C0)]),
                borderRadius: BorderRadius.vertical(top: Radius.circular(12)),
              ),
              child: Row(
                children: [
                  const Icon(Icons.location_on, color: Colors.white, size: 20),
                  const SizedBox(width: 8),
                  const Expanded(
                    child: Text('Selecciona tu ubicación',
                        style: TextStyle(color: Colors.white, fontWeight: FontWeight.w600, fontSize: 15)),
                  ),
                  IconButton(
                    icon: const Icon(Icons.close, color: Colors.white, size: 20),
                    onPressed: () => Navigator.pop(context),
                    padding: EdgeInsets.zero,
                    constraints: const BoxConstraints(),
                  ),
                ],
              ),
            ),

            // Map
            Expanded(
              child: _mapsError != null
                  ? Center(child: Padding(
                      padding: const EdgeInsets.all(24),
                      child: Column(mainAxisSize: MainAxisSize.min, children: [
                        const Icon(Icons.map_outlined, size: 48, color: Colors.grey),
                        const SizedBox(height: 12),
                        Text(_mapsError!, textAlign: TextAlign.center, style: const TextStyle(color: Colors.grey)),
                      ]),
                    ))
                  : _loading
                  ? const Center(child: CircularProgressIndicator())
                  : Stack(
                      children: [
                        GoogleMap(
                          initialCameraPosition: CameraPosition(target: _position, zoom: 15),
                          onMapCreated: (c) => _mapController = c,
                          onTap: _onMapTap,
                          markers: {
                            Marker(
                              markerId: const MarkerId('selected'),
                              position: _position,
                              draggable: true,
                              onDragEnd: (pos) {
                                setState(() => _position = pos);
                                _reverseGeocode(pos);
                              },
                            ),
                          },
                          myLocationEnabled: true,
                          myLocationButtonEnabled: true,
                          zoomControlsEnabled: true,
                        ),
                        if (_geocoding)
                          const Positioned(
                            top: 8, left: 0, right: 0,
                            child: Center(
                              child: Card(
                                child: Padding(
                                  padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
                                  child: Row(
                                    mainAxisSize: MainAxisSize.min,
                                    children: [
                                      SizedBox(width: 14, height: 14, child: CircularProgressIndicator(strokeWidth: 2)),
                                      SizedBox(width: 8),
                                      Text('Obteniendo dirección...', style: TextStyle(fontSize: 12)),
                                    ],
                                  ),
                                ),
                              ),
                            ),
                          ),
                      ],
                    ),
            ),

            // Address preview + confirm
            Container(
              padding: const EdgeInsets.all(12),
              decoration: BoxDecoration(
                color: Colors.grey[50],
                border: const Border(top: BorderSide(color: Color(0xFFE0E0E0))),
              ),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisSize: MainAxisSize.min,
                children: [
                  if (_address.isNotEmpty) ...[
                    Text(_address, style: const TextStyle(fontSize: 12, color: Colors.black87)),
                    const SizedBox(height: 8),
                  ],
                  if (_address.isEmpty && !_loading)
                    const Text('Toca el mapa para seleccionar una dirección',
                        style: TextStyle(fontSize: 12, color: Colors.grey)),
                  const SizedBox(height: 4),
                  SizedBox(
                    width: double.infinity,
                    child: ElevatedButton(
                      onPressed: (_loading || _geocoding)
                          ? null
                          : () => Navigator.pop(
                                context,
                                LocationResult(position: _position, address: _address, city: _city),
                              ),
                      style: ElevatedButton.styleFrom(
                        backgroundColor: const Color(0xFF42A4EF),
                        foregroundColor: Colors.white,
                        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
                      ),
                      child: const Text('Confirmar ubicación'),
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

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