import 'dart:developer';

import 'package:easy_localization/easy_localization.dart';
import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/features/authentication/models/request_models/registration_payload_model.dart';
import 'package:hmg_patient_app_new/features/authentication/models/request_models/send_activation_request_model.dart';
import 'package:hmg_patient_app_new/features/common/models/commong_authanticated_req_model.dart';
import 'package:hmg_patient_app_new/features/common/models/family_file_request.dart';
import 'package:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_calendar_model.dart';

class RequestUtils {
  static dynamic getPatientAuthenticationRequest({
    required String phoneNumber,
    required String nationId,
    required OTPTypeEnum otpTypeEnum,
    required bool patientOutSA,
    required bool isForRegister,
    required int? patientId,
    required String zipCode,
    required CalenderEnum calenderType,
    String? dob,
  }) {
    bool fileNo = false;
    if (nationId.isNotEmpty) {
      final numericRegex = RegExp(r'^[0-9]+$');
      fileNo = nationId.length < 10 && numericRegex.hasMatch(nationId);
      //fileNo = nationId.length < 10 && nationId.isNumericOnly() ;
      if (fileNo) {
        patientId = int.tryParse(nationId);
      }
    }
    var request = SendActivationRequest();
    if (phoneNumber.isNotEmpty) {
      // If zipCode is "0", it means "Others" country is selected
      if (zipCode == "0") {
        request.patientMobileNumberOthers = phoneNumber;
      } else {
        // Remove any non-numeric characters before parsing
        final numericPhone = phoneNumber.replaceAll(RegExp(r'[^0-9]'), '');
        final parsedPhone = int.tryParse(numericPhone);
        if (parsedPhone != null) {
          request.patientMobileNumber = parsedPhone;
        } else {
          // If parsing fails, use as string in Others field
          request.patientMobileNumberOthers = phoneNumber;
        }
      }
    }
    request.oTPSendType = otpTypeEnum.toInt(); // could map OTPTypeEnum if needed
    request.zipCode = zipCode; // or countryCode if defined elsewhere

    if (isForRegister) {
      final parsedNationId = int.tryParse(nationId.replaceAll(RegExp(r'[^0-9]'), ''));
      request.patientIdentificationID = parsedNationId ?? 0;
      request.searchType = 1;
      request.isHijri = calenderType.toInt;
      request.patientID = patientId;
      request.dob = dob;
      request.patientOutSA = patientOutSA ? 1 : 0;
      request.isDentalAllowedBackend = false;
    } else {
      if (fileNo) {
        request.patientID = patientId ?? (int.tryParse(nationId.replaceAll(RegExp(r'[^0-9]'), '')) ?? 0);
        request.patientIdentificationID = request.nationalID;
        request.searchType = 2;
      } else {
        request.patientID =  0;
        request.searchType = 1;
        request.patientIdentificationID = request.nationalID = nationId.isNotEmpty ? nationId : '0';
      }
      request.isRegister = false;
    }
    return request;
  }

