import 'dart:async';
import 'package:get/get.dart';
import 'package:mypoint_flutter_app/core/network/restful_api_client_all_request.dart';
import 'package:mypoint_flutter_app/core/network/restful_api_viewmodel.dart';
import 'package:mypoint_flutter_app/features/flash_sale/models/flash_sale_category_model.dart';
import 'package:mypoint_flutter_app/features/flash_sale/models/flash_sale_detail_response.dart';
import 'package:mypoint_flutter_app/features/voucher/models/product_model.dart';

class FlashSaleViewModel extends RestfulApiViewModel {
  final String groupId;
  FlashSaleViewModel({required this.groupId});

  static const FlashSaleCategoryModel allCategory = FlashSaleCategoryModel(id: -1, name: 'Tất cả');

  final RxList<FlashSaleCategoryModel> categories = <FlashSaleCategoryModel>[].obs;
  final RxnInt selectedCategoryId = RxnInt();
  final RxList<ProductModel> products = <ProductModel>[].obs;
  final Rx<FlashSaleDetailResponse?> flashSale = Rx<FlashSaleDetailResponse?>(null);
  final RxBool hasMore = true.obs;
  final Rx<Duration> remaining = const Duration().obs;
  void Function(String message)? onShowAlertError;

  Timer? _timer;
  int _offset = 0;
  final int _pageSize = 20;

  @override
  void onInit() {
    super.onInit();
    _loadInitialData();
  }

  Future<void> _loadInitialData({bool withLoading = true}) async {
    if (withLoading) showLoading();
    await fetchCategories();
    await loadProducts(reset: true);
    if (withLoading) hideLoading();
  }

  Future<void> fetchCategories() async {
    await callApi<List<FlashSaleCategoryModel>>(
      withLoading: false,
      request: () => client.getFlashSaleCategories(groupId),
      onSuccess: (data, _) {
        final extended = <FlashSaleCategoryModel>[allCategory, ...data];
        categories.assignAll(extended);
        selectedCategoryId.value ??= allCategory.id;
      },
      onFailure: (_, _, _) {
        if (categories.isEmpty) {
          categories.assignAll(const [allCategory]);
          selectedCategoryId.value = allCategory.id;
        }
      },
    );
  }

  Future<void> loadProducts({bool reset = false}) async {
    if (reset) {
      _offset = 0;
      hasMore.value = true;
    } else {
      _offset = products.length;
    }
    final categoryId = selectedCategoryId.value;
    final int? categoryParam = (categoryId != null && categoryId != allCategory.id) ? categoryId : null;
    await callApi<FlashSaleDetailResponse>(
      withLoading: false,
      request:
          () => client.getFlashSaleDetail(groupId: groupId, index: _offset, size: _pageSize, categoryId: categoryParam),
      onSuccess: (data, _) {
        final fetched = data.products ?? <ProductModel>[];
        if (reset) {
          products.assignAll(fetched);
        } else {
          products.addAll(fetched);
        }
        hasMore.value = fetched.length >= _pageSize;
        flashSale.value = data;
        _restartTimer();
      },
      onFailure: (message, _, _) {
        if (reset) {
          products.clear();
        }
        hasMore.value = false;
        onShowAlertError?.call(message);
      },
    );
  }

  Future<void> refresh() async {
    await loadProducts(reset: true);
  }

  void onCategorySelected(FlashSaleCategoryModel category) {
    if (selectedCategoryId.value == category.id) return;
    selectedCategoryId.value = category.id;
    loadProducts(reset: true);
  }

  void loadMore() {
    if (!hasMore.value) return;
    loadProducts(reset: false);
  }

  void _restartTimer() {
    final info = products.firstOrNull?.previewFlashSale;
    _timer?.cancel();
    final target = info;
    final int seconds = target?.countdownLocal?.inSeconds ?? target?.countdownSecond ?? 0;
    if (seconds <= 0) {
      remaining.value = Duration.zero;
      return;
    }
    remaining.value = Duration(seconds: seconds);
    _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      final current = remaining.value;
      if (current.inSeconds <= 1) {
        remaining.value = Duration.zero;
        timer.cancel();
        _loadInitialData(withLoading: false);
        return;
      }
      remaining.value = Duration(seconds: current.inSeconds - 1);
    });
  }

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