import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:http/http.dart' as http;
import 'package:prosapp_web_app/providers/auth_provider.dart';
import 'package:prosapp_web_app/providers/theme_provider.dart';
import 'package:prosapp_web_app/router/router.dart';
import 'package:prosapp_web_app/services/api_service.dart';
import 'package:prosapp_web_app/services/navigation_service.dart';
import 'package:provider/provider.dart';

class SetupCityView extends StatefulWidget {
  const SetupCityView({super.key});

  @override
  State<SetupCityView> createState() => _SetupCityViewState();
}

class _SetupCityViewState extends State<SetupCityView> {
  List<String> _cities = [];
  String? _selected;
  String? _detected;       // nombre detectado por GPS
  bool _detectedInList = false; // si la ciudad GPS está en la lista
  bool _loadingCities = true;
  bool _detectingGps = true;
  bool _saving = false;

  @override
  void initState() {
    super.initState();
    _loadCities();
    _detectCity();
  }

  Future<void> _loadCities() async {
    try {
      final data = await ApiService.instance.get('/locations/cities/all');
      final list = (data as List).map((c) => c['name'] as String).toList();
      if (mounted) {
        setState(() {
          _cities = list;
          _loadingCities = false;
          if (_detected != null) _tryPreselect(_detected!);
        });
      }
    } catch (_) {
      if (mounted) setState(() => _loadingCities = false);
    }
  }

  Future<void> _detectCity() async {
    setState(() => _detectingGps = true);
    try {
      LocationPermission perm = await Geolocator.checkPermission();
      if (perm == LocationPermission.denied) {
        perm = await Geolocator.requestPermission();
      }
      if (perm == LocationPermission.deniedForever ||
          perm == LocationPermission.denied) {
        if (mounted) setState(() => _detectingGps = false);
        return;
      }

      final pos = await Geolocator.getCurrentPosition(
        locationSettings: const LocationSettings(
          accuracy: LocationAccuracy.low,
          timeLimit: Duration(seconds: 8),
        ),
      );

      final url = Uri.parse(
        'https://nominatim.openstreetmap.org/reverse'
        '?format=json&lat=${pos.latitude}&lon=${pos.longitude}&zoom=10&addressdetails=1',
      );
      final resp = await http.get(url,
          headers: {'User-Agent': 'ProsApp/1.0 (prosapp.co)'});

      if (resp.statusCode == 200) {
        final json = jsonDecode(resp.body) as Map<String, dynamic>;
        final address = json['address'] as Map<String, dynamic>?;
        final city = address?['city'] as String? ??
            address?['town'] as String? ??
            address?['municipality'] as String? ??
            address?['county'] as String?;

        if (city != null && city.isNotEmpty && mounted) {
          setState(() => _detected = city);
          if (!_loadingCities) _tryPreselect(city);
        }
      }
    } catch (_) {
      // GPS no disponible
    } finally {
      if (mounted) setState(() => _detectingGps = false);
    }
  }

  void _tryPreselect(String detectedCity) {
    final normalized = detectedCity.toLowerCase().trim();
    String? match = _cities.firstWhere(
      (c) => c.toLowerCase() == normalized,
      orElse: () => '',
    );
    if (match!.isEmpty) {
      match = _cities.firstWhere(
        (c) =>
            c.toLowerCase().contains(normalized) ||
            normalized.contains(c.toLowerCase()),
        orElse: () => '',
      );
    }
    if (match.isNotEmpty) {
      setState(() {
        _selected = match;
        _detectedInList = true;
      });
    } else {
      setState(() {
        _detectedInList = false;
        _selected = null;
      });
    }
  }

  Future<void> _save() async {
    if (_selected == null) return;
    setState(() => _saving = true);
    try {
      await context.read<AuthProvider>().updateCity(_selected!);
      if (mounted) NavigationService.replaceTo(Flurorouter.dashboardRoute);
    } catch (_) {
      if (mounted) setState(() => _saving = false);
    }
  }

