import 'package:get/get.dart';
import 'package:mypoint_flutter_app/core/utils/extensions/string_extension.dart';
import 'package:mypoint_flutter_app/core/network/api/product_api.dart' deferred as product_api;
import 'package:uuid/uuid.dart';
import '../../../shared/widgets/base_view/base_response_model.dart';
import '../../../core/network/restful_api_viewmodel.dart';
import '../../../app/config/constants.dart';
import '../../../shared/router_gage.dart';
import '../../transaction/model/order_product_payment_response_model.dart';
import '../models/product_model.dart';
import '../models/product_store_model.dart';

class VoucherDetailViewModel extends RestfulApiViewModel {
  final int? productId;
  final int? customerProductId;
  VoucherDetailViewModel({
    this.productId,
    this.customerProductId,
  });

  var stores = RxList<ProductStoreModel>();
  var product = Rxn<ProductModel>();
  var liked = false.obs;
  void Function(String message)? onShowAlertError;
  var quantity = 1.obs;
  bool get isMyProduct => customerProductId != null;
  int? get _id => productId ?? product.value?.id;
  bool _productApiLoaded = false;

  Future<void> _ensureProductApiLoaded() async {
    if (_productApiLoaded) return;
    await product_api.loadLibrary();
    _productApiLoaded = true;
  }

  Future<BaseResponseModel<T>> _callProductApi<T>(Future<BaseResponseModel<T>> Function(dynamic api) fn) async {
    await _ensureProductApiLoaded();
    final api = product_api.ProductApi(client);
    return fn(api);
  }

  @override
  void onInit() {
    super.onInit();
    _getProductDetail();
    _getProductStores();
  }

  Future<void> toggleFavorite() async {
    if (_id == null) return;
    final value = product.value;
    if (value == null) return;
    try {
      if (value.liked == true) {
        await _callProductApi((api) => api.unlikeProduct(value.likeId ?? 0));
        value.likeId = 0;
        liked.value = false;
      } else {
        final response = await _callProductApi((api) => api.likeProduct(_id!));
        value.likeId = response.data?.id;
        liked.value = (response.data?.id ?? 0) != 0;
      }
    } catch (error) {
      onShowAlertError?.call(Constants.commonError);
    }
  }

  Future<void> _getProductDetail() async {
    await callApi<ProductModel>(
      request: () =>
      isMyProduct ?
      _callProductApi((api) => api.getCustomerProductDetail(customerProductId ?? 0)) :
      _callProductApi((api) => api.getProduct(productId ?? 0)),
      onSuccess: (data, _) {
        product.value = data;
        liked.value = product.value?.liked == true;
      },
      onFailure: (message, _, _) {
        onShowAlertError?.call(message);
      },
    );
  }

  Future<void> _getProductStores() async {
    if (_id == null) return;
    await callApi<List<ProductStoreModel>>(
      request: () => _callProductApi((api) => api.getProductStores(_id!)),
      onSuccess: (data, _) {
        stores.value = data;
      },
      onFailure: (message, _, _) {
        onShowAlertError?.call(message);
      },
      withLoading: false,
    );
  }

  Future<void> verifyOrderProduct(Function verified) async {
    final value = product.value;
    var body = {"product_id": productId, "price": value?.amountToBePaid, "quantity": quantity.value};
    if (value?.previewFlashSale?.isFlashSalePrice == true) {
      final flashSaleId = value?.previewFlashSale?.id;
      if (flashSaleId != null) {
        body["flash_sale_id"] = flashSaleId;
      }
    }
    showLoading();
    try {
      final response = await _callProductApi((api) => api.verifyOrderProduct(body));
      if (!response.isSuccess) {
        onShowAlertError?.call(response.errorMessage ?? Constants.commonError);
      } else {
        verified.call();
      }
    } catch (error) {
      onShowAlertError?.call(Constants.commonError);
    } finally {
      hideLoading();
    }
  }

  Future<void> redeemProduct() async {
    final requestId = Uuid().v4();
    await callApi<OrderProductPaymentResponseModel>(
      request: () =>
          _callProductApi(
                (api) =>
                api.orderSubmitPayment(
                  products: [product.value!],
                  quantity: 1,
                  requestId: requestId,
                  point: product.value?.amountToBePaid ?? 0,
                ),
          ),
      onSuccess: (data, _) {
        final id = data.id.orEmpty;
        if (id.isNotEmpty) {
          Get.offNamed(
            transactionHistoryDetailScreen,
            arguments: {"orderId": id, "canBack": false},
          );
        } else {
          onShowAlertError?.call(Constants.commonError);
        }
      },
      onFailure: (message, _, _) {
        onShowAlertError?.call(message);
      },
    );
  }
}
