import 'package:aman_kassa_flutter/core/entity/Category.dart';
import 'package:aman_kassa_flutter/core/entity/Goods.dart';
import 'package:aman_kassa_flutter/core/entity/Service.dart';
import 'package:aman_kassa_flutter/core/locator.dart';
import 'package:aman_kassa_flutter/core/models/dict_dao.dart';
import 'package:aman_kassa_flutter/core/models/product_dao.dart';
import 'package:aman_kassa_flutter/core/services/DataService.dart';
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
import 'package:meta/meta.dart';
import 'package:redux/redux.dart';
import 'package:redux_thunk/redux_thunk.dart';

import '../store.dart';

@immutable
class SetKassaStateAction {
  final KassaState kassaState;
  SetKassaStateAction(this.kassaState);
}

final DataService _dataService = locator<DataService>();
final DialogService _dialogService = locator<DialogService>();

Future<void> backBottomElement(Store<AppState> store) async {
  List<DictDao>? prevCategories = store.state.kassaState!.prevCategories;
  DictDao? last = prevCategories?.removeLast() ;
  if (last != null) {
    store.dispatch(SetKassaStateAction(KassaState(prevCategories: prevCategories)));
    store.dispatch(selectBottomElement(last.id));
  }
}

Future<void> cleanKassaItems(Store<AppState> store) async {
  store.dispatch(SetKassaStateAction(KassaState(kassaItems: [])));
}

ThunkAction<AppState> addCustomProductToKassaItems(String name, double count, double price, double total, {String? ntin}) {
  return (Store<AppState> store) async {
    List<ProductDao> items = store.state.kassaState!.kassaItems!;
    items.add(new ProductDao(name: name, count: count, price: price, total: total, ntin: ntin));
    store.dispatch(SetKassaStateAction(KassaState(kassaItems: items)));
  };
}


ThunkAction<AppState> addProductToKassaItems(Good good, String? excise) {
  return (Store<AppState> store) async {
    List<ProductDao> items = store.state.kassaState!.kassaItems!;
    int index = items.indexWhere((element) => element.excise == null && element.good?.id == good.id);
    if(excise !=null) {
      int existIndex = items.indexWhere((element) => element.excise != null && element.excise == excise);
      if(existIndex > -1) {
        _dialogService.showDialog(description: 'Нельзя добавить повторно одинаковые товары');
        return;
      }
    }
    if (index > -1 && excise == null) {
      store.dispatch(counterProductFromKassaItems(index, 1));
    } else {
      items.add(new ProductDao(
          name: good.name, good: good, count: 1, price: good.price, total: good.price, excise: excise));
      store.dispatch(SetKassaStateAction(KassaState(kassaItems: items)));
    }
  };
}

ThunkAction<AppState> addServiceToKassaItems(Service service) {
  return (Store<AppState> store) async {
    List<ProductDao> items = store.state.kassaState!.kassaItems!;
    int index = items.indexWhere((element) => element.good?.id == service.id);
    if (index > -1) {
      store.dispatch(counterProductFromKassaItems(index, 1));
    } else {
      items.add(new ProductDao(
          name: service.name, service: service, count: 1, price: service.price, total: service.price));
      store.dispatch(SetKassaStateAction(KassaState(kassaItems: items)));
    }
  };
}

ThunkAction<AppState> removeProductFromKassaItems(int index) {
  return (Store<AppState> store) async {
    List<ProductDao> items = List.from(store.state.kassaState!.kassaItems!);
    items.removeAt(index);
    store.dispatch(SetKassaStateAction(KassaState(kassaItems: items)));
  };
}

ThunkAction<AppState> counterProductFromKassaItems(int index, int counter) {
  return (Store<AppState> store) async {
    List<ProductDao> items = store.state.kassaState!.kassaItems!;
    ProductDao product = items.elementAt(index);
    if (product.count == 1 && counter < 0) {
      //if count to zero need delete element
      store.dispatch(removeProductFromKassaItems(index));
    } else {
      product.count += counter;
      product.total = (((product.count * product.price) * 100).roundToDouble()) / 100;
      store.dispatch(SetKassaStateAction(KassaState(kassaItems: items)));
    }
  };
}

ThunkAction<AppState> selectBottomElement(int parentId) {
  return (Store<AppState> store) async {
    store.dispatch(SetKassaStateAction(KassaState(bottomSheetLoading: true, bottomSheetElements: [])));
    try {
      List<DictDao> prevCategories = store.state.kassaState!.prevCategories!;
      if (parentId == 0) {
        prevCategories = [];
      }
      store.state.kassaState!.bottomSheetElements!.forEach((element) {
        if (element is Category && element.id == parentId) {
          prevCategories.add(DictDao(id: element.parentIn!, name: element.name));
        }
      });
      List _bottomSheetElements = [];


      if(store.state.settingState!.tradeType == SettingTradeTypeGood) {
        List<Category> categories = await _dataService.getCategoriesByParentId(parentId: parentId);
        _bottomSheetElements.addAll(categories);
        List<Good> goods = await _dataService.getGoodsByCategoryId(categoryId: parentId);
        _bottomSheetElements.addAll(goods);
      } else if(store.state.settingState!.tradeType == SettingTradeTypeService) {
        List<Service> services = await _dataService.getServices();
        _bottomSheetElements.addAll(services);
      }

      store.dispatch(SetKassaStateAction(KassaState(
          bottomSheetLoading: false,
          bottomSheetElements: _bottomSheetElements,
          prevCategories: prevCategories)));
    } catch (e) {
      print(e);
      store.dispatch(SetKassaStateAction(KassaState(bottomSheetLoading: false)));
    }
  };
}