  static dynamic getCommonRequestWelcome(
      {required String phoneNumber,
        required OTPTypeEnum otpTypeEnum,
        required String? deviceToken,
        required bool patientOutSA,
        required String? loginTokenID,
        RegistrationDataModelPayload? registeredData,
        int? patientId,
        required String nationIdText,
        required String countryCode,
        required int loginType}) {
    bool fileNo = false;
    if (nationIdText.isNotEmpty) {
      final numericRegex = RegExp(r'^[0-9]+$');
      fileNo = nationIdText.length < 10 && numericRegex.hasMatch(nationIdText);
    }
    var request = SendActivationRequest();
    // If countryCode is "0", it means "Others" country is selected
    if (countryCode == "0") {
      request.patientMobileNumberOthers = phoneNumber;
      request.mobileNo = phoneNumber;
    } else {
      // Remove any non-numeric characters before parsing
      final numericPhone = phoneNumber.replaceAll(RegExp(r'[^0-9]'), '');
      final parsedPhone = int.tryParse(numericPhone);
      if (parsedPhone != null) {
        request.patientMobileNumber = parsedPhone;
        request.mobileNo = '0$numericPhone';
      } else {
        // If parsing fails, use as string in Others field
        request.patientMobileNumberOthers = phoneNumber;
        request.mobileNo = phoneNumber;
      }
    }
    request.deviceToken = deviceToken;
    request.projectOutSA = patientOutSA;
    request.loginType = loginType;
    request.oTPSendType = otpTypeEnum.toInt(); // could map OTPTypeEnum if needed
    request.zipCode = countryCode; // or countryCode if defined elsewhere
    request.logInTokenID = loginTokenID ?? "";

    if (registeredData != null) {
      //TODO: Issue Here if Not Signup
      request.searchType = registeredData.searchType != null
          ? registeredData.searchType
          : fileNo
          ? 1
          : 2;
      request.patientID = registeredData.patientId ?? 0;
      request.patientIdentificationID = request.nationalID = (registeredData.patientIdentificationId ?? 0);
      request.dob = registeredData.dob;
      request.isRegister = registeredData.isRegister;
      log("nationIdText: ${nationIdText}");
    } else {
      if (fileNo) {
        final numericNationId = nationIdText.replaceAll(RegExp(r'[^0-9]'), '');
        request.patientID = patientId ?? (int.tryParse(numericNationId) ?? 0);
        request.patientIdentificationID = request.nationalID = '0';
        request.searchType = 2;
        //TODO: Issue HEre is Not Login
      } else {
        request.patientID = 0;
        request.searchType = 1;
        //TODO: Issue HEre is Not Login
        request.patientIdentificationID = request.nationalID = (nationIdText.isNotEmpty ? nationIdText : '0');
      }
      request.isRegister = false;
    }

    request.deviceTypeID = request.searchType;
    return request;
  }

  static getCommonRequestSendActivationCode({
    required OTPTypeEnum otpTypeEnum,
    required String mobileNumber,
    required String zipCode,
    required int? patientId,
    required dynamic nationalId,
    required bool patientOutSA,
    required int selectedLoginType,
    required bool isForRegister,
    required bool isFileNo,
    dynamic payload,
    required bool isExcludedUser,
    required bool isFormFamilyFile,
    int? responseID,
  }) {
    AppState _appState = getIt.get<AppState>();
    var request = SendActivationRequest();
    if (mobileNumber.isNotEmpty) {
      // If zipCode is "0", it means "Others" country is selected
      if (zipCode == "0") {
        request.patientMobileNumberOthers = mobileNumber;
        request.mobileNo = mobileNumber;
      } else {
        // Remove any non-numeric characters before parsing
        final numericMobile = mobileNumber.replaceAll(RegExp(r'[^0-9]'), '');
        final parsedMobile = int.tryParse(numericMobile);
        if (parsedMobile != null) {
          request.patientMobileNumber = parsedMobile;
          request.mobileNo = '0$numericMobile';
        } else {
          // If parsing fails, use as string in Others field
          request.patientMobileNumberOthers = mobileNumber;
          request.mobileNo = mobileNumber;
        }
      }
    }
    request.projectOutSA = patientOutSA;
    request.loginType = selectedLoginType;
    request.oTPSendType = otpTypeEnum.toInt(); //this.selectedOption == 1 ? 1 : 2;
    request.zipCode = zipCode;

    if (isForRegister && payload != null) {
      request.searchType = isFileNo ? 2 : 1;
      // request.searchType = payload["SearchType"];
      request.patientID = payload["PatientID"];
      request.patientIdentificationID = request.nationalID = payload["PatientIdentificationID"] ?? '0';
      request.dob = payload["DOB"];
      request.isRegister = payload["isRegister"];
      request.healthId = patientOutSA ? null : _appState.getNHICUserData.healthId;
      request.isHijri = payload["IsHijri"];
      request.deviceToken = _appState.deviceToken;
      request.projectOutSA = patientOutSA;
    } else {
      request.searchType = isFileNo ? 2 : 1;
      request.patientID = patientId ?? 0;
      request.nationalID = nationalId ?? 0;
      request.patientIdentificationID = (nationalId ?? '0');
      request.isRegister = false;
    }
    request.deviceTypeID = request.searchType;

    if (isFormFamilyFile) {
      //INFO: Only for Excluded User Family Member Addition
      request.isPatientExcluded = isExcludedUser;
      request.responseID = responseID;
      request.status = 2;
      request.familyRegionID = zipCode == CountryEnum.saudiArabia.countryCode ? 1 : 2;
    }

    return request;
  }

  //DeviceToken":""
  //

