import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter_contacts/contact.dart';
// import 'package:flutter_contacts/contact.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:get/get.dart';
import 'package:uco_mobile_poc/app/core/config/server_response.dart';
import 'package:uco_mobile_poc/app/core/constants/app_contants.dart';
import 'package:uco_mobile_poc/app/core/constants/translation_keys.dart';
import 'package:uco_mobile_poc/app/core/data/repositories/app_repositories.dart';
import 'package:uco_mobile_poc/app/core/enums/request_constants.dart';
import 'package:uco_mobile_poc/app/core/utils/SessionCache.dart';
import 'package:uco_mobile_poc/app/core/utils/app_utils.dart';
import 'package:uco_mobile_poc/app/core/utils/logs_utils.dart';
import 'package:uco_mobile_poc/app/custom_widgets/Fields/field_validations.dart';
import 'package:uco_mobile_poc/app/custom_widgets/Fields/input_field.dart';
import 'package:uco_mobile_poc/app/custom_widgets/custom_dropdown.dart';
import 'package:uco_mobile_poc/app/custom_widgets/custom_toasty.dart';
import 'package:uco_mobile_poc/app/models/AccountInquiryResponseModel.dart';
import 'package:uco_mobile_poc/app/models/DepositAccountResponse.dart';
import 'package:uco_mobile_poc/app/models/ExchangeRate.dart';
import 'package:uco_mobile_poc/app/models/SendTransactionStep1ResponseModel.dart';
import 'package:uco_mobile_poc/app/models/TransactionPinRequestModel.dart';
import 'package:uco_mobile_poc/app/models/TransactionSubmitRequestModel.dart';
import 'package:uco_mobile_poc/app/modules/qr_setting/controllers/qr_setting_controller.dart';
import 'package:uco_mobile_poc/app/modules/qr_setting/views/qr_scan_screen.dart';
import 'package:uco_mobile_poc/app/res/app_colors.dart';
import 'package:uco_mobile_poc/app/routes/app_pages.dart';

class USendController extends GetxController {
  TextEditingController pinPutController = TextEditingController();
  TextEditingController referenceCodeController = TextEditingController();
  final AppRepositories repository = Get.find<AppRepositories>();

  BuildContext context = Get.context as BuildContext;

  String OPTION_PHONE = "01";

  String OPTION_EMAIL = "02";

  //drop down
  RxList<DropDown> allDepositAccounts = RxList.empty();

  Rx<DepositAccount> selectedDepositAccount = DepositAccount.empty().obs;

  RxList<DropDown> allRecipientDetailOptions = RxList.empty();
  Rx<DropDown> selectedRecipientDetailOption = DropDown.empty().obs;

  RxList<DropDown> allCurrencieList = RxList.empty();
  DropDown selectedCurrency = DropDown.empty();
  RxString currencySymbol = "".obs;

  Contact? selectedContact;
  ExchangeRate? selectedExchangeRate;
  String receiverAccountNumber = "";
  String receiverAccountTitle = "";

  // fields
  late InputField depositAccountField;
  late InputField selectRecipientDetailField;

  late InputField selectCurrencyField;
  late InputField identityPhoneNumberField;
  late InputField identityEmailField;
  late InputField recipientCardNameField;
  late InputField sendingAmountField;
  late InputField exchangeRateField;
  late InputField messageField;
  late InputField userTransactionPinField;
  late InputField referenceCodeField;

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

    for (int i = 0; i < SessionCache.instance.depositAccountList.length; i++) {
      DepositAccount depositAccount = SessionCache.instance.depositAccountList.elementAt(i);

      allDepositAccounts.add(DropDown(i.toString(), "${depositAccount.mbmBkmstitle} - ${depositAccount.mbmBkmsnumber}", depositAccount));
    }

    selectedDepositAccount.value = allDepositAccounts.first.data;

    allRecipientDetailOptions.value = <DropDown>[
      DropDown(OPTION_PHONE, TranslationKeys.makeTranslation(TranslationKeys.textPhoneNumber)),
      DropDown(OPTION_EMAIL, TranslationKeys.makeTranslation(TranslationKeys.textEmail)),
    ];

