import 'dart:convert';
import 'dart:developer';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/models/module_permissions_model.dart';
import 'package:test_sa/models/new_models/general_response_model.dart';
import 'package:test_sa/models/new_models/update_password.dart';
import 'package:test_sa/models/new_models/verify_otp_model.dart';
import 'package:test_sa/models/site_contact_info_model.dart';
import 'package:test_sa/models/user.dart';
import 'package:test_sa/models/user_rota_model.dart';
import 'package:test_sa/new_views/swipe_module/models/swipe_model.dart';
import 'package:test_sa/new_views/swipe_module/models/swipe_transaction_history.dart';
import 'package:test_sa/new_views/swipe_module/models/swipe_transaction_model.dart';

import '../../../new_views/common_widgets/app_lazy_loading.dart';

class UserProvider extends ChangeNotifier {
  //reset provider data
  void reset() {
    _user = null;
    ApiManager.instance.user = user;
    _loading = false;
  }

  // contain user data
  // when user not login or register _user = null
  User? _user;

  User? get user => _user;

  User? _refreshedUser;

  User? get refreshedUser => _refreshedUser;

  File? profileImage;

  bool get isEngineer => user!.type == UsersTypes.engineer;

  bool get isNurse => user!.type == UsersTypes.normal_user;

  bool get isAssessor => user!.type == UsersTypes.assessor || user!.type == UsersTypes.assessorTl;

  bool get isQualityUser => user!.type == UsersTypes.qualityUser;

  bool get isCommissioningEngineer => user!.type == UsersTypes.commissioningEngineer;
  bool get isHouseKeeper => user!.type == UsersTypes.houseKeeper;

  VerifyOtpModel _verifyOtpModel = VerifyOtpModel();
  SwipeTransaction _swipeTransactionModel = SwipeTransaction();
  List<SwipeHistory> _swipeHistory = [];
  List<SiteContactInfoModel> _siteContactList = [];
  List<ModulesPermissionsModel> _modulesPermissionsModel = [];
  UserContactInfoModel userInfoModel = UserContactInfoModel();

  SwipeTransaction get swipeTransactionModel => _swipeTransactionModel;

  List<SwipeHistory> get swipeHistory => _swipeHistory;

  List<SiteContactInfoModel> get siteContactList => _siteContactList;

  List<ModulesPermissionsModel> get modulesPermissionsList => _modulesPermissionsModel;

  ModulesPermissionsModel currentModelPermission(int moduleId) => ModulesPermissionsModel.fromJson(_modulesPermissionsModel.singleWhere((module) => module.module!.value == moduleId).toJson());

  set swipeHistory(List<SwipeHistory> value) {
    _swipeHistory = value;
    notifyListeners();
  }

  set swipeTransactionModel(SwipeTransaction value) {
    _swipeTransactionModel = value;
    notifyListeners();
  }

  set siteContactList(List<SiteContactInfoModel> value) {
    _siteContactList = value;
    notifyListeners();
  }

  VerifyOtpModel get verifyOtpModel => _verifyOtpModel;

  set verifyOtpModel(VerifyOtpModel value) {
    _verifyOtpModel = value;
    notifyListeners();
  }

  void setUser(User user) {
    _user = user;
    ApiManager.instance.user = user;
    notifyListeners();
  }

  // when login or register in-process _login = true
  // when login or register is done or not start = false
  bool _loading = false;

  bool get isLoading => _loading;

  bool isUserConfirmSwipe = false;

  set isLoading(bool isLoading) {
    _loading = isLoading;
    notifyListeners();
  }

