import 'dart:convert';
import 'dart:async'; // Necessario per il Timeout
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:http/http.dart' as http;
import 'package:url_launcher/url_launcher.dart';

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

  @override
  State<CarroAttrezziScreen> createState() => _CarroAttrezziScreenState();
}

class _CarroAttrezziScreenState extends State<CarroAttrezziScreen> {
  List<dynamic> _officine = [];
  bool _isLoading = true;
  String _statusMessage = "Attivazione GPS...";

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

  Future<void> _avviaRicercaSicura() async {
    // Piccolo ritardo iniziale per dare tempo alla UI di disegnarsi
    await Future.delayed(const Duration(milliseconds: 500));
    if (!mounted) return;
    _cercaSoccorsiVicini();
  }

  Future<void> _cercaSoccorsiVicini() async {
    try {
      // 1. GESTIONE PERMESSI ROBUSTA
      bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
      if (!serviceEnabled) {
        if (!mounted) return;
        setState(() {
          _statusMessage = "Attiva il GPS per trovare i soccorsi.";
          _isLoading = false;
        });
        return;
      }

      LocationPermission permission = await Geolocator.checkPermission();
      if (permission == LocationPermission.denied) {
        permission = await Geolocator.requestPermission();
        if (permission == LocationPermission.denied) {
          if (!mounted) return;
          setState(() {
            _statusMessage = "Permesso GPS negato.";
            _isLoading = false;
          });
          return;
        }
      }

      if (permission == LocationPermission.deniedForever) {
        if (!mounted) return;
        setState(() {
          _statusMessage = "Permessi GPS bloccati permanentemente.";
          _isLoading = false;
        });
        return;
      }

      // 2. CICLO WHILE PER OTTENERE LA POSIZIONE (WAIT FOR GPS)
      if (mounted) setState(() => _statusMessage = "Ricerca posizione in corso...");

      Position? position;
      int tentativi = 0;
      const int maxTentativi = 3; // Prova 3 volte prima di arrendersi

      // FINCHÉ non ho la posizione E non ho superato i tentativi...
      while (position == null && tentativi < maxTentativi) {
        try {
          if (tentativi > 0) {
            if (mounted) setState(() => _statusMessage = "Aggancio satelliti (Tentativo ${tentativi + 1}/$maxTentativi)...");
          }

          // Prova a prendere la posizione con un timeout di 6 secondi per tentativo
          position = await Geolocator.getCurrentPosition(
            desiredAccuracy: LocationAccuracy.high,
            timeLimit: const Duration(seconds: 6),
          );
        } catch (e) {
          // Se fallisce, aspetta 1 secondo e riprova
          tentativi++;
          await Future.delayed(const Duration(seconds: 1));
        }
      }

      // Se dopo il ciclo while è ancora null, proviamo l'ultima posizione nota
      if (position == null) {
        if (mounted) setState(() => _statusMessage = "Segnale debole, uso ultima posizione...");
        position = await Geolocator.getLastKnownPosition();
      }

      // Se è ancora null, alziamo bandiera bianca
      if (position == null) {
        throw "Impossibile ottenere la posizione GPS dopo vari tentativi.";
      }

      // 3. RICERCA SU OVERPASS API (OSM)
      if (mounted) setState(() => _statusMessage = "Ricerca soccorsi nei paraggi...");

      String query = """
        [out:json][timeout:25];
        (
          node["craft"="car_repair"](around:15000,${position.latitude},${position.longitude});
          node["shop"="car_repair"](around:15000,${position.latitude},${position.longitude});
          node["service"="vehicle_recovery"](around:15000,${position.latitude},${position.longitude});
        );
        out body;
      """;

      final url = Uri.parse('https://overpass-api.de/api/interpreter?data=${Uri.encodeComponent(query)}');

      final response = await http.get(
        url,
        headers: {'User-Agent': 'CidApp_Flutter/1.0'},
      ).timeout(const Duration(seconds: 20));

      if (response.statusCode == 200) {
        final data = json.decode(response.body);
        List<dynamic> elements = data['elements'];
        List<Map<String, dynamic>> listaElaborata = [];

        for (var element in elements) {
          if (element['tags'] != null && element['tags']['name'] != null) {

            double distanzaMetri = Geolocator.distanceBetween(
                position!.latitude, position.longitude, element['lat'], element['lon']
            );

            listaElaborata.add({
              'name': element['tags']['name'],
              'phone': element['tags']['phone'] ?? element['tags']['contact:phone'] ?? element['tags']['mobile'],
              'street': element['tags']['addr:street'] ?? "",
              'city': element['tags']['addr:city'] ?? "",
              'distance': distanzaMetri,
              'lat': element['lat'],
              'lon': element['lon'],
            });
          }
        }

        listaElaborata.sort((a, b) => (a['distance'] as double).compareTo(b['distance'] as double));

        if (mounted) {
          setState(() {
            _officine = listaElaborata;
            _isLoading = false;
          });
        }
      } else {
        throw "Errore server OSM: ${response.statusCode}";
      }
    } catch (e) {
      if (mounted) {
        setState(() {
          _statusMessage = "Nessun soccorso trovato o errore GPS.\nRiprova tra poco.";
          _isLoading = false;
        });
      }
    }
  }

