import 'dart:convert';
import 'package:echo_app/auth/auth-request.dart';
import 'package:echo_app/enums/global-errors.dart';
import 'package:echo_app/global/global.dart';
import 'package:echo_app/models/customer-app-settings-model.dart';
import 'package:echo_app/models/language.dart';
import 'package:echo_app/models/user.dart';
import 'package:echo_app/screens/tap_page/tap.page.dart';
import 'package:echo_app/services/items.service.dart';
import 'package:echo_app/services/login.service.dart';
import 'package:echo_app/services/notification.service.dart';
import 'package:echo_app/services/offers.service.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:geocoding/geocoding.dart';
import 'package:geolocator/geolocator.dart';
import 'package:get/get.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import '../models/constant-storage.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

class CoreSession {
  static FirebaseMessaging messaging = FirebaseMessaging.instance;
  static NotificationsService _notificationService = new NotificationsService();
  static String c = '';
  static String deviceToken = "";
  static bool isRTL = false;
  static int selectedLanguageId = 1;
  static var ordersBasket = [];
  static String usedPoints = "";
  static double pointValue = 0.0;

  //-- PayTabsConfigRafa-Water ----------------//
  static var PayTabsConfig = {
    "profileId": "108893",
    "serverKey": "SDJNH99WGB-JHT6KN9B2W-JZLWDNRNKZ",
    "clientKey": "CMKM9T-M7P26H-7GKQP2-PN2HGK",
    "BillingCountry":"SA"
  };
  static String LahzaConfigKey = "sk_test_6pYzpaWLjjGG4UwWMBPXEamgBMQTV6giH";


  // ignore: non_constant_identifier_names
  static var Dashboards = [];
  static var currentBasket;
  static var favBasket = [];
  static var customerAppProperties;
  static var operatorList = [];
  static int pageSize = 25;
  static String baseCurrencyCode = '';
  static int numberOfDigits = 2;
  static int numberOfStockDigits = 2;
  static int zeroString = 0;
  static var divisionList = [];
  static var brandList = [];
  static var categoryList = [];
  static var masterGroupes = [];
  static var homePageData = [];

  static var signUpFields = [];
  static var countries = [];
  static var states = [];
  static var cities = [];
  static var areas = [];
  static var streets = [];
  static List<Language> languages = [];
  static int locationHierarchyLevel = -1;

  // ignore: non_constant_identifier_names
  static String Desc_Geographical_Location_Name_One = '';

  // ignore: non_constant_identifier_names
  static String Desc_Geographical_Location_Name_Two = '';

  // ignore: non_constant_identifier_names
  static String Desc_Geographical_Location_Name_Three = '';

  // ignore: non_constant_identifier_names
  static String Desc_Geographical_Location_Name_Four = '';

  // ignore: non_constant_identifier_names
  static String Desc_Geographical_Location_Name_Five = '';
  static bool hasGestUserBefore = false;
  static bool dataFilled = false;
  static String imagePath = '';
  static var bannersList = [];
  static String api = '';
  static String SiteName='';
  static var homeSlider = {};
  static var homePageTop = {};
  static int newNotificationCount = 0;
  static String rootPath = '';
  static bool showLogoInStartup = false;
  static bool showCategoriesInHomePage = false;
  static bool showCategoryInItemScreen = false;
  static String backgroundColorByHexString = '';
  static String currentAppVersion = '3.0.6';
  static int selectedItemBrandId = -1;
  static int selectedItemCategoryId = -1;
  static String selectedItemSearchText = '';
  static bool cartShowBackbtn = false;
  static bool guessUser = false;
  static bool hideBackgroundForStartup = false;
  static bool hideReorderButton = false;
  static Locale locale = Locale('en', 'US');
  static RangeValues currentRange = RangeValues(0, 5000);
  // ignore: avoid_init_to_null
  static var currentOperator = null;
  static String notificationVideoPath = '';
  static String notificationImagePath = '';

