import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import 'package:geolocator/geolocator.dart';
import 'package:flutter_tts/flutter_tts.dart';
import '../services/weather_service.dart';
import '../utils/navigation_helper.dart';
import '../utils/session_manager.dart';
import '../utils/api_config.dart';

enum NavStatus { waiting, readyToStart, active, paused, finished }

class NavigationScreen extends StatefulWidget {
  final Map<String, dynamic> routeData;
  final int targetMinutes;

  NavigationScreen({super.key, required this.routeData, required this.targetMinutes});

  @override
  State<NavigationScreen> createState() => _NavigationScreenState();
}

class _NavigationScreenState extends State<NavigationScreen> {
  final MapController _mapController = MapController();
  final WeatherService _weatherService = WeatherService();
  
  List<LatLng> _routePoints = [];
  LatLng? _currentPosition;
  Map<String, dynamic>? _weatherData;
  StreamSubscription<Position>? _positionStream;
  bool _isLoading = true;
  bool _isFollowingUser = true; // Mode auto-center

  // --- Fitur Navigasi ---
  final FlutterTts _tts = FlutterTts();
  NavStatus _navStatus = NavStatus.waiting;
  int _targetPointIndex = 0;
  bool _isOffRoute = false;
  String _nextInstruction = "Mencari Rute...";
  int _lastManeuverIndex = -1;
  DateTime? _lastAlertTime;
  double _distanceToNextTurn = 0;
  bool _isRouteReversed = false;
  int _lastReachedIndex = 0;
  bool _directionDetected = false;
  bool _isCircular = true; // Default rute melingkar
  bool _isRaining = false;
  bool _rainWarningSpoken = false;
  bool _dryWarningSpoken = false;
  int _rainWarningCount = 0;
  int _dryWarningCount = 0;

  // --- Real-time Stats ---
  double _remainingDistance = 0;
  int _remainingSeconds = 0;
  int _elapsedSeconds = 0;
  double _accumulatedDistance = 0;
  LatLng? _lastTrackedPosition;
  Timer? _timer;
  Timer? _weatherTimer; // Timer khusus untuk refresh cuaca periodik
  LatLng? _pausePosition; // Titik di mana perjalanan dijeda

  @override
  void initState() {
    super.initState();
    _initTTS();
    _parseRoutePoints();
    _initLocationTracking();
    
    // Set sisa jarak awal
    _remainingDistance = double.tryParse(widget.routeData['jarak'].toString()) ?? 0;
    // Set sisa waktu awal (detik)
    _remainingSeconds = widget.targetMinutes * 60;
    _elapsedSeconds = 0;
    // Aktifkan refresh cuaca otomatis setiap 5 menit (300 detik)
    _weatherTimer = Timer.periodic(const Duration(minutes: 5), (timer) {
      if (_currentPosition != null) {
        _fetchWeather(_currentPosition!.latitude, _currentPosition!.longitude);
        _fetchForecast(_currentPosition!.latitude, _currentPosition!.longitude);
      }
    });
  }

  Future<void> _initTTS() async {
    await _tts.setLanguage("id-ID");
    await _tts.setPitch(1.0);
    await _tts.setSpeechRate(0.5);
  }

  Future<void> _speak(String text) async {
    await _tts.speak(text);
  }

  void _parseRoutePoints() {
    try {
      final String coordsString = widget.routeData['titik_koordinat'];
      final List<dynamic> decoded = jsonDecode(coordsString);
      
      setState(() {
        _routePoints = decoded.map((c) => LatLng(
          double.parse(c['lat'].toString()), 
          double.parse(c['lng'].toString())
        )).toList();

        // DETEKSI RUTE MELINGKAR (Circular Route)
        // Jika titik awal dan akhir sangat dekat (< 50m), anggap rute melingkar.
        if (_routePoints.isNotEmpty) {
          double startEndDist = NavigationHelper.calculateDistance(_routePoints.first, _routePoints.last);
          _isCircular = startEndDist < 50;
        }
      });
    } catch (e) {
      print("Error parsing route points: $e");
    }
  }

  Future<void> _initLocationTracking() async {
    bool serviceEnabled;
    LocationPermission permission;

    serviceEnabled = await Geolocator.isLocationServiceEnabled();
    if (!serviceEnabled) {
      return Future.error('Location services are disabled.');
    }

    permission = await Geolocator.checkPermission();
    if (permission == LocationPermission.denied) {
      permission = await Geolocator.requestPermission();
      if (permission == LocationPermission.denied) {
        return Future.error('Location permissions are denied');
      }
    }

    // Ambil posisi awal
    Position position = await Geolocator.getCurrentPosition();
    _updatePosition(position);

    // Ambil cuaca awal sekali saja saat GPS terdeteksi pertama kali
    _fetchWeather(position.latitude, position.longitude);
    _fetchForecast(position.latitude, position.longitude);

    // Stream posisi real-time
    try {
      final LocationSettings locationSettings = AndroidSettings(
        accuracy: LocationAccuracy.bestForNavigation,
        distanceFilter: 1, // Set ke 1 agar update sesering mungkin
        intervalDuration: const Duration(seconds: 1), // Paksa update tiap 1 detik
        foregroundNotificationConfig: const ForegroundNotificationConfig(
          notificationText: "Smart Cycling sedang melacak perjalanan Anda",
          notificationTitle: "Navigasi Aktif",
          enableWakeLock: true,
        ),
      );

      _positionStream = Geolocator.getPositionStream(locationSettings: locationSettings)
        .listen((Position position) {
          _updatePosition(position);
        }, onError: (e) {
          debugPrint("GPS Stream Error: $e");
        });
    } catch (e) {
      debugPrint("Error starting location stream: $e");
      // Fallback: Try standard settings if AndroidSettings fails
      _positionStream = Geolocator.getPositionStream(
        locationSettings: const LocationSettings(
          accuracy: LocationAccuracy.best,
          distanceFilter: 0,
        ),
      ).listen(_updatePosition);
    }

    setState(() => _isLoading = false);
  }

