import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
// Keep your specific imports
import 'package:sefer_admin1/controller/functions/crud.dart';
import 'package:sefer_admin1/print.dart';

/// --------------------------------------------------------------------------
/// 1. DATA MODELS
/// --------------------------------------------------------------------------

class DriverLocation {
  final double latitude;
  final double longitude;
  final double speed;
  final double heading;
  final String updatedAt;

  DriverLocation({
    required this.latitude,
    required this.longitude,
    required this.speed,
    required this.heading,
    required this.updatedAt,
  });

  factory DriverLocation.fromJson(Map<String, dynamic> json) {
    return DriverLocation(
      latitude: double.tryParse(json['latitude'].toString()) ?? 0.0,
      longitude: double.tryParse(json['longitude'].toString()) ?? 0.0,
      speed: double.tryParse(json['speed'].toString()) ?? 0.0,
      heading: double.tryParse(json['heading'].toString()) ?? 0.0,
      updatedAt: json['updated_at'] ?? '',
    );
  }
}

/// --------------------------------------------------------------------------
/// 2. GETX CONTROLLER
/// --------------------------------------------------------------------------

class RideMonitorController extends GetxController {
  // CONFIGURATION
  final String apiUrl =
      "https://api.intaleq.xyz/intaleq/Admin/rides/monitorRide.php";

  // INPUT CONTROLLERS
  final TextEditingController phoneInputController = TextEditingController();

  // OBSERVABLES
  var isTracking = false.obs;
  var isLoading = false.obs;
  var hasError = false.obs;
  var errorMessage = ''.obs;

  // Driver & Ride Data
  var driverLocation = Rxn<DriverLocation>();
  var driverName = "Unknown Driver".obs;
  var rideStatus = "Waiting...".obs;

  // Route Data
  var startPoint = Rxn<LatLng>();
  var endPoint = Rxn<LatLng>();
  var routePolyline = <LatLng>[].obs; // List of points for the line

  // Map Variables
  final MapController mapController = MapController();
  Timer? _timer;
  bool _isFirstLoad = true; // To trigger auto-fit bounds only on first success

  @override
  void onClose() {
    _timer?.cancel();
    phoneInputController.dispose();
    super.onClose();
  }

  // --- ACTIONS ---

  void startSearch() {
    if (phoneInputController.text.trim().isEmpty) {
      Get.snackbar("Error", "Please enter a phone number");
      return;
    }

    // Reset state
    hasError.value = false;
    errorMessage.value = '';
    driverLocation.value = null;
    startPoint.value = null;
    endPoint.value = null;
    routePolyline.clear();
    driverName.value = "Loading...";
    rideStatus.value = "Loading...";
    _isFirstLoad = true;

    // Switch UI
    isTracking.value = true;
    isLoading.value = true;

    // Start fetching
    fetchRideData();

    // Start Polling
    _timer?.cancel();
    _timer = Timer.periodic(const Duration(seconds: 10), (timer) {
      fetchRideData();
    });
  }

  void stopTracking() {
    _timer?.cancel();
    isTracking.value = false;
    isLoading.value = false;
    phoneInputController.clear();
  }

  Future<void> fetchRideData() async {
    final phone = phoneInputController.text.trim();
    if (phone.isEmpty) return;

    try {
      final response = await CRUD().post(
        link: apiUrl,
        payload: {"phone": phone},
      );

      // Log.print('response: ${response}');

      if (response != 'failure') {
        final jsonResponse = response;

        if ((jsonResponse['message'] != null &&
                jsonResponse['message'] != 'failure') ||
            jsonResponse['status'] == 'success') {
          final data =
              jsonResponse['message'] ?? jsonResponse['data'] ?? jsonResponse;

          // 1. Parse Driver Info
          if (data['driver_details'] != null) {
            driverName.value = data['driver_details']['fullname'] ?? "Unknown";
          }

          // 2. Parse Ride Info & Route
          if (data['ride_details'] != null) {
            rideStatus.value = data['ride_details']['status'] ?? "Unknown";

            // Parse Start/End Locations (Format: "lat,lng")
            String? startStr = data['ride_details']['start_location'];
            String? endStr = data['ride_details']['end_location'];

            LatLng? s = _parseLatLngString(startStr);
            LatLng? e = _parseLatLngString(endStr);

            if (s != null && e != null) {
              startPoint.value = s;
              endPoint.value = e;
              routePolyline.value = [s, e]; // Straight line for now
            }
          }

          // 3. Parse Live Location
          final locData = data['driver_location'];
          if (locData is Map<String, dynamic>) {
            final newLocation = DriverLocation.fromJson(locData);
            driverLocation.value = newLocation;

            // 4. Update Camera Bounds
            _updateMapBounds();
          } else {
            // Even if no live driver, we might want to show the route
            if (startPoint.value != null && endPoint.value != null) {
              _updateMapBounds();
            }
            print("No live location coordinates.");
          }

          hasError.value = false;
        } else {
          hasError.value = true;
          errorMessage.value = jsonResponse['message'] ??
              "Phone number not found or no active ride.";
        }
      } else {
        hasError.value = true;
        errorMessage.value = "Connection Failed";
      }
    } catch (e) {
      print("Polling Error: $e");
      if (isLoading.value) {
        hasError.value = true;
        errorMessage.value = e.toString();
      }
    } finally {
      isLoading.value = false;
    }
  }