    for (int i = 0; i < SessionCache.instance.exchangeRateList.length; i++) {
      ExchangeRate exchangeRate = SessionCache.instance.exchangeRateList.elementAt(i);
      allCurrencieList.add(DropDown(exchangeRate.pcrCurrcode, exchangeRate.pcrCurrdesc, exchangeRate));
    }
  }

  @override
  Future<void> onReady() async {
    super.onReady();

    disposeAllResources();

    updateSelectedDeposit(allDepositAccounts.elementAt(0));

    Future.delayed(Duration.zero).then((value) {
      depositAccountField.setText((allDepositAccounts.first.label));
    });
  }

  void disposeAllResources() {
    depositAccountField.clear();
    selectRecipientDetailField.clear();
    selectCurrencyField.clear();
    identityPhoneNumberField.clear();
    identityEmailField.clear();
    recipientCardNameField.clear();
    sendingAmountField.clear();
    exchangeRateField.clear();
    messageField.clear();
    userTransactionPinField.clear();
    referenceCodeField.clear();
    referenceCodeController.clear();
  }

  void updateSelectedDeposit(DropDown item) {
    selectedDepositAccount.value = item.data as DepositAccount;
  }

  // void updateSelectedCurrency(/*DropDown? item*/ AccountInquiryResponseModel model) {
  //   print("************************model>> $model");
  //
  //   for (int i = 0; i < SessionCache.instance.exchangeRateList.length; i++) {
  //     print("************************elementAt(i).pcrCurrcode>> ${SessionCache.instance.exchangeRateList.elementAt(i).pcrCurrcode}");
  //     if (SessionCache.instance.exchangeRateList.elementAt(i).pcrCurrcode == model.pcrCurrcode) {
  //       currencySymbol.value = SessionCache.instance.exchangeRateList.elementAt(i).pcrCurrshort;
  //       selectedExchangeRate = SessionCache.instance.exchangeRateList.elementAt(i);
  //       exchangeRateField.setText(selectedExchangeRate!.perEratrateact.toString());
  //       break;
  //     }
  //   }
  // }

  void updateSelectedCurrency(DropDown? item) {
    if (item == null) return;

    // Get ExchangeRate object from dropdown data
    ExchangeRate model = item.data as ExchangeRate;

    print("************************model>> $model");

    currencySymbol.value = model.pcrCurrshort ?? "";

    selectedExchangeRate = model;

    exchangeRateField.setText(
      selectedExchangeRate!.perEratrateact.toString(),
    );
  }

  void updateRecipientDetail(DropDown? item) {
    selectedRecipientDetailOption.value = item!;
  }

  Future<void> selectContact() async {
    dynamic result = await Get.toNamed(Routes.CONTACTS_SCREEN);

    if ((result != null && result[AppConstants.SELECTED_CONTACT] != null)) {
      selectedContact = result[AppConstants.SELECTED_CONTACT];
      identityPhoneNumberField.setText(AppUtils.formatPhoneNumber(selectedContact!.phones.first.number) /*"${selectedContact!.displayName} (${AppUtils.formatPhoneNumber(selectedContact!.phones.first.number + ")")}"*/);
    }
  }

  bool validate() {
    bool isValid = FieldValidation.validateAll([
      depositAccountField,
      selectRecipientDetailField,
      recipientCardNameField,
      sendingAmountField,
      exchangeRateField,
      userTransactionPinField,
      referenceCodeField,
    ]);
    if (selectedRecipientDetailOption.value.id == OPTION_PHONE) {
      isValid = FieldValidation.validateAll([identityPhoneNumberField]);
    } else if (selectedRecipientDetailOption.value.id == OPTION_EMAIL) {
      isValid = FieldValidation.validateAll([identityEmailField]);
    }
    dp("Validate value", isValid);
    if (pinPutController.text.isEmpty) {
      return false;
    }
    if (referenceCodeController.text.isEmpty) {
      return false;
    }
    return isValid;
  }

  Future<void> sendTransaction({navigate = true}) async {
    if (!validate()) {
      Toasty.error("Please input and then proceed");
      return;
    }

    TransactionSubmitRequestModel transactionSubmitRequestModel = TransactionSubmitRequestModel(
      porOrgacode: RequestConstants.porOrgacode,
      pctCstycode: RequestConstants.pctCstycode,
      channelCode: RequestConstants.channelCode,
      cmpCustcode: SessionCache.instance.userInfo.cmpCustcode,
      drMbmBkmsnumber: selectedDepositAccount.value.mbmBkmsnumber,
      drMbmBkmstitle: selectedDepositAccount.value.mbmBkmstitle,
      drPcrCurrcode: selectedDepositAccount.value.pcrCurrcode,
      drPcrCurrdesc: selectedDepositAccount.value.pcrCurrdesc,
      drPcrCurrshort: selectedDepositAccount.value.pcrCurrshort,
      crMbmBkmsnumber: receiverAccountNumber,
      crMbmBkmstitle: receiverAccountTitle,
      crPcrCurrcode: selectedExchangeRate!.pcrCurrcode,
      crPcrCurrdesc: selectedExchangeRate!.pcrCurrdesc,
      crPcrCurrshort: selectedExchangeRate!.pcrCurrshort,
      sgtGntrnarration: "",
      dmpProdCode: selectedDepositAccount.value.dmpProdcode,
      transType: "DR",
      notificationId: "",
      transMode: "Online",
      sgtGntramtfc: double.parse(sendingAmountField.getCustomText().isEmpty ? "0.0" : sendingAmountField.getCustomText()),
      otdTrancomment: messageField.getCustomText(),
      isOtpRequired: false,
      cmpRefcode: referenceCodeField.getCustomText(),
    );

    TransactionPinRequestModel transactionPinRequestModel = TransactionPinRequestModel(
      porOrgacode: RequestConstants.porOrgacode,
      pctCstycode: RequestConstants.pctCstycode,
      channelCode: RequestConstants.channelCode,
      cmpCustcode: SessionCache.instance.userInfo.cmpCustcode,
      email: SessionCache.instance.userInfo.cmpUserId,
      pinType: "TRAN",
      transPincode: userTransactionPinField.getCustomText(),
      isOtpRequired: false,
    );

    ServerResponse response = await repository.sendTransactionStep1(transactionPinRequestModel);

    if (response.isError) {
      Toasty.error(response.errorMsg);
      return;
    }

    SendTransactionStep1ResponseModel step1responseModel = SendTransactionStep1ResponseModel.fromMap(response.response);
    transactionSubmitRequestModel.notificationId = step1responseModel.notificationId.toString();

    if (navigate) {
      Get.toNamed(Routes.U_SEND_OTP,
          arguments: {
        AppConstants.SEND_TRANS_STEP1_DATA: transactionSubmitRequestModel,
        AppConstants.EXCHANGE_RATE: exchangeRateField.getCustomText(),
      }
      );
    } else {
      Fluttertoast.showToast(
        msg: "OTP successfully send to your email address",
      );
    }
  }

  void clearTransaction() {
    selectRecipientDetailField.clear();
    identityPhoneNumberField.clear();
    identityEmailField.clear();
    recipientCardNameField.clear();
    sendingAmountField.clear();
    exchangeRateField.clear();
    messageField.clear();
    userTransactionPinField.clear();
    pinPutController.clear();
    referenceCodeField.clear();
    referenceCodeController.clear();
  }

  Future<void> verifyAccountAgainstIt() async {
    String valua = selectedRecipientDetailOption.value.id == OPTION_PHONE ? identityPhoneNumberField.getCustomText() : (selectedRecipientDetailOption.value.id == OPTION_EMAIL ? identityEmailField.getCustomText() : "");

    bool isValid = true;

    if (selectedRecipientDetailOption.value.id == OPTION_PHONE) {
      isValid = FieldValidation.validateAll([identityPhoneNumberField]);
    } else if (selectedRecipientDetailOption.value.id == OPTION_EMAIL) {
      isValid = FieldValidation.validateAll([identityEmailField]);
    }
    if (!isValid) {
      Toasty.error("Please input and then proceed");
      return;
    }
    ServerResponse response = await repository.fetchAccountInquiry(selectedRecipientDetailOption.value.id, valua);

    if (response.isError) {
      if (selectedRecipientDetailOption.value.id == OPTION_PHONE) {
        identityPhoneNumberField.setError(response.errorMsg);
      } else {
        identityEmailField.setError(response.errorMsg);
      }
      Toasty.error(response.errorMsg);
      return;
    }

    List<dynamic> responseData = response.response ?? [];

    List<AccountInquiryResponseModel> accountInquiryList;
    accountInquiryList = AccountInquiryResponseModel.fromList(responseData);

    accountsDialog(accountInquiryList);
    AccountInquiryResponseModel transactionSubmitRequestModel = AccountInquiryResponseModel.fromMap(((response.response ?? {}) as Map<Object?, Object?>).map((key, value) => MapEntry(key.toString(), value)));
  }

  void scanQr() async {
    Get.put(QrSettingController());

    var scanResult = await Get.to(() => const QrScanScreen());

    var resultJson = jsonDecode(scanResult);

    var accNumber = resultJson["phoneNumber"];

    dp("Phone", accNumber);

    identityPhoneNumberField.setText(accNumber);

    verifyAccountAgainstIt();
  }

  /// Accounts Dialogs...........u-send
  void accountsDialog(List<AccountInquiryResponseModel> accountInquiryList) {
    if (accountInquiryList.length == 1) {
      receiverAccountTitle = accountInquiryList.first.mbmBkmstitle;
      receiverAccountNumber = accountInquiryList.first.mbmBkmsnumber;
      recipientCardNameField.setText(receiverAccountTitle);
      // updateSelectedCurrency(accountInquiryList.first);
      return;
    }
    Get.dialog(
      responsiveWidget(
        Dialog(
          backgroundColor: Colors.transparent,
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
          child: Container(
            decoration: const BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.all(Radius.circular(10.0)),
            ),
            child: SingleChildScrollView(
              child: Padding(
                padding: const EdgeInsets.all(10),
                child: ListView(
                  physics: const NeverScrollableScrollPhysics(),
                  shrinkWrap: true,
                  children: [
                    Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        Text(TranslationKeys.makeTranslation(TranslationKeys.textSelectAccount), style: Theme.of(context).textTheme.titleMedium),
                        const SizedBox(height: 20),
                        ListView.separated(
                            shrinkWrap: true,
                            itemBuilder: (context, index) {
                              return GestureDetector(
                                onTap: () {
                                  receiverAccountTitle = accountInquiryList[index].mbmBkmstitle;
                                  receiverAccountNumber = accountInquiryList[index].mbmBkmsnumber;
                                  recipientCardNameField.setText(receiverAccountTitle);
                                  // updateSelectedCurrency(accountInquiryList[index]);
                                  Get.back();
                                },
                                child: Column(children: [
                                  Container(
                                    height: 40,
                                    width: double.infinity,
                                    decoration: const BoxDecoration(
                                      color: AppColors.colorGrey100,
                                      borderRadius: BorderRadius.all(Radius.circular(8.0)),
                                    ),
                                    child: Padding(
                                      padding: const EdgeInsets.all(8.0),
                                      child: Row(
                                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                        children: [
                                          Text("${accountInquiryList[index].mbmBkmstitle} (${accountInquiryList[index].pcrCurrshort})", style: Theme.of(context).textTheme.titleSmall),
                                          Text(accountInquiryList[index].mbmBkmsnumber, style: Theme.of(context).textTheme.titleSmall),
                                        ],
                                      ),
                                    ),
                                  ),
                                ]),
                              );
                            },
                            separatorBuilder: (BuildContext context, int index) {
                              return const Padding(padding: EdgeInsets.symmetric(vertical: 5));
                            },
                            itemCount: accountInquiryList.length),
                      ],
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
      barrierDismissible: false,
    );
  }
}