  // static UserModel signUpUser = new UserModel();
  static UserModel signUpUser = new UserModel();
  static bool hasDeffirentPricesFromGestUser = false;
  static var customerAppGestUserOperators = [];
  static var customerAppGuestUserCaption = [];
  static var customerAppSettings = [];
  static var organizationList = [];
  static var allorganizationList = [];

  static Future init() async {
    showCategoryInItemScreen = true;

    showLogoInStartup = true;
    showCategoriesInHomePage = true;
    hideReorderButton = true;
    backgroundColorByHexString = '#29438e';

    imagePath = api + 'img/echo/';

    // this.newNotificationCount = 0;
    // Echo
    api = 'http://20.203.101.85:5045/'; //Incube test
    // api = 'http://172.16.0.156:7500/'; //Incube Hatem
    SiteName = 'ECHO';






    //---------------------------------------------------



    imagePath = api + 'img/echo/';
    notificationVideoPath = api + 'notifications/videos/';
    notificationImagePath = api + 'notifications/images/';
    rootPath = 'assets/imgs/default/';
    showLogoInStartup = true;
    showCategoriesInHomePage = true;
    backgroundColorByHexString = '#222428';
  }

  static getDeviceToken() async {
    messaging.getToken().then(
          (token) => {
            print('Hello Login Token Is : '),
            print(token),
            CoreSession.deviceToken = token!,
            updateDeviceToken(token)
          },
        );
  }

  static updateDeviceToken(token) async {
    var response = await _notificationService.updateDeviceToken(token);
    if (response['status'] == GlobalErrors.Success.index) {
      // EasyLoading.showSuccess('saved-successfully'.tr);
    } else {
      // EasyLoading.showError('error'.tr);
    }
  }

