import 'dart:math';

import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart';
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';

class DoctorMapper{
  static Future<RegionList> getMappedDoctor(List<DoctorList> doctorList,
      {bool isArabic = false}) async {
    RegionList regionList = RegionList();
    AppSharedPreferences sharedPref = AppSharedPreferences();

    for (var element in doctorList) {
      String? region = element.getRegionName(isArabic);
      if (region == null) continue;

      var regionDoctorList = regionList.registeredDoctorMap?.putIfAbsent(region, () => PatientDoctorAppointmentListByRegion());

      List<PatientDoctorAppointmentList>? targetList = element.isHMC == true
          ? regionDoctorList?.hmcDoctorList
          : regionDoctorList?.hmgDoctorList;

      var doctorByHospital = targetList
              ?.where((clinic) =>
                  clinic.filterName == element.getProjectCompleteName())
              .toList() ??
          [];

      if (doctorByHospital.isNotEmpty) {
        doctorByHospital.first.patientDoctorAppointmentList?.add(element);
      } else {
        var newAppointment = PatientDoctorAppointmentList(
          filterName: element.getProjectCompleteName(),
          distanceInKMs: element.projectDistanceInKiloMeters.toString(),
          projectTopName: element.projectTopName,
          projectBottomName: element.projectBottomName,
          patientDoctorAppointment: element,
        );
        if(element.projectDistanceInKiloMeters!= null ){
          if(regionDoctorList!.distance>element.projectDistanceInKiloMeters){
            regionDoctorList!.distance = element.projectDistanceInKiloMeters;
          }
        }else
        if (await sharedPref.getDouble(USER_LAT) != null && await sharedPref.getDouble(USER_LONG) != null && element.latitude != null && element.longitude != null) {
          var lat = await sharedPref.getDouble(USER_LAT);
          var long = await sharedPref.getDouble(USER_LONG);

          double distance =  calculateDistance(lat, long, double.parse(element.latitude!), double.parse(element.longitude!));
          if(distance<0){
            distance *= -1;
          }
          if(regionDoctorList!.distance>distance){
            regionDoctorList!.distance = distance;
          }
          print("the distance is $distance");
        }
        targetList?.add(newAppointment);
      }




      regionDoctorList?.hmcSize = regionDoctorList.hmcDoctorList?.length ?? 0;
      regionDoctorList?.hmgSize = regionDoctorList.hmgDoctorList?.length ?? 0;

      regionList.registeredDoctorMap?[region] = regionDoctorList;
    }

    return regionList;
  }
  static double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
    var pi = 3.142;
    const double R = 6371;
    double dLat = (lat2 - lat1) * pi / 180;
    double dLon = (lon2 - lon1) * pi / 180;
    double a = sin(dLat / 2) * sin(dLat / 2) +
        cos(lat1 * pi / 180) * cos(lat2 * pi / 180) * sin(dLon / 2) * sin(dLon / 2);
    double c = 2 * atan2(sqrt(a), sqrt(1 - a));
    return R * c;
  }

  static Future<RegionList> sortList(bool isGPSEnabled, RegionList unsorted, )  async {
    if(isGPSEnabled){
      if(unsorted.registeredDoctorMap == null) return unsorted;
      var sortedMap = Map.fromEntries(
        unsorted.registeredDoctorMap!.entries.toList()
          ..sort((a, b) => a.value!.distance.compareTo(b.value!.distance)),
      );

      unsorted.registeredDoctorMap = sortedMap;
      return unsorted;

    }

    List<String>? keys = unsorted.registeredDoctorMap?.keys.toList();
    keys?.sort();

    if (keys == null) return unsorted;
    Map<String, PatientDoctorAppointmentListByRegion> sortedMap = {};
    for (var key in keys) {
      sortedMap[key] = unsorted.registeredDoctorMap![key]!;
    }
    unsorted.registeredDoctorMap = sortedMap;
    return unsorted;
  }
}