import 'package:e_commerce_training/res/R.dart';
import 'package:e_commerce_training/src/model/db/dbhelper.dart';
import 'package:e_commerce_training/src/model/repository/app_repository.dart';
import 'package:e_commerce_training/src/model/response/product_detail_response.dart';
import 'package:e_commerce_training/src/model/service/api_result.dart';
import 'package:e_commerce_training/src/model/service/network_exceptions.dart';
import 'package:e_commerce_training/src/page/shopping_cart/shopping_cart_state.dart';
import 'package:e_commerce_training/src/util/logger.dart';
import 'package:e_commerce_training/src/util/util.dart';
import 'package:e_commerce_training/src/util/validator.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class ShoppingCartCubit extends Cubit<ShoppingCartState> with Validators {
  final AppRepository repository;
  List<DetailProductData> listProduct = [];
  DetailProductData? productDetailData;
  int currentIndex = 0;
  int countCart = 0;
  final db = DatabaseHelper();

  ShoppingCartCubit(this.repository) : super(InitialShoppingCartState());

  List<DetailProductData> getList() {
    return listProduct;
  }

  Future<List<DetailProductData>> getListFromDb() {
    return db.fetchAllProduct();
  }

  Future<List<DetailProductData>> getListSelectedFromDb() {
    return db.getAllProductSelected();
  }

  Future<void> updateList() async {
    listProduct = await db.fetchAllProduct();
  }

  DetailProductData getProduct(int i) {
    return listProduct.elementAt(i);
  }

  void deleteItems(int index) {
    listProduct.removeAt(index);
  }

  num? totalValue() {
    double total = 0;
    for (int i = 0; i < listProduct.length; i++) {
      productDetailData = listProduct.elementAt(i);
      if (productDetailData!.rowNumber == 1) {
        if (productDetailData!.price == null) return null;
        total = total + (productDetailData!.price)! * productDetailData!.rowNumber!;
      }
    }
    return total;
  }

  int countProductMark() {
    int count = 0;
    for (int i = 0; i < listProduct.length; i++) {
      productDetailData = listProduct.elementAt(i);
      if (productDetailData!.rowNumber == 1) count++;
    }
    return count;
  }

  void increment(int index) async {
    emit(InitialShoppingCartState());
    currentIndex = index;
    await db.increaseProduct(listProduct.elementAt(currentIndex));
    emit(CheckDbState());
    getProductList(true);
  }

  void decrement(int index) async {
    emit(InitialShoppingCartState());
    currentIndex = index;
    if (listProduct.elementAt(currentIndex).rowNumber! >= 2) {
      await db.decreaseProduct(listProduct.elementAt(currentIndex));
    }
    emit(CheckDbState());
    getProductList(true);
  }

  void delete(int index, int id) async {
    emit(InitialShoppingCartState());
    deleteItems(index);
    db.removeProduct(id);
    listProduct = await getListFromDb();
    emit(GetProductListSuccess());
    getProductList(true);
  }

  void updateQuantityProduct(int index, String quantity) async {
    emit(InitialShoppingCartState());
    currentIndex = index;
    try {
      num rowNumber = num.parse(quantity.replaceAll(".", "."));
      DetailProductData data = listProduct.elementAt(currentIndex);
      if (data.rowNumber == rowNumber) {
        emit(CheckDbState());
      } else {
        //data.rowNumber= rowNumber;
        await db.updateProduct(data);
        emit(CheckDbState());
        getProductList(true);
      }
    } catch (e) {
      logger.e(e.toString());
      emit(ShoppingCartFailure(R.string.cart_empty));
    }
  }

  void getProductList(bool isRefresh) async {
    emit(isRefresh ? InitialShoppingCartState() : ShoppingCartLoading());
    listProduct = await getListFromDb();
    emit(GetProductListSuccess());
  }

  void getListProduct(
    int itemId,
  ) async {
    emit(ShoppingCartLoading());
    ApiResult<DetailProductData> listProductResult = await repository.getProductDetail(itemId);
    listProductResult.when(success: (DetailProductData data) async {
      productDetailData = data;
      emit(GetProductListSuccess());
    }, failure: (NetworkExceptions error) async {
      emit(ShoppingCartFailure(NetworkExceptions.getErrorMessage(error)));
      try {
        DetailProductResponse productDetailResponse =
            DetailProductResponse.fromJson(await Util.parseJson("product.json"));
        productDetailData = productDetailResponse.Data;
        emit(GetProductListSuccess());
      } catch (e) {
        logger.e(e);
      }
    });
  }
}