  // Helper to parse "lat,lng" string
  LatLng? _parseLatLngString(String? str) {
    if (str == null || !str.contains(',')) return null;
    try {
      final parts = str.split(',');
      final lat = double.parse(parts[0].trim());
      final lng = double.parse(parts[1].trim());
      return LatLng(lat, lng);
    } catch (e) {
      print("Error parsing location string '$str': $e");
      return null;
    }
  }

  // Logic to fit start, end, and driver on screen
  void _updateMapBounds() {
    // Only auto-fit on the first successful load to avoid fighting user pan/zoom
    if (!_isFirstLoad) return;

    List<LatLng> pointsToFit = [];

    if (startPoint.value != null) pointsToFit.add(startPoint.value!);
    if (endPoint.value != null) pointsToFit.add(endPoint.value!);
    if (driverLocation.value != null) {
      pointsToFit.add(LatLng(
          driverLocation.value!.latitude, driverLocation.value!.longitude));
    }

    if (pointsToFit.isNotEmpty) {
      try {
        final bounds = LatLngBounds.fromPoints(pointsToFit);
        mapController.fitCamera(
          CameraFit.bounds(
            bounds: bounds,
            padding:
                const EdgeInsets.all(80.0), // Padding so markers aren't on edge
          ),
        );
        _isFirstLoad = false; // Disable auto-fit after initial success
      } catch (e) {
        print("Map Controller not ready yet: $e");
      }
    }
  }
}

/// --------------------------------------------------------------------------
/// 3. UI SCREEN
/// --------------------------------------------------------------------------

class RideMonitorScreen extends StatelessWidget {
  const RideMonitorScreen({super.key});

  @override
  Widget build(BuildContext context) {
    final RideMonitorController controller = Get.put(RideMonitorController());

    return Scaffold(
      appBar: AppBar(
        title: const Text("Admin Ride Monitor"),
        backgroundColor: Colors.blueAccent,
        foregroundColor: Colors.white,
        actions: [
          Obx(() => controller.isTracking.value
              ? IconButton(
                  icon: const Icon(Icons.close),
                  onPressed: controller.stopTracking,
                  tooltip: "Stop Tracking",
                )
              : const SizedBox.shrink()),
        ],
      ),
      body: Obx(() {
        if (!controller.isTracking.value) {
          return _buildSearchForm(context, controller);
        }
        return _buildMapTrackingView(controller);
      }),
    );
  }

