import 'package:get/get.dart';
import 'package:get/get_rx/src/rx_types/rx_types.dart';
import 'package:mypoint_flutter_app/core/network/api/product_api.dart' deferred as product_api;
import 'package:mypoint_flutter_app/shared/preferences/data_preference.dart';
import 'package:mypoint_flutter_app/features/data_network_service/product_network_data_model.dart';
import 'package:mypoint_flutter_app/shared/widgets/custom_toast_message.dart';
import '../../shared/widgets/base_view/base_response_model.dart';
import '../../core/network/restful_api_viewmodel.dart';
import '../../app/config/constants.dart';
import '../../core/services/contact_storage_service.dart';
import '../../shared/preferences/point/point_manager.dart';
import '../topup/models/brand_network_model.dart';
import '../voucher/models/product_brand_model.dart';

class DataNetworkServiceViewModel extends RestfulApiViewModel {
  final RxList<String> histories = <String>[].obs;
  final RxList<ProductBrandModel> topUpBrands = <ProductBrandModel>[].obs;
  final RxList<TopUpNetworkDataModel> topUpNetworkData = <TopUpNetworkDataModel>[].obs;
  final Map<String, List<TopUpNetworkDataModel>> _allValue = {};

  final Rxn<ProductBrandModel> selectedBrand = Rxn<ProductBrandModel>();
  final Rxn<ProductNetworkDataModel> selectedProduct = Rxn<ProductNetworkDataModel>();
  final RxString phoneNumber = ''.obs;
  void Function(String message)? onShowAlertError;
  void Function(String message)? onShowAlertRedeemSuccess;
  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);
  }

  int get payPoint {
    return (int.tryParse(selectedProduct.value?.prices?.firstOrNull?.payPoint ?? "0") ?? 0);
  }
  bool get isValidBalance {
    return UserPointManager().point >= payPoint;
  }

  @override
  void onInit() {
    super.onInit();
    final myPhone = DataPreference.instance.phone ?? '';
    phoneNumber.value = myPhone;
    ContactStorageService().getUsedContacts().then((value) {
      if (value.isNotEmpty) {
        histories.assignAll(value);
      } else {
        histories.assignAll([myPhone]);
      }
    });
    if (!histories.contains(myPhone)) {
      histories.insert(0, myPhone);
      ContactStorageService().saveUsedContact(myPhone);
    }
  }

  Future<void> firstLoadNetworkData() async {
    await _getNetworkBrands();
  }

  Future<void> _getNetworkBrands() async {
    await callApi<List<ProductBrandModel>>(
      request: () => _callProductApi((api) => api.productTopUpBrands()),
      onSuccess: (data, _) {
        topUpBrands.assignAll(data);
        checkMobileNetwork();
      },
      onFailure: (mgs, _, _) async {
        topUpBrands.clear();
        onShowAlertError?.call(mgs);
      },
    );
  }

  Future<void> checkMobileNetwork() async {
    await callApi<BrandNameCheckResponse>(
      request: () => _callProductApi((api) => api.checkMobileNetwork(phoneNumber.value)),
      onSuccess: (data, _) {
        final brandCode = data.brand ?? '';
        var brand = topUpBrands.isNotEmpty
            ? topUpBrands.firstWhere(
                (b) => b.code == brandCode,
                orElse: () => topUpBrands.first,
              )
            : topUpBrands.firstOrNull;
        selectedBrand.value = brand;
        getTelcoDetail();
      },
      onFailure: (_, _, _) async {
        final first = topUpBrands.firstOrNull;
        if (first != null) selectedBrand.value = first;
        getTelcoDetail();
      },
    );
  }

  Future<void> getTelcoDetail({String? selected}) async {
    final id = selectedBrand.value?.id;
    final code = selectedBrand.value?.code;
    if (id == null && code == null) return;

    void makeSelected(List<TopUpNetworkDataModel> data) {
      bool didSelect = false;
      final list = data.expand((e) => e.products ?? []).toList();
      if (selected != null && selected.isNotEmpty) {
        for (var item in list) {
          final isMatch = item.id == int.tryParse(selected);
          if (isMatch) {
            selectedProduct.value = item;
            didSelect = true;
          }
        }
      }
      if (!didSelect && selectedProduct.value == null) {
        selectedProduct.value = list.firstOrNull;
      }
    }
    // Dùng cache nếu có
    if (_allValue.containsKey(code)) {
      final cached = _allValue[code]!;
      topUpNetworkData.assignAll(cached);
      makeSelected(cached);
      return;
    }
    await callApi<List<TopUpNetworkDataModel>>(
      request: () => _callProductApi((api) => api.getNetworkProducts((id ?? 0).toString())),
      onSuccess: (data, _) {
        final filtered = (data)
            .where((e) => e.products?.isNotEmpty == true)
            .toList();
        _allValue[code ?? ""] = filtered;
        topUpNetworkData.assignAll(filtered);
        makeSelected(filtered);
      },
      onFailure: (_, _, _) async {},
    );
  }

  Future<void> redeemProductMobileCard() async {
    final id = selectedProduct.value?.id;
    if (id == null) {
      showToastMessage('Vui lòng chọn sản phẩm');
      return;
    }
    await callApi<EmptyCodable>(
      request: () => _callProductApi((api) => api.redeemProductTopUps(id, phoneNumber.value)),
      onSuccess: (data, _) {
        onShowAlertRedeemSuccess?.call("Chúc mừng bạn đã đổi Ưu đãi data thành công");
      },
      onFailure: (msg, _, _) async {
        onShowAlertError?.call(msg.isNotEmpty ? msg : Constants.commonError);
      },
    );
  }
}