  Future<void> _chiamaNumero(String? numero) async {
    if (numero == null) return;
    // Pulisce il numero da spazi o caratteri strani
    final pulito = numero.replaceAll(RegExp(r'[^0-9+]'), '');
    final Uri url = Uri.parse("tel:$pulito");
    if (await canLaunchUrl(url)) await launchUrl(url);
  }

  Future<void> _apriMappa(double lat, double lon) async {
    // Link universale per aprire la navigazione
    final Uri url = Uri.parse("https://www.google.com/maps/search/?api=1&query=$lat,$lon");

    try {
      if (await canLaunchUrl(url)) {
        await launchUrl(url, mode: LaunchMode.externalApplication);
      } else {
        throw 'Impossibile aprire la mappa';
      }
    } catch (e) {
      debugPrint("Errore apertura mappa: $e");
    }
  }

  Future<void> _cercaSuGoogle(String nome) async {
    final Uri url = Uri.parse("https://www.google.com/search?q=soccorso stradale $nome telefono");
    if (await canLaunchUrl(url)) await launchUrl(url, mode: LaunchMode.externalApplication);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Soccorso Stradale"),
        backgroundColor: Colors.red.shade800,
        foregroundColor: Colors.white,
      ),
      body: _isLoading
          ? Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const CircularProgressIndicator(color: Colors.red),
            const SizedBox(height: 20),
            Text(_statusMessage, style: const TextStyle(color: Colors.grey)),
          ],
        ),
      )
          : _officine.isEmpty
          ? Center(
        child: Padding(
          padding: const EdgeInsets.all(20.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const Icon(Icons.car_crash, size: 60, color: Colors.grey),
              const SizedBox(height: 10),
              const Text("Nessun soccorso trovato nei paraggi (15km).", textAlign: TextAlign.center),
              const SizedBox(height: 20),
              ElevatedButton(
                onPressed: () => _cercaSuGoogle("vicino a me"),
                child: const Text("Cerca su Google"),
              )
            ],
          ),
        ),
      )
          : ListView.builder(
        padding: const EdgeInsets.all(10),
        itemCount: _officine.length,
        itemBuilder: (context, index) {
          final officina = _officine[index];
          double km = (officina['distance'] as double) / 1000;

          String indirizzo = officina['street'];
          if (officina['city'] != "") indirizzo += (indirizzo.isNotEmpty ? ", " : "") + officina['city'];
          if (indirizzo.isEmpty) indirizzo = "Posizione GPS";

          return Card(
            elevation: 3,
            margin: const EdgeInsets.only(bottom: 12),
            shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
            child: Padding(
              padding: const EdgeInsets.symmetric(vertical: 8.0),
              child: ListTile(
                // KM a sinistra
                leading: Container(
                  width: 55,
                  height: 55,
                  decoration: BoxDecoration(
                      color: Colors.red.shade50,
                      borderRadius: BorderRadius.circular(8),
                      border: Border.all(color: Colors.red.shade100)
                  ),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Icon(Icons.location_on, color: Colors.red.shade700, size: 24),
                      Text("${km.toStringAsFixed(1)} km", style: const TextStyle(fontSize: 10, fontWeight: FontWeight.bold), maxLines: 1),
                    ],
                  ),
                ),
                title: Text(officina['name'], style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16)),
                subtitle: Text(indirizzo, style: const TextStyle(fontSize: 13), maxLines: 2, overflow: TextOverflow.ellipsis),

                // DUE TASTI A DESTRA: MAPPA e CHIAMA
                trailing: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    // Tasto MAPPA
                    IconButton(
                      icon: const Icon(Icons.directions, color: Colors.blue, size: 32),
                      onPressed: () => _apriMappa(officina['lat'], officina['lon']),
                      tooltip: "Naviga",
                    ),
                    // Tasto CHIAMA
                    officina['phone'] != null
                        ? IconButton(
                      icon: const Icon(Icons.phone_in_talk, color: Colors.green, size: 32),
                      onPressed: () => _chiamaNumero(officina['phone']),
                    )
                        : IconButton(
                      icon: const Icon(Icons.search, color: Colors.orange, size: 32),
                      onPressed: () => _cercaSuGoogle(officina['name']),
                      tooltip: "Cerca Web",
                    ),
                  ],
                ),
              ),
            ),
          );
        },
      ),
    );
  }
}