import 'dart:async';
import 'package:get/get.dart';
import 'package:mypoint_flutter_app/core/network/api/product_api.dart' deferred as product_api;
import 'package:mypoint_flutter_app/core/network/restful_api_client_all_request.dart';
import '../../../shared/widgets/base_view/base_response_model.dart';
import '../../../core/network/restful_api_viewmodel.dart';
import '../models/product_model.dart';
import '../models/product_type.dart';
import '../models/search_product_response_model.dart';

class VoucherListViewModel extends RestfulApiViewModel {
  VoucherListViewModel({required this.isHotProduct, this.isFavorite = false});
  final bool isFavorite;
  final bool isHotProduct;
  Timer? _debounce;
  final RxList<ProductModel> products = <ProductModel>[].obs;
  int _currentPage = 0;
  final int _pageSize = 20;
  @override
  final RxBool isLoading = false.obs;
  bool _hasMore = true;
  bool get hasMore => _hasMore;
  String _searchQuery = '';
  String get searchQuery => _searchQuery;
  var totalResult = 0.obs;
  final firstLoadDone = false.obs;
  void Function(BaseResponseModel<SubmitViewVoucherCompletedResponse> response)? submitCampaignViewVoucherResponse;
  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();
    loadData(reset: true);
  }

  @override
  void onClose() {
    _debounce?.cancel();
    super.onClose();
  }

  void onSearchChanged(String value) {
    if (_searchQuery == value) return;
    _searchQuery = value;
    _debounce?.cancel();
    _debounce = Timer(const Duration(seconds: 1), () {
      loadData(reset: true);
    });
  }

  Future<void> loadData({bool reset = false}) async {
    if (isFavorite) {
      await _getFavoriteProducts(reset: reset);
    } else {
      await _getProducts(reset: reset);
    }
  }

  Future<void> _getFavoriteProducts({bool reset = false}) async {
    if (isLoading.value) return;
    if (reset) {
      _currentPage = 0;
      _hasMore = true;
      products.clear();
    } else {
      _currentPage = products.length;
      if (!_hasMore) return;
    }
    isLoading.value = true;
    final body = {"size": _pageSize, "index": _currentPage};
    await callApi<List<ProductModel>>(
      request: () => _callProductApi((api) => api.productsCustomerLikes(body)),
      onSuccess: (data, _) {
        if (data.isEmpty || data.length < _pageSize) {
          _hasMore = false;
        }
        products.addAll(data);
      },
      onFailure: (message, _, _) {
        _hasMore = false;
        // onShowAlertError?.call(message);
      },
      onComplete: () {
        isLoading.value = false;
        if (products.isNotEmpty) firstLoadDone.value = true;
      },
      withLoading: reset,
    );
  }

  Future<void> _getProducts({bool reset = false}) async {
    if (isLoading.value) return;
    if (reset) {
      _currentPage = 0;
      _hasMore = true;
      products.clear();
    } else {
      _currentPage = products.length;
    }
    if (!_hasMore) return;
    final body = {
      "type": ProductType.voucher.value,
      "size": _pageSize,
      "index": _currentPage,
      if (isHotProduct) "catalog_code": "HOT",
      if (_searchQuery.isNotEmpty) "keywords": _searchQuery,
      if (_searchQuery.isNotEmpty) "keyword": _searchQuery,
    };
    isLoading.value = true;
    await callApi<SearchProductResponseModel>(
      request: () => _callProductApi((api) => api.getSearchProducts(body)),
      onSuccess: (data, _) {
        final fetchedData = data.products ?? [];
        totalResult.value = data.total ?? 0;
        if (fetchedData.isEmpty || fetchedData.length < _pageSize) {
          _hasMore = false;
        }
        products.addAll(fetchedData);
      },
      onFailure: (message, _, _) {
        _hasMore = false;
        // onShowAlertError?.call(message);
      },
      onComplete: () {
        isLoading.value = false;
        if (products.isNotEmpty) firstLoadDone.value = true;
      },
      withLoading: reset,
    );
  }

  void submitCampaignViewVoucherComplete() async {
    showLoading();
    final response = await client.submitCampaignViewVoucherComplete();
    hideLoading();
    submitCampaignViewVoucherResponse?.call(response);
  }
}