  Widget _buildSearchForm(
      BuildContext context, RideMonitorController controller) {
    return Center(
      child: Padding(
        padding: const EdgeInsets.all(24.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Icon(Icons.map_outlined, size: 80, color: Colors.blueAccent),
            const SizedBox(height: 20),
            const Text(
              "Track Active Ride",
              style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 10),
            const Text(
              "Enter Driver or Passenger Phone Number",
              style: TextStyle(color: Colors.grey),
            ),
            const SizedBox(height: 30),
            TextField(
              controller: controller.phoneInputController,
              keyboardType: TextInputType.phone,
              decoration: InputDecoration(
                labelText: "Phone Number",
                hintText: "e.g. 9639...",
                border:
                    OutlineInputBorder(borderRadius: BorderRadius.circular(10)),
                prefixIcon: const Icon(Icons.phone),
              ),
            ),
            const SizedBox(height: 20),
            SizedBox(
              width: double.infinity,
              height: 50,
              child: ElevatedButton(
                onPressed: controller.startSearch,
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.blueAccent,
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10)),
                ),
                child: const Text("Start Monitoring",
                    style: TextStyle(color: Colors.white, fontSize: 16)),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildMapTrackingView(RideMonitorController controller) {
    return Stack(
      children: [
        FlutterMap(
          mapController: controller.mapController,
          options: MapOptions(
            initialCenter: const LatLng(30.0444, 31.2357),
            initialZoom: 12.0,
          ),
          children: [
            TileLayer(
              urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
              userAgentPackageName: 'com.sefer.admin',
            ),

            // 1. ROUTE LINE (Polyline)
            if (controller.routePolyline.isNotEmpty)
              PolylineLayer(
                polylines: [
                  Polyline(
                    points: controller.routePolyline.value,
                    strokeWidth: 5.0,
                    color: Colors.blueAccent.withOpacity(0.8),
                    borderStrokeWidth: 2.0,
                    borderColor: Colors.blue[900]!,
                  ),
                ],
              ),

            // 2. START & END MARKERS
            MarkerLayer(
              markers: [
                // Start Point (Green Flag)
                if (controller.startPoint.value != null)
                  Marker(
                    point: controller.startPoint.value!,
                    width: 40,
                    height: 40,
                    child:
                        const Icon(Icons.flag, color: Colors.green, size: 40),
                    alignment: Alignment.topCenter,
                  ),

                // End Point (Red Flag)
                if (controller.endPoint.value != null)
                  Marker(
                    point: controller.endPoint.value!,
                    width: 40,
                    height: 40,
                    child: const Icon(Icons.flag, color: Colors.red, size: 40),
                    alignment: Alignment.topCenter,
                  ),

                // Driver Car Marker
                if (controller.driverLocation.value != null)
                  Marker(
                    point: LatLng(
                      controller.driverLocation.value!.latitude,
                      controller.driverLocation.value!.longitude,
                    ),
                    width: 60,
                    height: 60,
                    child: Transform.rotate(
                      angle: (controller.driverLocation.value!.heading *
                          (3.14159 / 180)),
                      child: Column(
                        children: [
                          const Icon(
                            Icons.directions_car_filled,
                            color: Colors
                                .black, // Dark car for visibility on blue line
                            size: 35,
                          ),
                          Container(
                            padding: const EdgeInsets.symmetric(
                                horizontal: 4, vertical: 1),
                            decoration: BoxDecoration(
                              color: Colors.white.withOpacity(0.8),
                              borderRadius: BorderRadius.circular(4),
                            ),
                            child: Text(
                              "${controller.driverLocation.value!.speed.toInt()} km",
                              style: const TextStyle(
                                  fontSize: 10, fontWeight: FontWeight.bold),
                            ),
                          )
                        ],
                      ),
                    ),
                  ),
              ],
            ),
          ],
        ),

        // LOADING OVERLAY
        if (controller.isLoading.value &&
            controller.driverLocation.value == null &&
            controller.startPoint.value == null)
          Container(
            color: Colors.black45,
            child: const Center(
                child: CircularProgressIndicator(color: Colors.white)),
          ),

        // ERROR OVERLAY
        if (controller.hasError.value)
          Center(
            child: Container(
              margin: const EdgeInsets.all(20),
              padding: const EdgeInsets.all(20),
              decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(10),
                  boxShadow: const [
                    BoxShadow(blurRadius: 10, color: Colors.black26)
                  ]),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  const Icon(Icons.error_outline, color: Colors.red, size: 40),
                  const SizedBox(height: 10),
                  Text(controller.errorMessage.value,
                      textAlign: TextAlign.center),
                  const SizedBox(height: 10),
                  ElevatedButton(
                      onPressed: controller.stopTracking,
                      child: const Text("Back"))
                ],
              ),
            ),
          ),

        // INFO CARD
        if (!controller.hasError.value && !controller.isLoading.value)
          Positioned(
            bottom: 20,
            left: 20,
            right: 20,
            child: Card(
              elevation: 8,
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(15)),
              child: Padding(
                padding: const EdgeInsets.all(16.0),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Row(
                      children: [
                        const CircleAvatar(
                          backgroundColor: Colors.blueAccent,
                          child: Icon(Icons.person, color: Colors.white),
                        ),
                        const SizedBox(width: 12),
                        Expanded(
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Text(
                                controller.driverName.value,
                                style: const TextStyle(
                                    fontSize: 18, fontWeight: FontWeight.bold),
                                overflow: TextOverflow.ellipsis,
                              ),
                              Row(
                                children: [
                                  Icon(Icons.circle,
                                      size: 10,
                                      color:
                                          controller.rideStatus.value == 'Begin'
                                              ? Colors.green
                                              : Colors.grey),
                                  const SizedBox(width: 5),
                                  Text(controller.rideStatus.value,
                                      style: const TextStyle(
                                          fontWeight: FontWeight.w600)),
                                ],
                              ),
                            ],
                          ),
                        ),
                      ],
                    ),
                    const Divider(),
                    if (controller.driverLocation.value != null)
                      Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          _buildInfoBadge(Icons.speed,
                              "${controller.driverLocation.value!.speed.toStringAsFixed(1)} km/h"),
                          _buildInfoBadge(
                              Icons.access_time,
                              controller.driverLocation.value!.updatedAt
                                  .split(' ')
                                  .last),
                        ],
                      )
                    else
                      const Text("Connecting to driver...",
                          style: TextStyle(
                              color: Colors.orange,
                              fontStyle: FontStyle.italic)),
                  ],
                ),
              ),
            ),
          ),
      ],
    );
  }

  Widget _buildInfoBadge(IconData icon, String text) {
    return Row(
      children: [
        Icon(icon, size: 16, color: Colors.grey[600]),
        const SizedBox(width: 4),
        Text(text,
            style: TextStyle(
                color: Colors.grey[800], fontWeight: FontWeight.bold)),
      ],
    );
  }
}
