
import 'package:satu/core/base/base_service.dart';
import 'package:satu/core/entity/category_entity.dart';
import 'package:satu/core/entity/goods_entity.dart';
import 'package:satu/core/models/dictionary/category_response.dart';
import 'package:satu/core/models/dictionary/good_response.dart';
import 'package:satu/core/models/response.dart';
import 'package:satu/core/redux/store.dart';
import 'package:satu/core/utils/locator.dart';

import 'api_service.dart';
import 'db_service.dart';

class DictionaryService extends BaseService {
  final ApiService _api = locator<ApiService>();
  final DbService _db = locator<DbService>();

  Future<void> refreshFull() async {
    _db.deleteAll(categoryTableName);
    await refreshCategory();
    _db.deleteAll(goodTableName);
    await refreshGood();
  }

  Future<void> refreshCategory() async {
    try {
      final int? appCompanyId = Redux.store!.state.userState!.auth!.companyId;
      final Response categories = await _api.dictionaries('/categories');
      if (categories.operation! && categories.list!.isNotEmpty) {
        for (dynamic map in categories.list!) {
          CategoryResponse cat = CategoryResponse.fromMap(map)!;
          Category entity = new Category()
            ..id = cat.id
            ..name = cat.name
            ..updatedAt = cat.updatedAt
            ..parentId = cat.parentId
            ..appCompanyId = appCompanyId;
          _db.insert(categoryTableName, entity.toMap());
        }
      }
    } catch (e, stack) {
      log.e("categories", e, stack);
    }
  }

  Future<List<Category>> getCategoryByParentId(int parentId ) async {
    final List<Category> list = [];
    try {
      final int? appCompanyId = Redux.store?.state.userState?.auth?.companyId;
      final List<Map<String, dynamic>> elements = await _db.queryRowsWithWhere(categoryTableName, '$categoryColumnAppCompanyId = ? and $categoryColumnParentIn = ?', [appCompanyId, parentId]);
      for  (final Map<String, dynamic> element in  elements){
        list.add(Category.fromMap(element));
      }
    } catch (e, stack) {
      log.e("getCategoryByParentId", e, stack);
    }
    return list;
  }

  Future<List<Good>> getGoodsByCategoryId(int categoryId ) async {
    final List<Good> list = [];
    try {
      final int? appCompanyId = Redux.store?.state.userState?.auth?.companyId;
      final List<Map<String, dynamic>> elements = await _db.queryRowsWithWhere(goodTableName, '$GoodColumnAppCompanyId = ? and $GoodColumnCategoryId = ?', [appCompanyId, categoryId]);
      for  (final Map<String, dynamic> element in  elements){
        list.add(Good.fromMap(element));
      }
    } catch (e, stack) {
      log.e("getGoodsByCategoryId", e, stack);
    }
    return list;
  }

  Future<List<Good>> getGoodsByNameOrEan( String query ) async {
    final List<Good> list = [];
    try {
      final int? appCompanyId = Redux.store?.state.userState?.auth?.companyId;
      String where = '( $GoodColumnAppCompanyId = ? and $GoodColumnName like ? ) ';
      final List args = [appCompanyId, '%$query%'];
      if(_isNumericInt(query)){
        where += ' or $GoodColumnEan like ?';
        args.add('${int.parse(query).toString()}%');
      }
      final List<Map<String, dynamic>> elements = await _db.queryRowsWithWhere(goodTableName, where, args);
      for  (final Map<String, dynamic> element in  elements){
        list.add(Good.fromMap(element));
      }
    } catch (e, stack) {
      log.e("getGoodsByCategoryId", e, stack);
    }
    return list;
  }

  Future<List<Good>> getGoodsByEan( String code ) async {
    final List<Good> list = [];
    try {
      final int? appCompanyId = Redux.store?.state.userState?.auth?.companyId;
      final String where = '( $GoodColumnAppCompanyId = ? and $GoodColumnEan like ? ) ';
      final List args = [appCompanyId, '%$code%'];
      final List<Map<String, dynamic>>
      elements = await _db.queryRowsWithWhere(goodTableName, where, args);
      for  (final Map<String, dynamic> element in  elements){
        list.add(Good.fromMap(element));
      }
    } catch (e, stack) {
      log.e("getGoodsByEan", e, stack);
    }
    return list;
  }

  bool _isNumericInt(String str) {
    if(str == null) {
      return false;
    }
    return int.tryParse(str) != null;
  }

  Future<void> refreshGood() async {
    try {
      int? appCompanyId = Redux.store!.state.userState!.auth!.companyId;
      Response categories = await _api.dictionaries('/goods');
      if (categories.operation! && categories.list!.isNotEmpty) {
        for (final dynamic map in categories.list!) {
          final GoodResponse good = GoodResponse.fromMap(map);
          final Good entity = new Good()
            ..id = good.id
            ..name = good.name
            ..categoryId = good.categoryId
          ..ean = good.ean
          ..articul = good.articul
          ..price = good.price
          ..optPrice = good.optPrice
          ..basePrice = good.basePrice
          ..divisible = good.divisible
          ..updatedAt = good.updatedAt
          ..appCompanyId = appCompanyId;
          _db.insert(goodTableName, entity.toMap());
        }
      }
    } catch (e, stack) {
      log.e("goods", e, stack);
    }
  }
}