  void _updatePosition(Position position) {
    if (!mounted) return;
    
    final newPos = LatLng(position.latitude, position.longitude);
    debugPrint("GPS Update: ${position.latitude}, ${position.longitude}");
    setState(() {
      _currentPosition = newPos;
      if (_navStatus == NavStatus.active) {
        if (_lastTrackedPosition != null) {
          double dist = NavigationHelper.calculateDistance(_lastTrackedPosition!, newPos);
          _accumulatedDistance += (dist / 1000); // km
        }
        _lastTrackedPosition = newPos;
      }
    });

    // --- LOGIKA NAVIGASI ---
    if (_routePoints.isNotEmpty) {
      _processNavigation(newPos);
    }

    // Auto center map jika mode following aktif
    if (_isFollowingUser) {
      _mapController.move(newPos, 16);
    }
  }

  void _processNavigation(LatLng currentPos) {
    // 0. Cek jika sudah selesai
    if (_navStatus == NavStatus.finished) return;

    // 1. Hitung Kedekatan dengan Jalur untuk semua Case
    double minDistance = double.infinity;
    int nearestIndex = -1;

    for (int i = 0; i < _routePoints.length - 1; i++) {
        double dist = NavigationHelper.getDistanceToSegment(currentPos, _routePoints[i], _routePoints[i+1]);
        if (dist < minDistance) {
            minDistance = dist;
            nearestIndex = i;
        }
    }

    // 2. Cek Entry Point (Jika belum mulai)
    if (_navStatus == NavStatus.waiting) {
      if (minDistance < 25 && nearestIndex != -1) {
        // [SYARAT START KHUSUS RUTE SATU JALUR]
        if (!_isCircular) {
          bool isAtStart = nearestIndex <= 2; // Dekat titik awal asli
          bool isAtEnd = nearestIndex >= _routePoints.length - 3; // Dekat titik akhir asli
          
          if (!isAtStart && !isAtEnd) {
            // Pengguna di tengah rute satu jalur, jangan izinkan start
            return;
          }
        }

        setState(() {
          _navStatus = NavStatus.readyToStart;
          _targetPointIndex = nearestIndex; // Mark titik mulai terdekat
          // Hitung sisa jarak dari titik masuk ke finish
          _calculateRemainingDistance(nearestIndex, currentPos);
        });
        _showStartDialog();
      }
      return;
    }

    // 3. Cek Off-Route (Hanya saat perjalanan sedang berlangsung atau dijeda)
    if (_navStatus == NavStatus.active || _navStatus == NavStatus.paused) {
      // Peringatan Keluar Jalur: Tingkatkan ke 15m karena 5m masih sering false-positive
      if (minDistance > 10.0) {
        if (!_isOffRoute) {
          setState(() {
            _isOffRoute = true;
            if (_navStatus == NavStatus.active) {
              _navStatus = NavStatus.paused;
              _pausePosition = currentPos;
              _timer?.cancel();
            }
          });
          _speak("Anda keluar dari jalur, perjalanan dihentikan sementara");
        }
      } else if (minDistance <= 10.0) {
        // Kembali ke jalur (Toleransi 10m agar lebih stabil)
        if (_isOffRoute) {
          // 1. Cek dulu apakah dia meloncat rute (Potong Jalan)
          if (nearestIndex > _lastReachedIndex + 3) {
            _handleMissedPath();
            return;
          }

          // Jika tidak meloncat, otomatis resume perjalanan
          setState(() {
            _isOffRoute = false;
            if (_navStatus == NavStatus.paused) {
               _navStatus = NavStatus.active;
               _startCountdown();
               _speak("Anda kembali ke jalur, melanjutkan perjalanan");
            }
          });
        }
      }
    }

    // 4. Strict Point Sequence & U-Turn Detection
    if (_navStatus == NavStatus.active && nearestIndex != -1) {
      // A. DETEKSI ARAH AWAL (Tentukan arah maju atau mundur saat mulai bergerak)
      if (!_directionDetected) {
        if (nearestIndex != _lastReachedIndex) {
          // Jika rute melingkar, pengguna bisa gowes ke arah titik 1 (Maju) atau titik Akhir (Mundur)
          if (_isCircular && nearestIndex > _routePoints.length - 5) {
            setState(() {
              _isRouteReversed = true;
              _routePoints = _routePoints.reversed.toList();
              _lastReachedIndex = 0;
            });
            _speak("Arah perjalanan: Mundur. Tetap pada jalur ini.");
          } else {
            // Arah Maju (Rute satu jalur sudah dibalik di _startTrip jika perlu)
            setState(() {
              _lastReachedIndex = nearestIndex;
            });
            _speak("Arah perjalanan: Maju. Selamat bersepeda.");
          }
          _directionDetected = true;
        }
        return;
      }

      // B. DETEKSI PUTAR BALIK (U-TURN)
      // Jika user mundur dari titik terjauh yang pernah dicapai (toleransi 3 titik)
      if (nearestIndex < _lastReachedIndex - 3) {
        _handleUTurn();
        return;
      }

      // 4b. DETEKSI POTONG JALUR (STRICT ZERO TOLERANCE)
      // Jika user melompati lebih dari 3 titik koordinat (indikasi potong kompas)
      if (nearestIndex > _lastReachedIndex + 3) {
        _handleMissedPath();
        return;
      }

      // Update progress target jika user bergerak maju
      if (nearestIndex > _lastReachedIndex) {
        setState(() {
          _lastReachedIndex = nearestIndex;
        });
      }

      // Hitung sisa jarak dinamis
      _calculateRemainingDistance(nearestIndex, currentPos);

      // Turn-by-Turn Guidance - Threshold 2-5 meter sesuai permintaan
      for (int j = nearestIndex + 1; j <= nearestIndex + 5 && j < _routePoints.length - 1; j++) {
        String? maneuver = NavigationHelper.detectManeuver(_routePoints, j);
        if (maneuver != null && _lastManeuverIndex != j) {
          double distToTurn = NavigationHelper.calculateDistance(currentPos, _routePoints[j]);
          
          // Trigger Peringatan H-2m (disesuaikan rentang 2-5m agar GPS tidak terlewat)
          if (distToTurn <= 3 && distToTurn >= 1) {
            setState(() {
              _nextInstruction = "$maneuver di depan";
              _lastManeuverIndex = j;
              _distanceToNextTurn = distToTurn;
            });
            break;
          }
        }
      }
    }

    // 5. Deteksi Selesai (Finish Point)
    // Syarat Selesai:
    // 1. Dekat dengan titik terakhir rute
    // 2. Jika rute melingkar: Sudah menempuh minimal 80% dari rute (mencegah selesai prematur di awal)
    // 3. Jika rute satu jalur: Sudah menempuh minimal 90% dari rute
    double distToEnd = NavigationHelper.calculateDistance(currentPos, _routePoints.last);
    double progressPercent = (_routePoints.isNotEmpty) ? _lastReachedIndex / (_routePoints.length - 1) : 0;
    
    bool canFinish = _isCircular 
        ? (distToEnd < 25 && progressPercent > 0.9) // Harus satu putaran penuh
        : (distToEnd < 25 && progressPercent > 0.9); // Harus sampai di ujung seberang

    if (_navStatus == NavStatus.active && canFinish) {
      _showFinishDialog();
    }
  }

