import 'package:get/get_rx/src/rx_types/rx_types.dart';
import 'package:mypoint_flutter_app/app/config/constants.dart';
import 'package:mypoint_flutter_app/core/network/api/product_api.dart' deferred as product_api;
import 'package:mypoint_flutter_app/features/mobile_card/models/product_mobile_card_model.dart';
import '../../shared/widgets/base_view/base_response_model.dart';
import '../../core/network/restful_api_viewmodel.dart';
import '../../shared/preferences/point/point_manager.dart';
import 'models/mobile_service_redeem_data.dart';
import 'models/usable_voucher_model.dart';

class ProductMobileCardViewModel extends RestfulApiViewModel {
  void Function(String message)? onShowAlertError;
  void Function(UsableVoucherModel data)? onRedeemProductMobileSuccess;
  final RxMap<String, List<ProductMobileCardModel>> groupedSection = RxMap<String, List<ProductMobileCardModel>>();
  final RxList<ProductMobileCardModel> mobileCardSections = <ProductMobileCardModel>[].obs;
  final RxString selectedBrandCode = "".obs;
  List<ProductMobileCardModel> get products {
    return groupedSection[selectedBrandCode.value] ?? [];
  }
  ProductMobileCardModel? selectedProduct;
  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?.prices?.firstOrNull?.payPoint ?? "0") ?? 0;
  }
  bool get isValidBalance {
    return UserPointManager().point >= (int.tryParse(selectedProduct?.prices?.firstOrNull?.payPoint ?? "0") ?? 0);
  }

  @override
  onInit() {
    super.onInit();
    UserPointManager().fetchUserPoint();
  }

  Future<void> redeemProductMobileCard() async {
    await callApi<MobileServiceRedeemData>(
      request: () => _callProductApi((api) => api.redeemMobileCard((selectedProduct?.id ?? 0).toString())),
      onSuccess: (data, _) async {
        final itemId = data.itemId ?? "";
        if (itemId.isEmpty) {
          onShowAlertError?.call(Constants.commonError);
          return;
        }
        await _getMobileCardCode(itemId);
      },
      onFailure: (msg, _, _) async {
        onShowAlertError?.call(msg);
      },
    );
  }

  Future<void> _getMobileCardCode(String itemId) async {
    await callApi<RedeemProductResponseModel>(
      request: () => _callProductApi((api) => api.getMobileCardCode(itemId)),
      onSuccess: (data, _) {
        final item = data.item;
        if (item != null) {
          onRedeemProductMobileSuccess?.call(item);
        } else {
          onShowAlertError?.call(Constants.commonError);
        }
      },
      onFailure: (msg, _, _) async {
        onShowAlertError?.call(msg);
      },
    );
  }

  Future<void> getProductMobileCard() async {
    await callApi<ProductMobileCardResponse>(
      request: () => _callProductApi((api) => api.productMobileCardGetList()),
      onSuccess: (data, _) {
        final result = data.products ?? [];
        final seen = <String>{};
        final uniqueBrandCode = <ProductMobileCardModel>[];
        for (final p in result) {
          final code = p.brandCode ?? "";
          if (code.isNotEmpty && seen.add(code)) {
            uniqueBrandCode.add(p);
          }
        }
        selectedBrandCode.value = uniqueBrandCode.isNotEmpty ? uniqueBrandCode.first.brandCode ?? "" : "";
        mobileCardSections.assignAll(uniqueBrandCode);

        final Map<String, List<ProductMobileCardModel>> grouped = {};
        for (final product in result) {
          final code = product.brandCode ?? 'unknown';
          grouped.putIfAbsent(code, () => <ProductMobileCardModel>[]).add(product);
        }
        groupedSection.assignAll(grouped);
      },
      onFailure: (msg, _, _) async {
        onShowAlertError?.call(msg);
      },
    );
  }
}