  //{"PatientMobileNumber":530896018,"MobileNo":"0530896018","DeviceToken":"","ProjectOutSA":false,"LoginType":1,"ZipCode":"966","isRegister":true,"LogInTokenID":"","SearchType":2,"PatientID":0,"NationalID":"2599865082","PatientIdentificationID":"2599865082","OTP_SendType":1,"LanguageID":2,"VersionID":18.7,"Channel":3,"IPAdress":"10.20.10.20","generalid":"Cs2020@2016$2958","PatientOutSA":0,"isDentalAllowedBackend":false,"DeviceTypeID":1,"DOB":"19/07/1997","IsHijri":0,"HealthId":"30000541803510","Latitude":0.0,"Longitude":0.0,"PatientType":1}

  //{"PatientMobileNumber":530896018,"MobileNo":"0530896018","DeviceToken":"","ProjectOutSA":false,"LoginType":1,"ZipCode":"966","isRegister":true,"LogInTokenID":"","SearchType":1,"PatientID":0,"NationalID":"2599865082","PatientIdentificationID":"2599865082","OTP_SendType":1,"LanguageID":"2","VersionID":"18.7","Channel":"3","IPAdress":"10.20.10.20","generalid":"Cs2020@2016$2958","PatientOutSA":0,"SessionID":"TMRhVmkGhOsvamErw","isDentalAllowedBackend":false,"DeviceTypeID":"1","SMSSignature":"enKTDcqbOVd","DOB":"19/07/1997","PatientType":"1","Latitude":"0.0","Longitude":"0.0"}

  static getAuthanticatedCommonRequest() {
    AppState _appState = getIt.get<AppState>();
    var request = CommonAuthanticatedRequest();
    request.sessionId = ApiConsts.sessionID;
    request.latitude = _appState.userLat;
    request.longitude = _appState.userLong;
    request.languageId = _appState.getLanguageID();
    request.versionId = ApiConsts.appVersionID;
    request.ipAdress = ApiConsts.appIpAddress;
    request.deviceTypeId = _appState.getDeviceTypeID();
    request.patientTypeId = _appState.getAuthenticatedUser()?.patientType;
    request.patientType = _appState.getAuthenticatedUser()?.patientType;
    request.generalid = ApiConsts.appGeneralId;
    request.channel = ApiConsts.appChannelId;
    request.patientId = _appState.getAuthenticatedUser()!.patientId;
    request.patientOutSa = _appState.getAuthenticatedUser()!.outSa;
    request.tokenId = null;
    return request;
  }