  void _showStartDialog() {
    _speak("Anda sudah berada di jalur rute. Mulai perjalanan anda sekarang?");
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) => BackdropFilter(
        filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
        child: AlertDialog(
          backgroundColor: const Color(0xFF1E2140),
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
          title: const Text("Mulai Perjalanan?", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
          content: const Text("Anda sudah memasuki area rute. Klik 'Start' untuk mencatat performa gowes Anda.", style: TextStyle(color: Colors.white70)),
          actions: [
            TextButton(
              onPressed: () { 
                Navigator.pop(context);
                _startTrip();
              }, 
              child: const Text("START", style: TextStyle(color: Colors.greenAccent, fontWeight: FontWeight.bold))
            ),
          ],
        ),
      ),
    );
  }

  void _startTrip() {
    setState(() {
      if (!_isCircular) {
        // RUTE SATU JALUR: Jika start dari ujung akhir, balik rutenya agar flow tetap 0 -> N
        if (_targetPointIndex >= _routePoints.length - 3) {
          _routePoints = _routePoints.reversed.toList();
          _targetPointIndex = 0;
        }
        _lastReachedIndex = _targetPointIndex;
      } else {
        // RUTE MELINGKAR: Susun ulang rute agar titik masuk menjadi titik 0
        if (_targetPointIndex > 0 && _targetPointIndex < _routePoints.length - 1) {
          List<LatLng> startPart = _routePoints.sublist(_targetPointIndex);
          List<LatLng> endPart = _routePoints.sublist(0, _targetPointIndex + 1);
          _routePoints = [...startPart, ...endPart];
        }
        _targetPointIndex = 0;
        _lastReachedIndex = 0;
      }
      
      _navStatus = NavStatus.active;
      _isOffRoute = false; // Reset status off-route saat mulai
      _directionDetected = false;
      _isRouteReversed = false;
      _accumulatedDistance = 0;
      _lastTrackedPosition = _currentPosition;
    });
    
    // Hitung sisa jarak awal secara eksplisit agar UI langsung terupdate
    if (_currentPosition != null) {
      _calculateRemainingDistance(_lastReachedIndex, _currentPosition!);
    }
    
    _speak("Perjalanan dimulai. Selamat menempuh rute ${_isCircular ? 'bundar' : 'satu jalur'}.");
    _startCountdown();
  }

  void _togglePauseTrip() {
    if (_isOffRoute) {
      _speak("Anda tidak bisa memulai perjalanan sebelum memasuki jalur rute");
      showDialog(
        context: context,
        builder: (context) => AlertDialog(
          backgroundColor: Colors.red.shade900,
          title: const Text("Peringatan", style: TextStyle(color: Colors.white)),
          content: const Text("Anda tidak bisa melanjutkan perjalanan sebelum memasuki jalur rute kembali.", style: TextStyle(color: Colors.white)),
          actions: [
            TextButton(onPressed: () => Navigator.pop(context), child: const Text("OK", style: TextStyle(color: Colors.white))),
          ],
        ),
      );
      return;
    }

    setState(() {
      if (_navStatus == NavStatus.active) {
        _navStatus = NavStatus.paused;
        _pausePosition = _currentPosition; // Simpan titik saat ini untuk cek resume
        _timer?.cancel();
        _speak("Perjalanan dijeda");
      } else if (_navStatus == NavStatus.paused) {
        // Cek jika posisi resume masih sama (toleransi 10m)
        if (_pausePosition != null && _currentPosition != null) {
          double dist = NavigationHelper.calculateDistance(_currentPosition!, _pausePosition!);
          if (dist > 10.0) {
             _speak("Gagal melanjutkan. Anda harus kembali ke titik awal saat menjeda perjalanan.");
             ScaffoldMessenger.of(context).showSnackBar(
               const SnackBar(
                 content: Text("⚠️ Anda harus kembali ke titik jeda terakhir (Toleransi 10m)."),
                 backgroundColor: Colors.orange,
               )
             );
             return;
          }
        }
        _navStatus = NavStatus.active;
        _startCountdown();
        _speak("Perjalanan dilanjutkan");
      }
    });
  }

  void _handleJumpAhead() {
    _navStatus = NavStatus.finished;
    _timer?.cancel();
    _positionStream?.cancel();
    
    _speak("Anda me-resume rute di lokasi berbeda, misi otomatis gagal.");
    
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) => AlertDialog(
        backgroundColor: Colors.red.shade900,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
        title: const Row(
          children: [
            Icon(Icons.warning_amber_rounded, color: Colors.white),
            SizedBox(width: 10),
            Text("Misi Gagal!", style: TextStyle(color: Colors.white)),
          ],
        ),
        content: const Text("Anda terdeteksi melanjutkan perjalanan di titik yang berbeda dari titik jeda terakhir. Misi ini otomatis gagal karena ketidaksesuaian data.", style: TextStyle(color: Colors.white)),
        actions: [
          TextButton(
            onPressed: () {
              Navigator.pop(context); // Tutup dialog
              Navigator.pop(context); // Kembali ke Home
            }, 
            child: const Text("KEMBALI KE HOME", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))
          ),
        ],
      ),
    );
  }

  void _handleUTurn() {
    _navStatus = NavStatus.finished;
    _timer?.cancel();
    _positionStream?.cancel();
    
    _speak("Anda memutar balik arah, misi otomatis gagal.");
    
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) => AlertDialog(
        backgroundColor: Colors.orange.shade900,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
        title: const Row(
          children: [
            Icon(Icons.warning_amber_rounded, color: Colors.white),
            SizedBox(width: 10),
            Text("Misi Gagal!", style: TextStyle(color: Colors.white)),
          ],
        ),
        content: const Text("Anda memutar balik arah. Misi ini otomatis gagal dan tidak akan tersimpan ke riwayat.", style: TextStyle(color: Colors.white)),
        actions: [
          TextButton(
            onPressed: () {
              Navigator.pop(context); // Tutup dialog
              Navigator.pop(context); // Kembali ke Home
            }, 
            child: const Text("KEMBALI KE HOME", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))
          ),
        ],
      ),
    );
  }

  void _handleMissedPath() {
    _navStatus = NavStatus.finished;
    _timer?.cancel();
    _positionStream?.cancel();
    
    _speak("Ada jalur yang terlewat, misi otomatis gagal.");
    
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) => AlertDialog(
        backgroundColor: Colors.red.shade900,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
        title: const Row(
          children: [
            Icon(Icons.error_outline, color: Colors.white),
            SizedBox(width: 10),
            Text("Misi Gagal!", style: TextStyle(color: Colors.white)),
          ],
        ),
        content: const Text("Gps mendeteksi Anda memotong rute. Misi ini otomatis gagal dan tidak akan tersimpan ke riwayat.", style: TextStyle(color: Colors.white)),
        actions: [
          TextButton(
            onPressed: () {
              Navigator.pop(context); // Tutup dialog
              Navigator.pop(context); // Kembali ke Home
            }, 
            child: const Text("KEMBALI KE HOME", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))
          ),
        ],
      ),
    );
  }

  void _confirmManualFinish() {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        backgroundColor: const Color(0xFF1E2140),
        title: const Text("Selesaikan Perjalanan?", style: TextStyle(color: Colors.white)),
        content: const Text("Apakah anda yakin ingin mengakhiri perjalanan ini?", style: TextStyle(color: Colors.white70)),
        actions: [
          TextButton(onPressed: () => Navigator.pop(context), child: const Text("BATAL")),
          TextButton(
            onPressed: () { 
              Navigator.pop(context);
              _finishTrip(manually: true); 
            }, 
            child: const Text("AKHIRI", style: TextStyle(color: Colors.redAccent))
          ),
        ],
      ),
    );
  }

  void _showFinishDialog() {
    if (_navStatus == NavStatus.finished) return;
    setState(() => _navStatus = NavStatus.finished);
    _timer?.cancel();
    
    _speak("Misi selesai! Anda sudah berhasil menyelesaikan perjalanan ini.");

    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) => BackdropFilter(
        filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
        child: AlertDialog(
          backgroundColor: const Color(0xFF1E2140),
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
          title: const Row(
            children: [
              Icon(Icons.stars, color: Colors.yellowAccent),
              SizedBox(width: 10),
              Text("Misi Selesai!", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
            ],
          ),
          content: const Text("Selamat! Anda sudah berhasil menyelesaikan perjalanan ini dan melewati semua titik rute.", style: TextStyle(color: Colors.white70)),
          actions: [
            ElevatedButton(
              onPressed: () { 
                Navigator.pop(context);
                _finishTrip(manually: false); 
              }, 
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.greenAccent,
                shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))
              ),
              child: const Text("SIMPAN & SELESAI", style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold))
            ),
          ],
        ),
      ),
    );
  }

  void _calculateRemainingDistance(int nearestIndex, LatLng currentPos) {
    double total = 0;
    // Gunakan _lastReachedIndex atau nearestIndex untuk sisa jarak yang konsisten
    int currentIndex = nearestIndex;
    
    if (currentIndex + 1 < _routePoints.length) {
      // Jarak dari posisi saat ini ke titik rute berikutnya
      total += NavigationHelper.calculateDistance(currentPos, _routePoints[currentIndex + 1]);
      
      // Tambahkan jarak antar semua titik rute yang tersisa
      for (int i = currentIndex + 1; i < _routePoints.length - 1; i++) {
        total += NavigationHelper.calculateDistance(_routePoints[i], _routePoints[i + 1]);
      }
    }

    setState(() {
      _remainingDistance = total / 1000; // Ubah ke KM
    });
  }

  void _startCountdown() {
    _timer?.cancel(); // Pastikan tidak ada timer ganda
    _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      if (_navStatus != NavStatus.active) {
        timer.cancel();
        return;
      }
      setState(() {
        _remainingSeconds--;
        _elapsedSeconds++;
        
        if (_remainingSeconds == 300) _speak("Sisa waktu lima menit lagi");
        if (_remainingSeconds == 60) _speak("Sisa waktu satu menit lagi, ayo percepat gowes anda!");
      });
    });
  }

  String _formatTime(int seconds) {
    bool isNegative = seconds < 0;
    int absSecs = seconds.abs();
    int m = absSecs ~/ 60;
    int s = absSecs % 60;
    String result = "${m.toString().padLeft(2, '0')}:${s.toString().padLeft(2, '0')}";
    return isNegative ? "+$result" : result; // Ganti '-' dengan '+' sesuai permintaan
  }

  Future<void> _finishTrip({required bool manually}) async {
    _navStatus = NavStatus.finished;
    _timer?.cancel();
    _positionStream?.cancel();
    
    bool isSuccess = !manually && _remainingSeconds >= 0;
    String status = isSuccess ? "BERHASIL" : "GAGAL";
    
    // Simpan ke Riwayat
    await _saveToHistory(status);

    if (!mounted) return;

    // Jika manual finish butuh dialog hasil berbeda
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) => BackdropFilter(
        filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
        child: AlertDialog(
          backgroundColor: const Color(0xFF1E2140),
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
          content: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Icon(
                isSuccess ? Icons.emoji_events : (manually ? Icons.flag_outlined : Icons.timer_off_outlined),
                size: 80,
                color: isSuccess ? Colors.yellowAccent : (manually ? Colors.blueAccent : Colors.redAccent),
              ),
              const SizedBox(height: 20),
              Text(
                manually ? "PERJALANAN SELESAI" : "MISI $status!",
                style: const TextStyle(color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold),
              ),
              const SizedBox(height: 10),
              Text(
                isSuccess 
                  ? "Selamat! Anda berhasil mencapai target waktu sebagai pesepeda tangguh."
                  : (manually ? "Perjalanan telah dihentikan oleh pengguna. Data Anda sudah tersimpan di riwayat." : "Sayang sekali, Anda belum mencapai target waktu. Jangan menyerah, coba lagi nanti!"),
                textAlign: TextAlign.center,
                style: const TextStyle(color: Colors.white70),
              ),
              const SizedBox(height: 30),
              ElevatedButton(
                onPressed: () {
                  Navigator.pop(context); // Tutup dialog
                  Navigator.pop(context); // Kembali ke Home
                },
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.blueAccent,
                  shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))
                ),
                child: const Text("KEMBALI", style: TextStyle(color: Colors.white)),
              )
            ],
          ),
        ),
      ),
    );
    
    if (manually) {
      _speak("Perjalanan diakhiri. Riwayat perjalanan Anda telah tersimpan.");
    } else {
       _speak(isSuccess 
        ? "Selamat, perjalan anda selesai. Anda berhasil dalam misi perjalanan ini!" 
        : "Perjalanan selesai. Anda gagal dalam misi perjalanan ini. Tetap semangat!");
    }
  }

  Future<void> _saveToHistory(String status) async {
    double totalRouteDistance = double.tryParse(widget.routeData['jarak'].toString()) ?? 0;
    double traveledDistance = _accumulatedDistance;
    if (traveledDistance < 0.05) traveledDistance = 0; // Anggap 0 jika di bawah 50 meter untuk mengatasi jitter GPS
    if (status == "BERHASIL") traveledDistance = totalRouteDistance;

    int timeSpentSeconds = (widget.targetMinutes * 60) - _remainingSeconds;
    // waktu_tempuh bisa lebih besar dari target (misal target 10 menit, tempuh 13 menit)
    // Jika sisa waktu negatif, berarti telat.
    if (timeSpentSeconds < 0) timeSpentSeconds = 0;

    double avgSpeed = 0;
    if (timeSpentSeconds > 0) {
      double timeInHours = timeSpentSeconds / 3600;
      avgSpeed = traveledDistance / timeInHours;
    }

    final url = Uri.parse("${ApiConfig.baseUrl}/save_history.php");
    try {
      await http.post(url, body: {
        'id_users': SessionManager.userId.toString(),
        'id_routes': widget.routeData['id_routes'].toString(),
        'target_waktu': (widget.targetMinutes * 60).toString(),
        'status': status,
        'jarak_tempuh': traveledDistance.toStringAsFixed(2),
        'waktu_tempuh': timeSpentSeconds.toString(),
        'kecepatan_rata_rata': avgSpeed.toStringAsFixed(1),
        'tanggal': DateTime.now().toString(),
      });
    } catch (e) {
      debugPrint("Gagal menyimpan riwayat ke server: $e");
    }
  }

  Future<void> _fetchWeather(double lat, double lon) async {
    final data = await _weatherService.fetchWeather(lat, lon);
    if (data != null && mounted) {
      setState(() {
        _weatherData = data;
        _checkWeatherAlerts(data);
      });
    }
  }

  Future<void> _fetchForecast(double lat, double lon) async {
    final data = await _weatherService.fetchForecast(lat, lon);
    if (data != null && mounted) {
      // Cek forecast untuk peringatan "akan hujan" (H-5 menit disimulasikan dari probabilitas hujan terdekat)
      _checkForecastAlerts(data);
    }
  }

  void _checkWeatherAlerts(Map<String, dynamic> data) {
    // Cek kondisi saat ini
    String mainWeather = data['weather'][0]['main'].toString().toLowerCase();
    bool currentlyRaining = mainWeather.contains('rain') || mainWeather.contains('drizzle') || mainWeather.contains('thunderstorm');

    if (currentlyRaining && !_isRaining) {
      _isRaining = true;
      _dryWarningSpoken = false;
      if (!_rainWarningSpoken && _rainWarningCount < 2) {
        _speak("Peringatan, saat ini mulai turun hujan. Mohon segera berteduh demi keamanan.");
        _showWeatherSnackBar("⚠️ Hujan Turun! Mohon segera berteduh.");
        _rainWarningSpoken = true;
        _rainWarningCount++;
      }
    } else if (!currentlyRaining && _isRaining) {
      _isRaining = false;
      _rainWarningSpoken = false;
      if (!_dryWarningSpoken && _dryWarningCount < 2) {
        _speak("Hujan telah reda. Anda dapat melanjutkan perjalanan dengan hati-hati.");
        _showWeatherSnackBar("🌤️ Hujan Reda. Tetap waspada jalan licin.");
        _dryWarningSpoken = true;
        _dryWarningCount++;
      }
    }
  }

  void _checkForecastAlerts(Map<String, dynamic> data) {
    // Simulasi H-5 Menit menggunakan data forecast terdekat
    // Karena API gratis hanya memberikan per 3 jam, kita cek probability of precipitation (pop)
    // Jika pop tinggi (> 0.5) pada forecast terdekat, berikan peringatan dini.
    if (data['list'] != null && data['list'].isNotEmpty) {
      var nextForecast = data['list'][0];
      double pop = double.tryParse(nextForecast['pop'].toString()) ?? 0;
      String nextWeather = nextForecast['weather'][0]['main'].toString().toLowerCase();
      
      if (pop > 0.7 && (nextWeather.contains('rain')) && !_isRaining) {
        if (!_rainWarningSpoken && _rainWarningCount < 2) {
          // Anggap ini peringatan "Akan Hujan"
          _speak("Peringatan, diperkirakan akan turun hujan dalam waktu dekat. Persiapkan diri Anda.");
          _showWeatherSnackBar("⛈️ Perkiraan Hujan dalam waktu dekat!");
          _rainWarningSpoken = true;
          _rainWarningCount++;
        }
      }
    }
  }

  void _showWeatherSnackBar(String message) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(message, style: const TextStyle(fontWeight: FontWeight.bold)),
        backgroundColor: Colors.blueGrey.shade900,
        behavior: SnackBarBehavior.floating,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
        duration: const Duration(seconds: 5),
      )
    );
  }

  @override
  void dispose() {
    _timer?.cancel();
    _weatherTimer?.cancel();
    _positionStream?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    String weatherIcon = _weatherData != null 
        ? "https://openweathermap.org/img/wn/${_weatherData!['weather'][0]['icon']}@2x.png" 
        : "";

    return Scaffold(
      body: Stack(
        children: [
          // MAP LAYER
          FlutterMap(
            mapController: _mapController,
            options: MapOptions(
              initialCenter: _routePoints.isNotEmpty ? _routePoints.first : const LatLng(-8.3, 113.6),
              initialZoom: 15,
              onPositionChanged: (pos, hasGesture) {
                if (hasGesture && _isFollowingUser) {
                  setState(() => _isFollowingUser = false); // Matikan auto-center jika user geser peta
                }
              },
            ),
            children: [
              TileLayer(
                urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
                userAgentPackageName: 'com.example.smart_cycling',
              ),
              if (_routePoints.isNotEmpty)
                PolylineLayer(
                  polylines: [
                    Polyline(
                      points: _routePoints,
                      color: Colors.blueAccent.withOpacity(0.6),
                      strokeWidth: 8,
                    ),
                    Polyline(
                      points: _routePoints,
                      color: Colors.white.withOpacity(0.3),
                      strokeWidth: 2,
                    ),
                  ],
                ),
              if (_routePoints.isNotEmpty)
                MarkerLayer(
                  markers: [
                    // Start/Finish Marker (Flag)
                    Marker(
                      point: _routePoints.last,
                      width: 50,
                      height: 50,
                      child: Column(
                        children: [
                          Container(
                            padding: const EdgeInsets.all(4),
                            decoration: const BoxDecoration(
                              color: Colors.redAccent,
                              shape: BoxShape.circle,
                            ),
                            child: const Icon(Icons.flag, color: Colors.white, size: 20),
                          ),
                          const Text("FINISH", style: TextStyle(color: Colors.redAccent, fontWeight: FontWeight.bold, fontSize: 10)),
                        ],
                      ),
                    ),
                  ],
                ),
              if (_currentPosition != null)
                MarkerLayer(
                  markers: [
                    Marker(
                      point: _currentPosition!,
                      width: 40,
                      height: 40,
                      child: Stack(
                        alignment: Alignment.center,
                        children: [
                          // Shadow/Glow effect
                          Container(
                            width: 35,
                            height: 35,
                            decoration: BoxDecoration(
                              shape: BoxShape.circle,
                              color: Colors.blue.withOpacity(0.3),
                            ),
                          ),
                          // Outer White Circle
                          Container(
                            width: 20,
                            height: 20,
                            decoration: const BoxDecoration(
                              shape: BoxShape.circle,
                              color: Colors.white,
                            ),
                          ),
                          // Inner Blue Dot (Google Maps Style)
                          Container(
                            width: 14,
                            height: 14,
                            decoration: const BoxDecoration(
                              shape: BoxShape.circle,
                              color: Colors.blue,
                            ),
                          ),
                          // Small Cyclist Overlay
                          const Icon(Icons.directions_bike, size: 10, color: Colors.white),
                        ],
                      ),
                    ),
                  ],
                ),
            ],
          ),

          // TOP HEADER (Route Info & Navigation Instruction)
          Positioned(
            top: 50,
            left: 20,
            right: 20,
            child: Column(
              children: [
                // Instruction Panel
                const SizedBox(height: 0),

                Row(
                  children: [
                    CircleAvatar(
                      backgroundColor: const Color(0xFF1E2140),
                      child: IconButton(
                        icon: const Icon(Icons.arrow_back, color: Colors.white),
                        onPressed: () => Navigator.pop(context),
                      ),
                    ),
                    const SizedBox(width: 15),
                    Expanded(
                      child: ClipRRect(
                        borderRadius: BorderRadius.circular(20),
                        child: BackdropFilter(
                          filter: ImageFilter.blur(sigmaX: 12, sigmaY: 12),
                          child: Container(
                            padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
                            decoration: BoxDecoration(
                              color: const Color(0xFF1E2140).withOpacity(0.85),
                              borderRadius: BorderRadius.circular(20),
                              border: Border.all(color: Colors.white.withOpacity(0.2)),
                              boxShadow: [
                                BoxShadow(color: Colors.black.withOpacity(0.3), blurRadius: 10)
                              ],
                            ),
                            child: Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                Text(
                                  widget.routeData['nama_rute'] ?? "Navigasi",
                                  style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 16),
                                  overflow: TextOverflow.ellipsis,
                                ),
                                Row(
                                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                  children: [
                                    Text(
                                      "${_remainingDistance.toStringAsFixed(2)} KM lagi • ${widget.routeData['kondisi_medan']}",
                                      style: const TextStyle(color: Colors.blueAccent, fontSize: 12, fontWeight: FontWeight.w600),
                                    ),
                                    Column(
                                      crossAxisAlignment: CrossAxisAlignment.end,
                                      children: [
                                        if (_navStatus == NavStatus.active || _navStatus == NavStatus.paused)
                                          Padding(
                                            padding: const EdgeInsets.only(bottom: 4.0),
                                            child: Row(
                                              mainAxisSize: MainAxisSize.min,
                                              children: [
                                                _buildSmallControlBtn(
                                                  icon: _navStatus == NavStatus.active ? Icons.pause_circle_filled : Icons.play_circle_filled,
                                                  color: _navStatus == NavStatus.active ? Colors.orangeAccent : Colors.greenAccent,
                                                  onTap: _togglePauseTrip,
                                                ),
                                                const SizedBox(width: 8),
                                                _buildSmallControlBtn(
                                                  icon: Icons.stop_circle,
                                                  color: Colors.redAccent,
                                                  onTap: _confirmManualFinish,
                                                ),
                                              ],
                                            ),
                                          ),
                                        Text(
                                          _formatTime(_remainingSeconds),
                                          style: TextStyle(
                                            color: _remainingSeconds < 0 ? Colors.redAccent : Colors.greenAccent,
                                            fontWeight: FontWeight.bold,
                                            fontSize: 16,
                                          ),
                                        ),
                                      ],
                                    ),
                                  ],
                                ),
                              ],
                            ),
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ],
            ),
          ),

          // FLOATING ACTION BUTTONS
          Positioned(
            right: 20,
            bottom: 310, // Naikkan ke atas agar tidak tertutup
            child: Column(
              children: [
                FloatingActionButton(
                  heroTag: "follow",
                  backgroundColor: _isFollowingUser ? Colors.blue : const Color(0xFF1E2140),
                  mini: true,
                  onPressed: () {
                    setState(() => _isFollowingUser = !_isFollowingUser);
                    if (_isFollowingUser && _currentPosition != null) {
                      _mapController.move(_currentPosition!, 16);
                    }
                  },
                  child: Icon(
                    _isFollowingUser ? Icons.my_location : Icons.location_searching,
                    color: Colors.white,
                  ),
                ),
              ],
            ),
          ),


          // WEATHER PANEL (Premium Deep Blue Glassmorphism)
          if (_weatherData != null)
            Positioned(
              bottom: 30,
              left: 20,
              right: 20,
              child: ClipRRect(
                borderRadius: BorderRadius.circular(30),
                child: BackdropFilter(
                  filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15),
                  child: Container(
                    padding: const EdgeInsets.all(24),
                    decoration: BoxDecoration(
                      gradient: LinearGradient(
                        colors: [
                          const Color(0xFF1E2140).withOpacity(0.95),
                          const Color(0xFF0D0F21).withOpacity(0.85)
                        ],
                        begin: Alignment.topLeft,
                        end: Alignment.bottomRight,
                      ),
                      borderRadius: BorderRadius.circular(30),
                      border: Border.all(color: Colors.white.withOpacity(0.1)),
                    ),
                    child: Column(
                      children: [
                        Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            Row(
                              children: [
                                Image.network(weatherIcon, width: 60, height: 60,
                                  errorBuilder: (c,e,s) => const Icon(Icons.wb_sunny, color: Colors.yellow, size: 40),
                                ),
                                Column(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: [
                                    Text(
                                      "${_weatherData!['main']['temp'].round()}°C",
                                      style: const TextStyle(color: Colors.white, fontSize: 36, fontWeight: FontWeight.bold),
                                    ),
                                    Text(
                                      _weatherData!['weather'][0]['description'].toString().toUpperCase(),
                                      style: const TextStyle(color: Colors.blueAccent, fontSize: 12, fontWeight: FontWeight.w600, letterSpacing: 1.2),
                                    ),
                                  ],
                                ),
                              ],
                            ),
                            Container(
                              padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
                              decoration: BoxDecoration(
                                color: Colors.blueAccent.withOpacity(0.2),
                                borderRadius: BorderRadius.circular(10),
                                border: Border.all(color: Colors.blueAccent.withOpacity(0.5)),
                              ),
                              child: const Text("REAL-TIME", style: TextStyle(color: Colors.blueAccent, fontSize: 10, fontWeight: FontWeight.bold)),
                            ),
                          ],
                        ),
                        const SizedBox(height: 20),
                        Divider(color: Colors.white.withOpacity(0.1)),
                        const SizedBox(height: 10),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.spaceAround,
                          children: [
                            _buildWeatherDetail(Icons.water_drop, "${_weatherData!['main']['humidity']}%", "Kelembaban"),
                            _buildWeatherDetail(Icons.air, "${_weatherData!['wind']['speed']} m/s", "Angin"),
                            _buildWeatherDetail(Icons.visibility, "${(_weatherData!['visibility']/1000).toStringAsFixed(1)} km", "Jarak Pandang"),
                          ],
                        ),
                      ],
                    ),
                  ),
                ),
              ),
            ),

          if (_isLoading)
            const Center(child: CircularProgressIndicator(color: Colors.white)),
        ],
      ),
    );
  }

  Widget _buildWeatherDetail(IconData icon, String value, String label) {
    return Column(
      children: [
        Icon(icon, color: Colors.blueAccent, size: 20),
        const SizedBox(height: 8),
        Text(value, style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
        Text(label, style: const TextStyle(color: Colors.white54, fontSize: 10)),
      ],
    );
  }

  Widget _buildSmallControlBtn({required IconData icon, required Color color, required VoidCallback onTap}) {
    return GestureDetector(
      onTap: onTap,
      child: Icon(icon, color: color, size: 24), // Ukuran kecil tanpa latar belakang
    );
  }
}