  void _skip() => NavigationService.replaceTo(Flurorouter.dashboardRoute);

  @override
  Widget build(BuildContext context) {
    final isDark = context.watch<ThemeProvider>().isDark;
    final cardBg = isDark ? const Color(0xFF1E293B) : Colors.white;
    final border = isDark ? const Color(0xFF334155) : const Color(0xFFE5E7EB);
    final textPrimary = isDark ? Colors.white : const Color(0xFF111827);
    final textSec = isDark ? const Color(0xFF94A3B8) : const Color(0xFF6B7280);

    // Ciudad GPS detectada pero no está en la lista
    final bool unavailable =
        _detected != null && !_detectingGps && !_loadingCities && !_detectedInList;

    return Center(
      child: ConstrainedBox(
        constraints: const BoxConstraints(maxWidth: 440),
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 32),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              // ── Header ──────────────────────────────────────────────────────
              Column(
                children: [
                  Container(
                    width: 64, height: 64,
                    decoration: BoxDecoration(
                      color: const Color(0xFF42A4EF).withOpacity(0.12),
                      shape: BoxShape.circle,
                    ),
                    child: const Icon(Icons.location_city_rounded,
                        color: Color(0xFF42A4EF), size: 32),
                  ),
                  const SizedBox(height: 14),
                  Text('¿En qué ciudad estás?',
                      style: TextStyle(
                          fontSize: 21,
                          fontWeight: FontWeight.bold,
                          color: textPrimary),
                      textAlign: TextAlign.center),
                  const SizedBox(height: 5),
                  Text('Selecciona una de las ciudades disponibles.',
                      style: TextStyle(fontSize: 13, color: textSec),
                      textAlign: TextAlign.center),
                ],
              ),

              const SizedBox(height: 18),

              // ── Banner GPS ──────────────────────────────────────────────────
              if (_detectingGps)
                _Banner(
                  color: const Color(0xFF42A4EF),
                  icon: null,
                  loading: true,
                  text: 'Detectando tu ubicación...',
                )
              else if (_detected != null && _detectedInList)
                _Banner(
                  color: const Color(0xFF10B981),
                  icon: Icons.my_location,
                  text: 'Tu ubicación: $_detected — disponible ✓',
                )
              else if (unavailable)
                _Banner(
                  color: const Color(0xFFF59E0B),
                  icon: Icons.location_off_outlined,
                  text:
                      'El servicio aún no está disponible en "$_detected". Selecciona una ciudad disponible.',
                  multiline: true,
                ),

              if (_detectingGps || _detected != null) const SizedBox(height: 12),

              // ── Lista de ciudades ────────────────────────────────────────────
              Expanded(
                child: _loadingCities
                    ? const Center(child: CircularProgressIndicator())
                    : _cities.isEmpty
                        ? Center(
                            child: Text('No hay ciudades disponibles.',
                                style: TextStyle(color: textSec)),
                          )
                        : Container(
                            decoration: BoxDecoration(
                              color: cardBg,
                              borderRadius: BorderRadius.circular(14),
                              border: Border.all(color: border),
                            ),
                            child: ClipRRect(
                              borderRadius: BorderRadius.circular(14),
                              child: ListView.separated(
                                itemCount: _cities.length,
                                separatorBuilder: (_, __) =>
                                    Divider(height: 1, color: border),
                                itemBuilder: (_, i) {
                                  final city = _cities[i];
                                  final isSelected = city == _selected;
                                  final isGps = city == _detected;
                                  return InkWell(
                                    onTap: () =>
                                        setState(() => _selected = city),
                                    child: AnimatedContainer(
                                      duration:
                                          const Duration(milliseconds: 150),
                                      color: isSelected
                                          ? const Color(0xFF42A4EF)
                                              .withOpacity(0.10)
                                          : Colors.transparent,
                                      padding: const EdgeInsets.symmetric(
                                          horizontal: 18, vertical: 16),
                                      child: Row(
                                        children: [
                                          Icon(
                                            Icons.location_on_outlined,
                                            size: 18,
                                            color: isSelected
                                                ? const Color(0xFF42A4EF)
                                                : textSec,
                                          ),
                                          const SizedBox(width: 12),
                                          Expanded(
                                            child: Text(
                                              city,
                                              style: TextStyle(
                                                fontSize: 15,
                                                fontWeight: isSelected
                                                    ? FontWeight.w600
                                                    : FontWeight.normal,
                                                color: isSelected
                                                    ? const Color(0xFF42A4EF)
                                                    : textPrimary,
                                              ),
                                            ),
                                          ),
                                          if (isGps && !isSelected)
                                            Container(
                                              margin: const EdgeInsets.only(
                                                  right: 8),
                                              padding:
                                                  const EdgeInsets.symmetric(
                                                      horizontal: 7,
                                                      vertical: 2),
                                              decoration: BoxDecoration(
                                                color: const Color(0xFF10B981)
                                                    .withOpacity(0.12),
                                                borderRadius:
                                                    BorderRadius.circular(4),
                                              ),
                                              child: const Text('GPS',
                                                  style: TextStyle(
                                                      fontSize: 10,
                                                      color:
                                                          Color(0xFF10B981),
                                                      fontWeight:
                                                          FontWeight.bold)),
                                            ),
                                          if (isSelected)
                                            const Icon(
                                                Icons.check_circle_rounded,
                                                size: 20,
                                                color: Color(0xFF42A4EF)),
                                        ],
                                      ),
                                    ),
                                  );
                                },
                              ),
                            ),
                          ),
              ),

              const SizedBox(height: 14),

              // ── Botón guardar ────────────────────────────────────────────────
              SizedBox(
                height: 48,
                child: ElevatedButton(
                  style: ElevatedButton.styleFrom(
                    backgroundColor: const Color(0xFF42A4EF),
                    foregroundColor: Colors.white,
                    disabledBackgroundColor:
                        const Color(0xFF42A4EF).withOpacity(0.35),
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(12)),
                    elevation: 0,
                  ),
                  onPressed: _selected != null && !_saving ? _save : null,
                  child: _saving
                      ? const SizedBox(
                          width: 20, height: 20,
                          child: CircularProgressIndicator(
                              strokeWidth: 2, color: Colors.white))
                      : Text(
                          _selected != null
                              ? 'Continuar con $_selected'
                              : 'Selecciona una ciudad',
                          style: const TextStyle(
                              fontSize: 14, fontWeight: FontWeight.w600),
                        ),
                ),
              ),

              const SizedBox(height: 8),

              TextButton(
                onPressed: _skip,
                child: Text('Omitir por ahora',
                    style: TextStyle(color: textSec, fontSize: 12)),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class _Banner extends StatelessWidget {
  final Color color;
  final IconData? icon;
  final String text;
  final bool loading;
  final bool multiline;

  const _Banner({
    required this.color,
    required this.text,
    this.icon,
    this.loading = false,
    this.multiline = false,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
      decoration: BoxDecoration(
        color: color.withOpacity(0.08),
        borderRadius: BorderRadius.circular(10),
        border: Border.all(color: color.withOpacity(0.3)),
      ),
      child: Row(
        crossAxisAlignment: multiline
            ? CrossAxisAlignment.start
            : CrossAxisAlignment.center,
        children: [
          if (loading)
            SizedBox(
              width: 14, height: 14,
              child: CircularProgressIndicator(
                  strokeWidth: 2, color: color),
            )
          else if (icon != null)
            Icon(icon, size: 16, color: color),
          const SizedBox(width: 10),
          Expanded(
            child: Text(text,
                style: TextStyle(
                    fontSize: 12,
                    color: color,
                    fontWeight: FontWeight.w500,
                    height: 1.4)),
          ),
        ],
      ),
    );
  }
}