  static dynamic getUserSignupCompletionRequest(
      {String? fullName, String? emailAddress, GenderTypeEnum? gender, MaritalStatusTypeEnum? maritalStatus}) {
    AppState appState = getIt.get<AppState>();

    bool isDubai = appState.getUserRegistrationPayload.patientOutSa == 1 ? true : false;
    List<String> names = fullName != null ? fullName.split(" ") : [];

    var dob = appState.getUserRegistrationPayload.dob;
    final DateFormat dateFormat1 = DateFormat('MM/dd/yyyy', "en-US");
    final DateFormat dateFormat2 = DateFormat('dd/MM/yyyy', "en-US");
    DateTime gregorianDate = dateFormat2.parse(dob!);
    HijriGregDate hijriDate = HijriGregConverter.gregorianToHijri(gregorianDate);
    String? date = "${hijriDate.day}/${hijriDate.month}/${hijriDate.year}";

    return {
      "Patientobject": {
        "TempValue": true,
        "PatientIdentificationType": (isDubai
            ? appState.getUserRegistrationPayload.patientIdentificationId?.toString().substring(0, 1)
            : appState.getNHICUserData.idNumber!.substring(0, 1)) ==
            "1"
            ? 1
            : 2,
        "PatientIdentificationNo":
        isDubai ? appState.getUserRegistrationPayload.patientIdentificationId.toString() : appState.getNHICUserData.idNumber.toString(),
        "MobileNumber": appState.getUserRegistrationPayload.patientMobileNumber ?? 0,
        "PatientOutSA": (appState.getUserRegistrationPayload.zipCode == CountryEnum.saudiArabia.countryCode ||
            appState.getUserRegistrationPayload.zipCode == '+966')
            ? 0
            : 1,
        "FirstNameN": isDubai ? "..." : appState.getNHICUserData.firstNameAr,
        "FirstName": isDubai ? (names.isNotEmpty ? names[0] : "...") : appState.getNHICUserData.firstNameEn,
        "MiddleNameN": isDubai ? "..." : appState.getNHICUserData.secondNameAr,
        "MiddleName": isDubai ? "..." : appState.getNHICUserData.secondNameEn,
        "LastNameN": isDubai ? "..." : appState.getNHICUserData.lastNameAr,
        "LastName": isDubai ? (names.length > 1 ? names[1] : "...") : appState.getNHICUserData.lastNameEn,
        "StrDateofBirth": dateFormat1.format(dateFormat2.parse(dob)),
        "DateofBirth": DateUtil.convertISODateToJsonDate((dob ?? "").replaceAll('/', '-')),
        "Gender": isDubai ? (gender == GenderTypeEnum.male ? 1 : 2) : (appState.getNHICUserData.gender == 'M' ? 1 : 2),
        "NationalityID": isDubai ? "UAE" : appState.getNHICUserData.nationalityCode,
        "eHealthIDField": isDubai ? null : appState.getNHICUserData.healthId,
        "DateofBirthN": date,
        "EmailAddress": emailAddress,
        "SourceType": (appState.getUserRegistrationPayload.zipCode == CountryEnum.saudiArabia.countryCode ||
            appState.getUserRegistrationPayload.zipCode == '+966')
            ? "1"
            : "2",
        "PreferredLanguage": appState.getLanguageCode() == "ar" ? (isDubai ? "1" : 1) : (isDubai ? "2" : 2),
        "Marital": isDubai
            ? (maritalStatus == MaritalStatusTypeEnum.single
            ? '0'
            : maritalStatus == MaritalStatusTypeEnum.married
            ? '1'
            : '2')
            : (appState.getNHICUserData.maritalStatusCode == 'U'
            ? '0'
            : appState.getNHICUserData.maritalStatusCode == 'M'
            ? '1'
            : '2'),
      },
      "PatientIdentificationID":
      isDubai ? appState.getUserRegistrationPayload.patientIdentificationId.toString() : appState.getNHICUserData.idNumber.toString(),
      "PatientMobileNumber": appState.getUserRegistrationPayload.patientMobileNumber.toString()[0] == '0'
          ? appState.getUserRegistrationPayload.patientMobileNumber
          : '0${appState.getUserRegistrationPayload.patientMobileNumber}',
      "DOB": dob,
      "IsHijri": appState.getUserRegistrationPayload.isHijri,
      "PatientOutSA": (appState.getUserRegistrationPayload.zipCode == CountryEnum.saudiArabia.countryCode ||
          appState.getUserRegistrationPayload.zipCode == '+966')
          ? 0
          : 1,
      "isDentalAllowedBackend": appState.getUserRegistrationPayload.isDentalAllowedBackend,
      "ZipCode": appState.getUserRegistrationPayload.zipCode,
      if (!isDubai) "HealthId": appState.getNHICUserData.healthId,
    };
  }

  static Future<FamilyFileRequest> getAddFamilyRequest(
      {required String nationalIDorFile, required String mobileNo, required String countryCode}) async {
    FamilyFileRequest request = FamilyFileRequest();
    int? loginType = 0;

    if (countryCode == CountryEnum.saudiArabia.countryCode || countryCode == '+966') {
      loginType = (nationalIDorFile.length == 10) ? 1 : 2;
    } else if (countryCode == CountryEnum.unitedArabEmirates.countryCode || countryCode == '+971') {
      loginType = (nationalIDorFile.length == 15) ? 1 : 2;
    }

    if (loginType == 1) {
      request.sharedPatientId = 0;
      request.sharedPatientIdentificationId = nationalIDorFile;
    } else if (loginType == 2) {
      // Remove any non-numeric characters before parsing
      final numericId = nationalIDorFile.replaceAll(RegExp(r'[^0-9]'), '');
      request.sharedPatientId = int.tryParse(numericId) ?? 0;
      request.sharedPatientIdentificationId = '';
    }
    request.searchType = loginType;
    request.sharedPatientMobileNumber = mobileNo;
    request.zipCode = countryCode;
    request.isRegister = false;
    request.patientStatus = 2;
    request.isDentalAllowedBackend = false;
    return request;
  }
}