import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:just_audio/just_audio.dart'; // لتشغيل صوت عند وصول رحلة

import '../../constant/box_name.dart';
import '../../constant/links.dart';
import '../../main.dart'; // للوصول لـ box
import '../functions/crud.dart';
import '../functions/location_controller.dart';

class RideAvailableController extends GetxController {
  bool isLoading = false;

  // RxList: أي تغيير هنا سينعكس فوراً على الشاشة
  RxList<Map<String, dynamic>> availableRides = <Map<String, dynamic>>[].obs;

  DateTime? _lastFetchTime;
  static const _cacheDuration = Duration(seconds: 5); // تقليل مدة الكاش قليلاً

  // مشغل الصوت
  final AudioPlayer _audioPlayer = AudioPlayer();

  @override
  void onInit() {
    super.onInit();

    // 1. جلب القائمة الأولية من السيرفر (HTTP)
    getRideAvailable(forceRefresh: true);

    // 2. تفعيل الاستماع المباشر للتحديثات (Socket)
    _initSocketListeners();
  }

  @override
  void onClose() {
    // تنظيف الموارد عند الخروج
    var socket = Get.find<LocationController>().socket;
    socket?.off('market_new_ride');
    socket?.off('ride_taken'); // تم توحيد الحدث لـ ride_taken
    _audioPlayer.dispose();
    super.onClose();
  }

  // ========================================================================
  // 1. جلب الرحلات (HTTP Request) - الطريقة الجديدة (Lat/Lng)
  // ========================================================================
  Future<void> getRideAvailable({bool forceRefresh = false}) async {
    // منع الطلبات المتكررة السريعة
    if (!forceRefresh &&
        _lastFetchTime != null &&
        DateTime.now().difference(_lastFetchTime!) < _cacheDuration) {
      return;
    }

    try {
      if (forceRefresh) {
        isLoading = true;
        update();
      }

      // الحصول على موقع السائق الحالي
      final location = Get.find<LocationController>().myLocation;

      // 🔥 التعديل الجوهري: نرسل Lat/Lng فقط بدلاً من Bounds
      var payload = {
        'lat': location.latitude.toString(),
        'lng': location.longitude.toString(),
        'radius': '50', // نصف القطر بالكيلومتر (كما حددناه في السيرفر)
      };

      var res =
          await CRUD().get(link: AppLink.getRideWaiting, payload: payload);

      isLoading = false;
      _lastFetchTime = DateTime.now();

      if (res != 'failure') {
        final decodedResponse = jsonDecode(res);

        if (decodedResponse is Map && decodedResponse['status'] == 'success') {
          final rides = decodedResponse['message'];
          if (rides is List) {
            // تحويل البيانات وتخزينها
            availableRides.value = List<Map<String, dynamic>>.from(rides);
          } else {
            availableRides.clear();
          }
        } else {
          availableRides.clear();
        }
      }

      update(); // تحديث الواجهة
    } catch (e) {
      isLoading = false;
      update();
      print("Error fetching rides: $e");
    }
  }

  // ========================================================================
  // 2. الاستماع للسوكيت (Real-time Updates) ⚡
  // ========================================================================
  void _initSocketListeners() {
    var locationCtrl = Get.find<LocationController>();
    var socket = locationCtrl.socket;

    if (socket == null) {
      print("⚠️ Socket is null in RideAvailableController");
      return;
    }

    // A. عند وصول رحلة جديدة للسوق (market_new_ride)
    socket.on('market_new_ride', (data) {
      print("🔔 Socket: New Ride Market: $data");

      if (data != null && data is Map) {
        // فلترة: هل نوع السيارة يناسبني؟
        if (_isCarTypeMatch(data['carType'])) {
          // منع التكرار (إذا كانت الرحلة موجودة مسبقاً)
          bool exists = availableRides
              .any((r) => r['id'].toString() == data['id'].toString());

          if (!exists) {
            // إضافة الرحلة لأعلى القائمة
            availableRides.insert(0, Map<String, dynamic>.from(data));

            // تشغيل صوت تنبيه (Bling) 🎵
            _playNotificationSound();
          }
        }
      }
    });

    // B. عند أخذ رحلة من قبل سائق آخر (ride_taken)
    // هذا الحدث يصل من acceptRide.php عبر السوكيت
    socket.on('ride_taken', (data) {
      print("🗑️ Socket: Ride Taken: $data");
      if (data != null && data['ride_id'] != null) {
        // حذف الرحلة من القائمة فوراً
        availableRides.removeWhere(
            (r) => r['id'].toString() == data['ride_id'].toString());
      }
    });
  }

  // دالة مساعدة للتحقق من نوع السيارة
  bool _isCarTypeMatch(String? rideCarType) {
    if (rideCarType == null) return false;
    String myDriverType = box.read(BoxName.carTypeOfDriver).toString();

    // منطق التوزيع الهرمي
    switch (myDriverType) {
      case 'Comfort':
        return ['Speed', 'Comfort', 'Fixed Price'].contains(rideCarType);
      case 'Speed':
      case 'Scooter':
      case 'Awfar Car':
        return rideCarType == myDriverType;
      case 'Lady':
        return ['Comfort', 'Speed', 'Lady'].contains(rideCarType);
      default:
        return true; // احتياطياً
    }
  }

  // تشغيل صوت التنبيه
  Future<void> _playNotificationSound() async {
    try {
      // تأكد من وجود الملف في assets وإضافته في pubspec.yaml
      await _audioPlayer.setAsset('assets/audio/notification.mp3');
      _audioPlayer.play();
    } catch (e) {
      // تجاهل الخطأ إذا لم يوجد ملف صوت
    }
  }
}
