import 'package:get/get.dart';
import 'package:get/get_core/src/get_main.dart';
import 'package:get/get_rx/src/rx_types/rx_types.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart';
import 'package:mypoint_flutter_app/shared/router_gage.dart';
import 'package:uuid/uuid.dart';
import '../../networking/restful_api_viewmodel.dart';
import '../../configs/constants.dart';
import '../../preference/contact_storage_service.dart';
import '../../preference/data_preference.dart';
import '../voucher/models/product_model.dart';
import '../webview/payment_web_view_screen.dart';
import '../webview/web_view_screen.dart';
import 'model/payment_bank_account_info_model.dart';
import 'model/payment_method_model.dart';
import 'model/preview_order_payment_model.dart';

class TransactionDetailViewModel extends RestfulApiViewModel {
  final int definedCodeIndexBankAccount = 1000;
  var previewData = Rxn<PreviewOrderPaymentModel>();
  var paymentMethods = RxList<PaymentMethodModel>();
  var paymentBankAccounts = RxList<PaymentBankAccountInfoModel>();
  final RxBool isLoading = false.obs;
  final ProductModel product;
  String? metaData;
  final int quantity;
  final String? targetPhoneNumber;
  final RxBool usePoints = true.obs;
  var selectedPaymentMethodIndex = -1.obs;
  void Function(String message)? onShowAlertError;

  int get finalTotal {
    final totalPrice = previewData.value?.totalPrice ?? 0;
    final pointValue = previewData.value?.pointData?.point ?? 0;
    final finalTotal =
        usePoints.value && previewData.value?.pointData?.status == 1 ? totalPrice - pointValue : totalPrice;
    return finalTotal;
  }

  TransactionDetailViewModel({required this.product, required this.quantity, this.targetPhoneNumber, this.metaData});

  Future<void> refreshData() async {
    isLoading.value = true;
    await Future.wait([_getPreviewOrderPayment(), _getPaymentMethods(), _getPaymentBankAccounts()]);
    isLoading.value = false;
  }

  void requestPaymentProduct() {
    showLoading();
    final requestId = Uuid().v4();
    int? point = usePoints.value ? previewData.value?.pointData?.point : 0;
    PaymentBankAccountInfoModel? selectedBankAccount;
    PaymentMethodModel? selectedPaymentMethod;
    bool? saveToken;
    if (finalTotal == 0) {
      point = previewData.value?.pointData?.point ?? 0;
    } else if (selectedPaymentMethodIndex >= definedCodeIndexBankAccount) {
      selectedBankAccount = paymentBankAccounts.value[selectedPaymentMethodIndex - definedCodeIndexBankAccount];
    } else if (selectedPaymentMethodIndex >= 0) {
      selectedPaymentMethod = paymentMethods.value[selectedPaymentMethodIndex];
      saveToken = selectedPaymentMethod?.saveToken == true && selectedPaymentMethod?.needSaveTokenWhenOrder == true;
    }
    client
        .orderSubmitPayment(
          products: [product],
          quantity: quantity,
          requestId: requestId,
          point: point,
          cash: finalTotal,
          method: selectedPaymentMethod,
          paymentTokenId: selectedBankAccount?.id,
          saveToken: saveToken,
          metadata: metaData,
          targetPhoneNumber: targetPhoneNumber,
        )
        .then((value) {
          hideLoading();
          if (value.isSuccess) {
            final data = value.data;
            if ((data?.paymentUrl ?? "").isNotEmpty) {
              if ((targetPhoneNumber ?? "").isNotEmpty) {
                ContactStorageService().saveUsedContact(targetPhoneNumber ?? "");
              }
              Get.toNamed(
                paymentWebViewScreen,
                arguments: PaymentWebViewInput(
                  url: data?.paymentUrl ?? "",
                  isContract: false,
                  orderId: data?.id ?? "",
                  showAlertBack: true,
                  callback: (result) {
                    if (result == PaymentProcess.success) {
                      Get.offNamed(
                        transactionHistoryDetailScreen,
                        arguments: {"orderId": data?.id ?? "", "canBack": true},
                      );
                    }
                  },
                )
              );
            } else if ((data?.redeemId ?? "").isNotEmpty && (data?.id ?? "").isNotEmpty) {
              Get.offNamed(transactionHistoryDetailScreen, arguments: {"orderId": data?.id ?? "", "canBack": true});
            } else {
              onShowAlertError?.call(value.errorMessage ?? Constants.commonError);
            }
          } else {
            onShowAlertError?.call(value.errorMessage ?? Constants.commonError);
          }
        });
  }

  Future<void> _getPreviewOrderPayment() async {
    String? token = DataPreference.instance.token ?? "";
    try {
      final body = {
        "product_id": product.id,
        "quantity": quantity,
        "price": product.amountToBePaid ?? 0,
        "access_token": token,
        "target_phone_number": targetPhoneNumber ?? "",
      };
      if (product.previewFlashSale?.isFlashSalePrice == true && product.previewFlashSale?.id != null) {
        body["flash_sale_id"] = product.previewFlashSale!.id;
      }
      if ((metaData ?? '').isNotEmpty) {
        body["metadata"] = metaData;
      }
      final response = await client.getPreviewOrderInfo(body);
      previewData.value = response.data;
    } catch (error) {
      print("Error fetching preview order payment: $error");
    }
  }

  Future<void> _getPaymentMethods() async {
    try {
      final response = await client.getPreviewPaymentMethods();
      paymentMethods.value = response.data ?? [];
    } catch (error) {
      print("Error fetching payment methods: $error");
    }
  }

  Future<void> _getPaymentBankAccounts() async {
    try {
      final response = await client.getPreviewOrderBankAccounts();
      paymentBankAccounts.value = response.data ?? [];
    } catch (error) {
      print("Error fetching payment bank accounts: $error");
    }
  }
}