  //#region [GENERAL FUNCTIONS]
  static setLanguage() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    if (prefs.getInt('languageId') == null) {
      CoreSession.selectedLanguageId = 1;
    } else {
      CoreSession.selectedLanguageId = prefs.getInt('languageId')!;
    }
    if (CoreSession.selectedLanguageId == 2) {
      prefs.setInt('languageId', 2);
      locale = Locale('ar', 'AE');
    } else {
      prefs.setInt('languageId', 1);
      locale = Locale('en', 'US');
    }
  }

  static Future<void> fillCustomerLoggdedInData(
      response, username, password, organizationId) async {
    currentOperator = response['data']['operatorModel'];
    operatorList = [];
    operatorList.add(response['data']['operatorModel']['operatorCustomers']);

    // ignore: unused_local_variable
    var itemOffers = response['data']['operatorModel']['itemOffers'];
    var key = response['data']['key'];

    // CASH DATA IN STORAGE
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setString(ConstantStorage.username, username);
    prefs.remove(ConstantStorage.tokenName);
    prefs.setString(ConstantStorage.tokenName, key);
    prefs.setString(ConstantStorage.password, password);
    //prefs.setInt(ConstantStorage.organizationId, organizationId);
    prefs.setString(
        ConstantStorage.currentOperator, json.encode(currentOperator));

    bannersList = response['data']["bannersImages"];

    var list = [];
    bannersList.forEach((a) => {list.add((imagePath + 'banner/' + a))});
    bannersList = list;
    prefs.setString(ConstantStorage.bannersList, json.encode(bannersList));

    int index = operatorList.indexWhere((user) =>
        user[0]['customerId'] == currentOperator['customerId'] &&
        user[0]['outletId'] == currentOperator['outletId']);

    operatorList.forEach((u) => {u[0]['isCurrentUser'] = false});
    if (index < 0) {
      currentOperator['isCurrentUser'] = true;
      operatorList.add(currentOperator);
    } else {
      operatorList[index][0]['isCurrentUser'] = true;
      operatorList[index][0]['username'] = username;
      operatorList[index][0]['password'] = password;
    }

    prefs.setString(ConstantStorage.operatorsList, json.encode(operatorList));

    await initializeApp();

    // this.router.navigateByUrl(ConstantUrls.home);
  }

  static Future<dynamic> login(userName, password, organizationId) async {
    var result = 0;
    var message = '';
    var data;
    try {
      LoginService _loginService = new LoginService();
      OffersService _offersService = new OffersService();
      ItemService _itemService = new ItemService();
      var auth = new Auth();
      // EasyLoading.show(status: 'loading'.tr);
      var response = await _loginService.login(
          userName, password, organizationId, CoreSession.currentAppVersion);
      result = response['status'];
      message = response['message'].toString();
      data = response['data'];

      if (result == GlobalErrors.EchoCustomerMultiAccount.index) {
        CoreSession.organizationList = response['data']['organizationsList'];
      } else if (result == GlobalErrors.Success.index) {
        result = GlobalErrors.Success.index;
        CoreSession.organizationList = response['data']['organizationsList'];
        CoreSession.allorganizationList = response['data']['allorganizationsList'] ?? [];
        await fillCustomerLoggdedInData(
                response, userName, password, organizationId)
            .then(
          (value) async => await auth.MyAuth().then(
            (v1) async => {
              await _offersService.fillOffers().then(
                    (v2) async => {
                      await _itemService.fillHomePageSectionsAndItems().then(
                            (value) => {
                              getDeviceToken(),
                            },
                          ),
                    },
                  ),
            },
          ),
        );
      } else if (response['status'] == GlobalErrors.VersionNotMatch.index) {
        result = GlobalErrors.VersionNotMatch.index;
      } else {
        result = GlobalErrors.Error.index;
      }
    } catch (e) {
      result = GlobalErrors.Error.index;
    } finally {
      // EasyLoading.dismiss();
      if (result != GlobalErrors.VersionNotMatch.index &&
          result != GlobalErrors.Error.index &&
          result != GlobalErrors.EchoCustomerMultiAccount.index)
        result = GlobalErrors.Success.index;
    }
    return {
      'result': result,
      'message': message,
      'data': data,
    };
  }

  static initializeApp() async {
    CoreSession.currentBasket = null;
    SharedPreferences prefs = await SharedPreferences.getInstance();

    var operatorJson = prefs.getString(ConstantStorage.currentOperator);
    if (operatorJson != '' && operatorJson != null) {
      CoreSession.currentOperator = json.decode(operatorJson);
    }
    var operatorsListJson = prefs.getString(ConstantStorage.operatorsList);
    var operatorsList;
    if (operatorsListJson != '' && operatorsListJson != null) {
      operatorsList = json.decode(operatorsListJson);
      CoreSession.operatorList = operatorsList;
    }

    var bannersListJson = prefs.getString(ConstantStorage.bannersList);
    if (bannersListJson != '' && bannersListJson != null) {
      CoreSession.bannersList = json.decode(bannersListJson);
    }
    var customerAppSettingsModelJson =
        prefs.getString(ConstantStorage.customerAppSettingsModel);
    if (customerAppSettingsModelJson != null &&
        customerAppSettingsModelJson != '') {
      var appSettings = json.decode(customerAppSettingsModelJson);
      CustomerAppSettingsModel.showAchievements =
          appSettings['showAchievements'];
      CustomerAppSettingsModel.showApplied = appSettings['showAchievements'];
      CustomerAppSettingsModel.showOffers = appSettings['showOffers'];
      CustomerAppSettingsModel.showSummaryAfterSave =
          appSettings['showSummaryAfterSave'];
      CustomerAppSettingsModel.showCategoriesInHomePage =
          appSettings['showCategoriesInHomePage'];
      CustomerAppSettingsModel.showCategoryInItemScreen =
          appSettings['showCategoryInItemScreen'];
      CustomerAppSettingsModel.showDiscountDetailsInSummary =
          appSettings['showDiscountDetailsInSummary'];
      CustomerAppSettingsModel.showGroupInItemScreen =
          appSettings['showGroupInItemScreen'];
    }

    int index = CoreSession.ordersBasket.indexWhere((o) =>
        o['customerId'] == currentOperator['customerId'] &&
        o['outletId'] == currentOperator['outletId']);

    if (index > -1) {
      currentBasket = ordersBasket[index];
    }
    CoreSession.selectedLanguageId = 1;
    int? langId = prefs.getInt(ConstantStorage.languageId);
    if (langId != null) {
      CoreSession.selectedLanguageId = langId;
    }
    if (CoreSession.currentOperator != null &&
        CoreSession.currentOperator.toString() != 'null') {
      CoreSession.numberOfDigits = CoreSession.currentOperator['numberOfDigit'];
    }
    if (CoreSession.currentOperator.toString() != 'null') {
      CoreSession.numberOfStockDigits =
          CoreSession.currentOperator['numberOfStockDigits'];
    }

    // var v= CoreSession.numberOfDigits ;
    // double x = 0;
    // this.zeroString = int.parse(x.toStringAsFixed(CoreSession.numberOfDigits)); //dont forget
    CoreSession.dataFilled = false;
    CoreSession.numberOfStockDigits = 0;
  }

  static getLocationName() async {
    var position = await Geolocator.getCurrentPosition(
            desiredAccuracy: LocationAccuracy.best)
        .timeout(Duration(seconds: 5));

    try {
      List<Placemark> placemarks = await placemarkFromCoordinates(
        position.latitude,
        position.longitude,
      );
      if (placemarks.first.thoroughfare!.isNotEmpty)
        return placemarks.first.thoroughfare;
      else
        return placemarks.first.administrativeArea;
    } catch (err) {
      return 'error';
    }
  }

  static getLocationNameByParm(LatLng loc) async {
    try {
      List<Placemark> placemarks = await placemarkFromCoordinates(
        loc.latitude,
        loc.longitude,
      );
      if (placemarks.first.thoroughfare!.isNotEmpty)
        return placemarks.first.thoroughfare;
      else
        return placemarks.first.administrativeArea;
    } catch (err) {
      return 'error';
    }
  }

  static recalculateItemNetTotal(pack) {
    var requiredQty = pack['requiredQty'] == '' ? 0 : pack['requiredQty'];
    var price = pack['price'];
    var tax = pack['tax'];
    // ignore: unused_local_variable
    var packId = pack['packId'];
    var gross = price * requiredQty;
    var netAmount = gross + (gross * tax / 100);
    pack['netAmount'] = netAmount;
    pack['netAmountString'] =
        netAmount.toStringAsFixed(CoreSession.numberOfDigits);
    return netAmount;
  }

  static addItemToFavList(item) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
  }

  static getFavBasket() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String? favBasketJson = prefs.getString(ConstantStorage.favBasket);
    var basket;
    var favBasket = [];

    if (favBasketJson != '' && favBasketJson != null && favBasketJson != '[]') {
      favBasket = json.decode(favBasketJson);
      for (var item in favBasket) {
        var val = item;
        if (val['customerId'] == CoreSession.currentOperator['customerId'] &&
            val['outletId'] == CoreSession.currentOperator['outletId']) {
          basket = val;
        }
        if (val['customerId'] == 0 && val['outletId'] != null) {
          hasGestUserBefore = true;
        }
        if (basket == null) {
          basket = {
            'customerId': currentOperator['customerId'],
            'outletId': currentOperator['outletId'],
            'items': [],
          };
        } else {
          CoreSession.favBasket = basket;
        }
        favBasket.add(basket);
      }
    } else {
      basket = {
        'customerId': CoreSession.currentOperator['customerId'],
        'outletId': CoreSession.currentOperator['outletId'],
        'items': [],
      };
    }
  }

  static getCustomerBasket() async {
    //ItemService.cartCount = 0;
    SharedPreferences prefs = await SharedPreferences.getInstance();
    // ignore: avoid_init_to_null
    var basket = null;
    var savedBasket = [];

    if (CoreSession.currentOperator != null && operatorList.length > 0) {
      String? orderBasketJson = prefs.getString(ConstantStorage.orderBasket);
      if (orderBasketJson != '' &&
          orderBasketJson != null &&
          orderBasketJson != '[]') {
        savedBasket = json.decode(orderBasketJson);
        for (var item in savedBasket) {
          var val = item;
          if (val['customerId'] == CoreSession.currentOperator['customerId'] &&
              val['outletId'] == CoreSession.currentOperator['outletId']) {
            basket = val;
          }
          if (val['customerId'] == 0 && val['outletId'] != null) {
            hasGestUserBefore = true;
          }
        }
        if (basket == null) {
          basket = {
            'customerId': currentOperator['customerId'],
            'outletId': currentOperator['outletId'],
            'items': [],
            'netTotal': 0
          };
        } else {
          CoreSession.currentBasket = basket;
        }
      } else {
        basket = {
          'customerId': CoreSession.currentOperator['customerId'],
          'outletId': CoreSession.currentOperator['outletId'],
          'items': [],
          'netTotal': 0
        };
      }
      var currentUserItems = [];
      currentUserItems = basket['items'];
      var basketNetTotal = 0.0;
      if (basket != null &&
          hasGestUserBefore &&
          CoreSession.currentOperator['customerId'] != Global.GuestCustomerId &&
          currentUserItems.length <= 0) {
        //check if savedBasket has basket from gest user
        int index = savedBasket.indexWhere(
            (element) => element['customerId'] == Global.GuestCustomerId);
        if (index != -1) {
          var gestBasket = savedBasket[index];
          var gestItems = [];
          gestItems = gestBasket['items'];
          //check if the basket from gest user has items
          if (gestItems.length > 0) {
            for (var item in gestItems) {
              int index1 = ItemService.items
                  .indexWhere((cItem) => cItem['packId'] == item['packId']);
              //check if the basket from gest user found in chached item
              if (index1 > -1) {
                var myItem;
                myItem = ItemService.items[index1];
                myItem['requiredQty'] = item['requiredQty'];
                if (myItem['exclusivePrice'] != item['exclusivePrice']) {
                  hasDeffirentPricesFromGestUser = true;
                }
                var netTotal = await recalculateItemNetTotal(myItem);
                basketNetTotal = basketNetTotal + netTotal;
                int index2 = currentUserItems.indexWhere(
                    (element) => element['packId'] == item['packId']);
                //check if the basket from current user has the item #c1
                if (index2 > -1) {
                  //if #c1 is true remove and add new
                  currentUserItems.remove(index2);
                  currentUserItems.add(myItem);
                } else {
                  //if #c1 is false add new
                  currentUserItems.add(myItem);
                }
              }
            }

            basket['items'] = [];
            basket['items'] = currentUserItems;
            basket['netTotal'] = basketNetTotal;
            ItemService.netTotal = basket['netTotal'];
            savedBasket.removeAt(index);
          }
        }
      }

      int index = savedBasket.indexWhere((element) =>
          element['customerId'] == CoreSession.currentOperator['customerId'] &&
          element['outletId'] == CoreSession.currentOperator['outletId']);
      if (index < 0) {
        savedBasket.add(basket);
      } else {
        savedBasket.remove(savedBasket[index]);
        savedBasket.add(basket);
      }
      CoreSession.currentBasket = basket;
      CoreSession.ordersBasket.add(basket);
      prefs.setString(ConstantStorage.orderBasket, json.encode(savedBasket));
      if (CoreSession.currentBasket != null) {
        if (CoreSession.currentBasket['items'].length > 0) {
          var items = [];
          items = CoreSession.currentBasket['items'];
          TapPage.cartValue.value = items.length;
          for (var pack in items) {
            var itemIndex = ItemService.items.indexWhere(
              (element) => element['packId'] == pack['packId'],
            );
            if (itemIndex > -1) {
              ItemService.items[itemIndex]['requiredQty'] = pack['requiredQty'];
            }
          }
        } else {
          TapPage.cartValue.value = 0;
        }
      }

      savedBasket = [];
    }
  }

  static Future<void> showYesNoDialog(
      BuildContext context, VoidCallback onYesPressed,String message) async {
    return showDialog<void>(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text('waiting-confirmation'.tr),
          content: Text(message),
          actions: <Widget>[
            TextButton(
              child: Text('no'.tr),
              onPressed: () {
                Navigator.of(context)
                    .pop(false); // Return false when "No" is pressed.
              },
            ),
            TextButton(
              child: Text('yes'.tr),
              onPressed: () {
                onYesPressed(); // Return true when "Yes" is pressed.
                Navigator.of(context).pop(true);
              },
            ),
          ],
        );
      },
    );
  }

  static logOut() async {
    // ignore: non_constant_identifier_names
    ItemService _ItemService = new ItemService();
    // ignore: unused_local_variable
    var response = await _ItemService.saveCustomerBasket(
        CoreSession.currentBasket['items']);
    //Clear Storage
    clearCatchData();
  }

  static clearCatchData() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.remove(ConstantStorage.tokenName);
    prefs.remove(ConstantStorage.currentOperator);
    prefs.remove(ConstantStorage.username);
    prefs.remove(ConstantStorage.password);
    // remove oper

    c = '';
    isRTL = false;

    ordersBasket = [];
    Dashboards = [];
    currentBasket = null;
    operatorList = [];
    baseCurrencyCode = '';
    zeroString = 0;
    divisionList = [];
    brandList = [];
    categoryList = [];
    masterGroupes = [];
    homePageData = [];

    hasGestUserBefore = false;
    dataFilled = false;
    bannersList = [];

    homeSlider = {};
    homePageTop = {};
    newNotificationCount = 0;

    showLogoInStartup = false;
    showCategoriesInHomePage = false;
    showCategoryInItemScreen = false;
    backgroundColorByHexString = '';
    selectedItemBrandId = -1;
    selectedItemCategoryId = -1;
    selectedItemSearchText = '';
    cartShowBackbtn = false;
    guessUser = false;
    hideBackgroundForStartup = false;
    hideReorderButton = false;
    locale = Locale('en', 'US');

    currentOperator = null;
    notificationVideoPath = '';
    notificationImagePath = '';
  }

  static onSearch() {}

  static fillLocationData(var response) {
    if (response['data'].length > 0) {
      CoreSession.locationHierarchyLevel =
          response['data']['locationHierarchyLevel'];

      CoreSession.countries = response['data']['countries'];
      CoreSession.states = response['data']['states'];
      CoreSession.cities = response['data']['cities'];
      CoreSession.areas = response['data']['areas'];
      CoreSession.streets = response['data']['streets'];

      CoreSession.Desc_Geographical_Location_Name_One =
          response['data']['desc_Geographical_Location_Name_One'];
      CoreSession.Desc_Geographical_Location_Name_Two =
          response['data']['desc_Geographical_Location_Name_Two'];
      CoreSession.Desc_Geographical_Location_Name_Three =
          response['data']['desc_Geographical_Location_Name_Three'];
      CoreSession.Desc_Geographical_Location_Name_Four =
          response['data']['desc_Geographical_Location_Name_Four'];
      CoreSession.Desc_Geographical_Location_Name_Five =
          response['data']['desc_Geographical_Location_Name_Five'];

      // if (CoreSession.countries.length > 0) {
      //   CoreSession.countries.insert(0, CoreSession.countries);
      // }
    }
  }
static void showToast(String message) {
    Fluttertoast.showToast(
      msg: message.tr,
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.BOTTOM,
      backgroundColor: Colors.black,
      textColor: Colors.white,
    );
  }
//#endregion
}
