import 'package:geolocator/geolocator.dart';
import 'package:get/get.dart';
import 'package:intaleq_maps/intaleq_maps.dart';
import 'package:siro_driver/constant/box_name.dart';
import 'package:siro_driver/constant/country_polygons.dart';
import 'package:siro_driver/constant/city_polygons.dart';
import 'package:siro_driver/main.dart';
import '../../print.dart';

class CountryLogic {
  /// Formats the phone number based on the country's dialing rules.
  static String formatPhone(String phone, String country) {
    phone = phone.replaceAll(RegExp(r'[ \-\(\)\+]'), '').trim();

    if (country == 'Egypt') {
      // Rule: 010, 011, 012, 015 -> 2010, 2011, 2012, 2015
      if (phone.startsWith('0020')) phone = phone.replaceFirst('0020', '20');
      if (phone.startsWith('01') && phone.length >= 10) {
        return '20${phone.substring(1)}';
      }
      if (phone.startsWith('1') &&
          phone.length >= 9 &&
          !phone.startsWith('20')) {
        return '20$phone';
      }
      if (!phone.startsWith('20') && phone.length > 8) return '20$phone';
    } else if (country == 'Jordan') {
      // Rule: 07x -> 9627x
      if (phone.startsWith('00962')) phone = phone.replaceFirst('00962', '962');
      if (phone.startsWith('07') && phone.length >= 9) {
        return '962${phone.substring(1)}';
      }
      if (phone.startsWith('7') &&
          phone.length >= 8 &&
          !phone.startsWith('962')) {
        return '962$phone';
      }
      if (!phone.startsWith('962') && phone.length > 7) return '962$phone';
    } else {
      // Default to Syria
      if (phone.startsWith('00963')) phone = phone.replaceFirst('00963', '963');
      if (phone.startsWith('0963')) phone = phone.replaceFirst('0963', '963');
      if (phone.startsWith('096309')) {
        phone = phone.replaceFirst('096309', '963');
      }
      if (phone.startsWith('96309')) phone = '9639${phone.substring(5)}';
      if (phone.startsWith('9630')) phone = '9639${phone.substring(4)}';
      if (phone.startsWith('9639') && phone.length == 12) return phone;
      if (phone.startsWith('963') &&
          phone.length > 3 &&
          !phone.startsWith('9639')) {
        phone = '9639${phone.substring(3)}';
      }
      if (phone.startsWith('09')) return '963${phone.substring(1)}';
      if (phone.startsWith('9') && phone.length == 9) return '963$phone';
      if (phone.startsWith('0') && phone.length == 10) {
        return '963${phone.substring(1)}';
      }
    }
    return phone;
  }

  /// Returns the default country prefix (EG, JO, SY) for UI initial selection.
  static String getCountryPrefix(String country) {
    if (country == 'Egypt') return 'EG';
    if (country == 'Jordan') return 'JO';
    return 'SY';
  }

  /// Returns the default emergency number for the country.
  static String getEmergencyNumber(String country) {
    if (country == 'Egypt') return '122';
    if (country == 'Jordan') return '911';
    return '112'; // Syria
  }

  /// Returns the hint text for phone inputs based on the country.
  static String getPhoneHint(String country) {
    if (country == 'Egypt') return 'e.g. 01012345678 (Default +20)';
    if (country == 'Jordan') return 'e.g. 0791234567 (Default +962)';
    return 'e.g. 0912345678 (Default +963)'; // Syria
  }

  /// Helper to format phone using the current country in box.
  static String formatCurrentCountryPhone(String phone) {
    String cleanPhone = phone.replaceAll(RegExp(r'[ \-\(\)\+]'), '').trim();
    
    // 1. Explicit International Code Detection
    if (cleanPhone.startsWith('00963')) {
      cleanPhone = cleanPhone.replaceFirst('00963', '963');
    }
    if (cleanPhone.startsWith('00962')) {
      cleanPhone = cleanPhone.replaceFirst('00962', '962');
    }
    if (cleanPhone.startsWith('0020')) {
      cleanPhone = cleanPhone.replaceFirst('0020', '20');
    }

    if (cleanPhone.startsWith('963')) {
      return formatPhone(cleanPhone, 'Syria');
    }
    if (cleanPhone.startsWith('962')) {
      return formatPhone(cleanPhone, 'Jordan');
    }
    if (cleanPhone.startsWith('20')) {
      return formatPhone(cleanPhone, 'Egypt');
    }

    // 2. Local/National Format Detection by Country-Specific Mobile Prefixes
    // Jordan: 07x / 7x (9 national digits)
    if (cleanPhone.startsWith('07') && cleanPhone.length == 10) {
      return formatPhone(cleanPhone, 'Jordan');
    }
    if (cleanPhone.startsWith('7') && cleanPhone.length == 9) {
      return formatPhone(cleanPhone, 'Jordan');
    }

    // Syria: 09x / 9x (9 national digits)
    if (cleanPhone.startsWith('09') && cleanPhone.length == 10) {
      return formatPhone(cleanPhone, 'Syria');
    }
    if (cleanPhone.startsWith('9') && cleanPhone.length == 9) {
      return formatPhone(cleanPhone, 'Syria');
    }

    // Egypt: 01x (10 national digits) / 1x (9 national digits)
    if (cleanPhone.startsWith('01') && cleanPhone.length == 11) {
      return formatPhone(cleanPhone, 'Egypt');
    }
    if (cleanPhone.startsWith('1') && cleanPhone.length == 10) {
      return formatPhone(cleanPhone, 'Egypt');
    }

    // 3. Fallback: Default to current user's country code saved in box
    final country = box.read(BoxName.countryCode) ?? 'Syria';
    return formatPhone(cleanPhone, country);
  }