  /// sign in with user - need (email or phone) and password;
  /// return -2 if request in progress
  /// return -1 if error happen when sending request
  /// return state code if request complete may be 200, 404 or 403
  /// for more details check http state manager
  /// lib\controllers\http_status_manger\http_status_manger.dart
  Future<int> login({required BuildContext context, required User user}) async {
    if (_loading == true) return -2;
    _loading = true;
    notifyListeners();
    Response response;
    try {
      // showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
      response = await ApiManager.instance.post(URLs.login, body: await user.toLoginJson());

      _loading = false;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        // client's request was successfully received
        _user = await User.fromJson(jsonDecode(response.body));
        _user!.profilePhotoName = URLs.getFileUrl(_user!.profilePhotoName);
        ApiManager.instance.user = _user;
        notifyListeners();
        // Navigator.pop(context);
        return response.statusCode;
      }
      notifyListeners();
      // Navigator.pop(context);
      return response.statusCode;
    } catch (error) {
      //  debugPrint(error);
      print('SSL or Network Error: $error');
      // Navigator.pop(context);
      _loading = false;
      notifyListeners();
      return -1;
    }
  }

  Future<bool> getUserInfo({String? fireBaseToken}) async {
    Response response;
    try {
      response = await ApiManager.instance.post(URLs.getUserInfo, body: {'fireBaseToken': fireBaseToken});
      if (response.statusCode >= 200 && response.statusCode < 300) {
        _refreshedUser = await User.fromJson(jsonDecode(response.body));
        _refreshedUser!.profilePhotoName = URLs.getFileUrl(_refreshedUser!.profilePhotoName);
        if (response.statusCode == 200) {
          return true;
        }
      }
      return false;
    } catch (error) {
      return false;
    }
  }

  Future<bool> userChangeAssetGroup() async {
    Response response;
    try {
      response = await ApiManager.instance.post(URLs.userChangeAssetGroup, body: {});
      if (response.statusCode >= 200 && response.statusCode < 300) {
        User tempUser = await User.fromJson(jsonDecode(response.body));
        tempUser.profilePhotoName = URLs.getFileUrl(tempUser!.profilePhotoName);
        ApiManager.instance.user = tempUser;
        _user = user;
        return true;
      }
      return false;
    } catch (error) {
      return false;
    }
  }

  Future<bool> getMobilePermissionByUser() async {
    _modulesPermissionsModel = [];
    Response response;
    try {
      response = await ApiManager.instance.get(URLs.getMobilePermissionByUser, enableToastMessage: false);
      if (response.statusCode >= 200 && response.statusCode < 300) {
        List dataList = json.decode(response.body)["data"] ?? [];
        _modulesPermissionsModel = List.generate(dataList.length, (index) => ModulesPermissionsModel.fromJson(dataList[index])).where((module) => module.canView!).toList();
        if (response.statusCode == 200) {
          return true;
        }
      }
      return false;
    } catch (error) {
      return false;
    }
  }

  Future<bool> logout(BuildContext context) async {
    Response response;
    try {
      showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
      response = await ApiManager.instance.post(URLs.logout, body: {});
      if (response.statusCode >= 200 && response.statusCode < 300) {
        Navigator.pop(context);
        return true;
      }
      Navigator.pop(context);
      return false;
    } catch (error) {
      Navigator.pop(context);
      return false;
    }
  }

  Future<bool> deleteUser(BuildContext context, {required String employeeId, required String userId}) async {
    Response response;
    try {
      showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
      response = await ApiManager.instance.post(
        URLs.deleteUser,
        body: {
          "employeeId": employeeId,
          "userId": userId,
        },
      );
      if (response.statusCode >= 200 && response.statusCode < 300) {
        Navigator.pop(context);
        return true;
      }
      Navigator.pop(context);
      return false;
    } catch (error) {
      Navigator.pop(context);
      return false;
    }
  }

  /// sign up with User object;
  /// return -2 if request in progress
  /// return -1 if error happen when sending request
  /// return state code if request complete may be 200, 404 or 403
  /// for more details about state codes check http state manager
  /// lib\controllers\http_status_manger\http_status_manger.dart
  // Future<int> register({
  //   required String host,
  //   required User user,
  // }) async {
  //   if (_loading == true) return -2;
  //   _loading = true;
  //   notifyListeners();
  //   Response response;
  //   try {
  //     response = await ApiManager.instance.post(
  //       URLs.register,
  //       body: await user.toLoginJson(),
  //     );
  //   } catch (error) {
  //     _loading = false;
  //     notifyListeners();
  //     return -1;
  //   }
  //   _loading = false;
  //   notifyListeners();
  //   if (response.statusCode >= 200 && response.statusCode < 300) {
  //     // client's request was successfully received
  //     _user = User.fromJson(jsonDecode(utf8.decode(response.bodyBytes))[0]);
  //     _user!.clientId = user.clientId;
  //     _user!.clientName = user.clientName;
  //     notifyListeners();
  //     return response.statusCode;
  //   }
  //   return response.statusCode;
  // }
  Future<GeneralResponseModel> sendForgetPasswordOtp({required BuildContext context, required String employeeId, required String typeSend}) async {
    GeneralResponseModel generalResponseModel = GeneralResponseModel(responseCode: -1);
    if (_loading == true) return generalResponseModel;
    _loading = true;
    notifyListeners();
    Response response;
    try {
      showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
      response = await ApiManager.instance.post(URLs.sendForgetPasswordOtp, showToast: false, body: {"employeeId": employeeId, "typeSend": typeSend});
      generalResponseModel = GeneralResponseModel.fromJson(json.decode(response.body));
      _loading = false;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        notifyListeners();
        Navigator.pop(context);
        return generalResponseModel;
      }
      notifyListeners();
      Navigator.pop(context);
      return generalResponseModel;
    } catch (error) {
      //  debugPrint(error);
      Navigator.pop(context);
      _loading = false;
      notifyListeners();
      return generalResponseModel;
    }
  }

  Future<GeneralResponseModel> forgetPasswordValidateOtp({required BuildContext context, required String employeeId, required String otp}) async {
    GeneralResponseModel generalResponseModel = GeneralResponseModel(responseCode: -1);
    // if (_loading == true) return generalResponseModel;
    _loading = true;
    notifyListeners();
    Response response;
    try {
      showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
      response = await ApiManager.instance.post(URLs.sendForgetPasswordValidateOtp + '?employeeId=$employeeId&otp=$otp', body: {});
      generalResponseModel = GeneralResponseModel.fromJson(json.decode(response.body));
      _loading = false;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        if (generalResponseModel.data != null) {
          verifyOtpModel = VerifyOtpModel.fromJson(generalResponseModel.data);
        }
        notifyListeners();
        Navigator.pop(context);
        return generalResponseModel;
      }
      notifyListeners();
      Navigator.pop(context);
      return generalResponseModel;
    } catch (error) {
      //  debugPrint(error);
      Navigator.pop(context);
      _loading = false;
      notifyListeners();
      return generalResponseModel;
    }
  }

  Future<GeneralResponseModel> updateNewPassword({required BuildContext context, required UpdatePasswordModel updatePasswordModel}) async {
    GeneralResponseModel generalResponseModel = GeneralResponseModel(responseCode: -1);
    if (_loading == true) return generalResponseModel;
    _loading = true;
    notifyListeners();
    Response response;
    try {
      showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
      response = await ApiManager.instance.post(URLs.updateNewPassword, body: updatePasswordModel.toJson());
      generalResponseModel = GeneralResponseModel.fromJson(json.decode(response.body));
      _loading = false;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        notifyListeners();
        Navigator.pop(context);
        return generalResponseModel;
      }
      notifyListeners();
      Navigator.pop(context);
      return generalResponseModel;
    } catch (error) {
      //  debugPrint(error);
      //  debugPrint(error);
      Navigator.pop(context);
      _loading = false;
      notifyListeners();
      return generalResponseModel;
    }
  }

  Future<int> uploadProfileImage(String userId, File image) async {
    if (_loading == true) return -2;
    _loading = true;
    notifyListeners();
    Response response;
    try {
      Map<String, dynamic> body = {
        "userId": userId,
        "imageEmployee": "${image.path.split("/").last}|${base64Encode(image.readAsBytesSync())}",
      };
      response = await ApiManager.instance.post(URLs.updateProfileImage, body: body);
      if (response.statusCode >= 200 && response.statusCode < 300) {
        profileImage = image;
        String imageId = jsonDecode(response.body)["data"];
        _user!.profilePhotoName = URLs.getFileUrl(imageId);
        ApiManager.instance.user = _user;
      }
      _loading = false;
      notifyListeners();
      return response.statusCode;
    } catch (error) {
      _loading = false;
      notifyListeners();
      return -1;
    }
  }

  Future<bool> updateContactInfo(String userId, String email, String phoneNo, String extensionNo) async {
    Response response;
    try {
      response = await ApiManager.instance.put('${URLs.updateUserContactInformation}/userId?userId=$userId', body: {"mobileNumber": phoneNo, "email": email, "extensionNo": extensionNo});
      if (response.statusCode >= 200 && response.statusCode < 300) {
        Fluttertoast.showToast(msg: "Updated Successfully");
        return true;
      } else {
        Fluttertoast.showToast(msg: "${json.decode(response.body)['message']}");
      }
      return false;
    } catch (e) {
      return false;
    }
  }

  Future<SwipeModel> makeSwipe({required Swipe model}) async {
    isLoading = true;
    SwipeModel swipeResponse = SwipeModel(data: false, message: '', responseCode: 0, isSuccess: false);
    notifyListeners();
    Response response;
    // try {
    response = await ApiManager.instance.post(URLs.swipeUrl, body: model.toJson(), showToast: false);
    swipeResponse = SwipeModel.fromJson(json.decode(response.body));

    if (response.statusCode >= 200 && response.statusCode < 300) {
      isUserConfirmSwipe = true;
      await getSwipeLastTransaction(userId: user!.userID!);

      notifyListeners();
    }
    isLoading = false;
    notifyListeners();
    return swipeResponse;
    // } catch (error) {
    //   notifyListeners();
    //   return swipeResponse;
    // }
  }

  Future<int> getSwipeLastTransaction({required String userId}) async {
    isLoading = true;
    notifyListeners();
    Response response;
    var body = {
      "userId": userId,
    };
    try {
      response = await ApiManager.instance.post(URLs.getSwipeLastTransactionUrl, body: body, showToast: false);

      if (response.statusCode >= 200 && response.statusCode < 300) {
        swipeTransactionModel = SwipeTransaction.fromJson(json.decode(response.body)['data']);
      }
      isLoading = false;
      notifyListeners();
      return response.statusCode;
    } catch (error) {
      isLoading = false;
      notifyListeners();
      return -1;
    }
  }

  Future<int> getSiteContactInfo() async {
    Response response;
    try {
      response = await ApiManager.instance.get(URLs.getSiteContactInfo);
      if (response.statusCode >= 200 && response.statusCode < 300) {
        List dataList = GeneralResponseModel.fromJson(json.decode(response.body)).data;
        _siteContactList = List.generate(dataList.length, (index) => SiteContactInfoModel.fromJson(dataList[index]));
      }
      return response.statusCode;
    } catch (error) {
      _siteContactList = [];
      return -1;
    }
  }

  Future<UserRotaModel?> getUserTodayRota(String startDate, String endDate) async {
    Response response;
    try {
      response = await ApiManager.instance.get(URLs.getUserRota + "?fromDate=$startDate&toDate=$endDate");
      if (response.statusCode >= 200 && response.statusCode < 300) {
        List dataList = json.decode(response.body);
        return UserRotaModel.fromJson(dataList.first);
      }
      return null;
    } catch (error) {
      return null;
    }
  }

  Future<List<UserRotaModel>> getUserMonthlyRota(String startDate, String endDate) async {
    Response response;
    try {
      response = await ApiManager.instance.get(URLs.getUserRota + "?fromDate=$startDate&toDate=$endDate");
      if (response.statusCode >= 200 && response.statusCode < 300) {
        List dataList = json.decode(response.body);
        return dataList.map((e) => UserRotaModel.fromJson(e)).toList();
      }
      return [];
    } catch (error) {
      return [];
    }
  }

  Future<int> getSwipeTransactionHistory({required String userId, required DateTime dateFrom, required DateTime dateTo}) async {
    isLoading = true;
    notifyListeners();
    Response response;
    var body = {
      "userId": userId,
      "dateFrom": dateFrom.toIso8601String(),
      "dateTo": dateTo.toIso8601String(),
      "IsSucces": true,
    };
    try {
      response = await ApiManager.instance.post(URLs.getSwipeTransactionHistoryUrl, body: body);

      if (response.statusCode >= 200 && response.statusCode < 300) {
        List dataList = GeneralResponseModel.fromJson(json.decode(response.body)).data;
        swipeHistory = List.generate(dataList.length, (index) => SwipeHistory.fromJson(dataList[index]));
      }
      isLoading = false;
      notifyListeners();
      return response.statusCode;
    } catch (error) {
      isLoading = false;
      notifyListeners();
      return -1;
    }
  }

