import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../../../app.dart';
import 'state.dart';

class FilterController extends GetxController {
  final Map<String, dynamic> params;

  FilterController(this.params);

  final state = FilterState();

  @override
  void onInit() {
    _initFunctions();

    super.onInit();
  }

  void _initFunctions() {
    debugPrint('FilterController _initFunctions $params');

    state.filterableQueryParams.value = params;
    update();

    getSortMethods();
    getFilters();
    getPriceFilters();
  }

  Future<void> getSortMethods() async {
    state.isSortLoading.value = true;

    final result = await FilterApi.getSortMethods();
    state.sortModels.addAll(result);

    state.isSortLoading.value = false;
  }

  Future<void> getFilters() async {
    debugPrint('getFilters');

    state.filterModels.clear();
    state.isFiltersLoading.value = true;
    state.hasError.value = false;

    final categoryId = state.filterableQueryParams['category_id'];

    final result = await FilterApi.getFilters(categoryId == null ? 1 : categoryId);

    if (result == null) {
      state.hasError.value = true;
      state.isFiltersLoading.value = false;
      return;
    }

    state.filterModels.addAll(result);

    calculateTotalAppliedFilter();

    state.isFiltersLoading.value = false;
  }

  Future<void> getPriceFilters() async {
    state.isPriceLoading.value = true;

    final result = await FilterApi.getPriceFilters();
    state.priceModels.addAll(result);

    state.isPriceLoading.value = false;
  }

  void onPriceMethodChange(PriceFilterModel model, BuildContext context) {
    debugPrint('onPriceMethodChange ${model.id}');
    state.isFiltersLoading.value = true;
    state.isPriceLoading.value = !state.isPriceLoading.value;

    // if model is selected, then deselect it
    if (state.selectedPriceFilterModelId == model.id) {
      state.selectedPriceFilterModelId.value = 0;
      state.selectedPriceFilter.value = null;
      // state.startPrice.text = '';
      // state.endPrice.text = '';

      if (state.filterableQueryParams.isNotEmpty) {
        state.filterableQueryParams.removeWhere((key, value) => key == 'price');
      }

      debugPrint('state.filterableQueryParams ${state.filterableQueryParams}');
    } else {
      state.selectedPriceFilterModelId.value = model.id;
      state.selectedPriceFilter.value = model;
      // state.startPrice.text = model.start.toString();
      // state.endPrice.text = model.end.toString();

      // add price to filterableQueryParams
      if (state.selectedPriceFilter.value != null) {
        state.filterableQueryParams.addAll(
          {
            'price': state.selectedPriceFilter.value!.queryValue,
          },
        );
      }
    }
    state.isFiltersLoading.value = false;

    Get.back();
  }

  void onFilterPageClosed() {
    debugPrint('onFilterPageClosed');
    ProductListController plc = Get.put(ProductListController());
    plc.reset();
    plc.fetchProducts();
    Get.back();
  }

  void navigateToFilterScreen() {
    debugPrint('navigateToFilterScreen');
    Get.toNamed(AppRoutes.FILTER_PAGE);
    // getFilters();
  }

  void calculateTotalAppliedFilter() {
    state.totalAppliedFilter.value = state.filterModels.where((fm) => fm.selectedOptions.isNotEmpty).toList().length;
  }

  void onSortMethodChange(SortModel sortModel, BuildContext context) {
    debugPrint('onSortMethodChange ${sortModel.id}');
    state.selectedSortModelId = sortModel.id;

    update();

    Get.back();

    state.filterableQueryParams.addAll(sortModel.queryParameters);

    ProductListController plc = Get.put(ProductListController());
    plc.reset();
    plc.fetchProducts();
  }

  void onMultipleSelectionConfirmed(FilterModel model, List<dynamic> selectedOptions) {
    state.isFiltersLoading.value = true;

    String params = '';

    for (final FilterOption option in selectedOptions) {
      params += option.id.toString() + ',';
    }

    params = removeLastChar(params);

    state.filterableQueryParams.addAll({
      model.code: params,
    });

    model.selectedOptions = [...selectedOptions];
    state.filterModels[state.filterModels.indexWhere((fm) => fm.id == model.id)] = model;

    calculateTotalAppliedFilter();

    state.isFiltersLoading.value = false;
  }

  void onMultipleSelectionCleared(FilterModel model) {
    state.isFiltersLoading.value = true;

    state.filterableQueryParams.removeWhere((String key, dynamic value) => key == model.code);

    model.selectedOptions.clear();
    state.filterModels[state.filterModels.indexWhere((fm) => fm.id == model.id)] = model;

    calculateTotalAppliedFilter();

    state.isFiltersLoading.value = false;
  }

  void clearAllFilters() {
    debugPrint('clearAllFilters');

    // clear price filters
    state.selectedPriceFilterModelId.value = 0;
    state.selectedPriceFilter.value = null;

    for (int i = 0; i < state.filterModels.length; i++) {
      state.filterModels[i].selectedOptions.clear();
    }

    state.filterModels.refresh();

    final categoryId = state.filterableQueryParams['category_id'];
    state.filterableQueryParams.clear();
    state.filterableQueryParams['category_id'] = categoryId;

    debugPrint('debugPoint');

    calculateTotalAppliedFilter();
  }
}