  /// التحقق مما إذا كانت نقطة داخل مضلع (Ray Casting Algorithm)
  static bool isPointInPolygon(LatLng point, List<LatLng> polygon) {
    int intersections = 0;
    for (int i = 0; i < polygon.length; i++) {
      final v1 = polygon[i];
      final v2 = polygon[(i + 1) % polygon.length];

      if ((v1.latitude <= point.latitude && v2.latitude > point.latitude) ||
          (v2.latitude <= point.latitude && v1.latitude > point.latitude)) {
        final t = (point.latitude - v1.latitude) / (v2.latitude - v1.latitude);
        if (point.longitude <
            v1.longitude + t * (v2.longitude - v1.longitude)) {
          intersections++;
        }
      }
    }
    return intersections % 2 != 0;
  }

  /// كشف الدولة تلقائياً عبر الموقع الجغرافي
  /// باستخدام مضلعات الدول المحددة في CountryPolygons
  /// تعيد 'Syria' | 'Egypt' | 'Jordan' | null (في حال الفشل)
  static Future<String?> detectByLocation() async {
    try {
      bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
      if (!serviceEnabled) {
        Log.print('[CountryLogic] GPS غير مفعل');
        return null;
      }

      LocationPermission permission = await Geolocator.checkPermission();
      if (permission == LocationPermission.denied) {
        permission = await Geolocator.requestPermission();
        if (permission == LocationPermission.denied) {
          Log.print('[CountryLogic] رفض الإذن');
          return null;
        }
      }
      if (permission == LocationPermission.deniedForever) return null;

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

      final point = LatLng(pos.latitude, pos.longitude);

      // فحص المضلعات بالترتيب: Jordan → Syria → Egypt
      if (isPointInPolygon(point, CountryPolygons.jordanBoundary)) {
        return 'Jordan';
      }
      if (isPointInPolygon(point, CountryPolygons.syriaBoundary)) {
        return 'Syria';
      }
      if (isPointInPolygon(point, CountryPolygons.egyptBoundary)) {
        return 'Egypt';
      }

      Log.print('[CountryLogic] الموقع خارج جميع المضلعات');
    } catch (e) {
      Log.print('[CountryLogic] detectByLocation error: $e');
    }
    return null;
  }

  /// تهيئة الدولة عند بدء التطبيق
  /// إذا لم تكن الدولة محددة مسبقاً → يكشفها عبر الموقع
  /// إذا فشل الكشف → Jordan كخيار افتراضي
  static Future<void> initializeCountry() async {
    final existing = box.read(BoxName.countryCode);
    if (existing != null && existing.toString().isNotEmpty) {
      Log.print('[CountryLogic] الدولة موجودة مسبقاً: $existing');
      return;
    }

    Log.print('[CountryLogic] كشف الدولة عبر الموقع...');
    final country = await detectByLocation();

    if (country != null) {
      box.write(BoxName.countryCode, country);
      Log.print('[CountryLogic] تم الكشف: $country');
    } else {
      box.write(BoxName.countryCode, 'Jordan');
      Log.print('[CountryLogic] افتراضي: Jordan');
    }
  }

  /// إرجاع مضلع المدينة بناءً على الدولة الحالية
  static List<LatLng> getCurrentCityPolygon() {
    final country = box.read(BoxName.countryCode) ?? 'Jordan';
    if (country == 'Syria') return CityPolygons.damascusPolygon;
    if (country == 'Egypt') return CityPolygons.cairoPolygon;
    return CityPolygons.ammanPolygon;
  }
}