// Future<int> updateProfile({
//   required String host,
//   required User user,
// }) async {
//   if (_loading == true) return -2;
//   _loading = true;
//   notifyListeners();
//   Response response;
//
//   Map<String, dynamic> jsonObject = {};
//   jsonObject["uid"] = user.id;
//   jsonObject["token"] = user.token;
//   if (user.departmentId != _user.departmentId) jsonObject["department"] = user.departmentId;
//   // if (user.whatsApp != _user.whatsApp) jsonObject["whatsapp"] = user.whatsApp;
//   if (user.phoneNumber != _user.phoneNumber) jsonObject["phone"] = user.phoneNumber;
//   try {
//     response = response = await ApiManager.instance.post(
//       URLs.login,
//       body: jsonObject,
//     );
//   } catch (error) {
//     _loading = false;
//     notifyListeners();
//     return -1;
//   }
//
//   _loading = false;
//   notifyListeners();
//
//   if (response.statusCode >= 200 && response.statusCode < 300) {
//     // client's request was successfully received
//     _user = User.fromJson(jsonDecode(utf8.decode(response.bodyBytes))[0]);
//     _user.clientId = user.clientId;
//     _user.clientName = user.clientName;
//     _user.departmentName = user.departmentName;
//     _user.departmentId = user.departmentId;
//     notifyListeners();
//     return response.statusCode;
//   }
//   return response.statusCode;
// }
}
