import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/dashboard_api_client.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_model.dart';
import 'package:mohem_flutter_app/models/dashboard/get_open_notifications_list.dart';
import 'package:mohem_flutter_app/models/dashboard/itg_forms_model.dart';
import 'package:mohem_flutter_app/models/dashboard/menu_entries.dart';
import 'package:mohem_flutter_app/models/dashboard/menus.dart';
import 'package:mohem_flutter_app/models/generic_response_model.dart';
import 'package:mohem_flutter_app/widgets/Updater.dart';

/// Mix-in [DiagnosticableTreeMixin] to have access to [debugFillProperties] for the devtool
// ignore: prefer_mixin
class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
  //Attendance Tracking
  bool isAttendanceTrackingLoading = true;
  int endTime = 0, isTimeRemainingInSeconds = 0;
  double progress = 0.0;
  GetAttendanceTracking? attendanceTracking;

  //Work List
  bool isWorkListLoading = true;
  int workListCounter = 0;

  //Misssing Swipe
  bool isMissingSwipeLoading = true;
  int missingSwipeCounter = 0;

  //Leave and Ticket Balance
  bool isLeaveTicketBalanceLoading = true;
  double leaveBalance = 0;
  double ticketBalance = 0;

  //Menu Entries
  bool isServicesMenusLoading = true;
  List<Menus>? homeMenus;
  List<GetMenuEntriesList>? getMenuEntriesList;

  //Attendance Tracking API's & Methods
  Future<bool> fetchAttendanceTracking(context) async {
    try {
      attendanceTracking = await DashboardApiClient().getAttendanceTracking();
      print("attendanceTracking:" + (attendanceTracking!.pRemainingHours).toString());
      isAttendanceTrackingLoading = false;
      // isTimeRemainingInSeconds = calculateSeconds( "00:00:00");
      if (attendanceTracking?.pSwipeIn != null) {
        isTimeRemainingInSeconds = calculateSeconds(attendanceTracking!.pRemainingHours ?? "00:00:00");
        int totalShiftTimeInSeconds = calculateSeconds(attendanceTracking!.pScheduledHours ?? "00:00:00");
        print("totalShiftTimeInSeconds: " + totalShiftTimeInSeconds.toString());
        print("isTimeRemainingInSeconds: " + isTimeRemainingInSeconds.toString());
        progress = (isTimeRemainingInSeconds / totalShiftTimeInSeconds);
        endTime = DateTime.now().millisecondsSinceEpoch + Duration(seconds: isTimeRemainingInSeconds).inMilliseconds;
        print("endTime " + endTime.toString());
      }

      notifyListeners();
    } catch (ex) {
      Utils.handleException(ex, context, null);
    }
    return true;
  }

  int calculateSeconds(String time) {
    int hour = int.parse(time.split(":")[0]);
    int mints = int.parse(time.split(":")[1]);
    int seconds = int.parse(time.split(":")[2]);
    return ((hour * 60 * 60) + (mints * 60) + seconds);
  }

  update(context) {
    fetchAttendanceTracking(context);
    // isAttendanceTrackingLoading = !isAttendanceTrackingLoading;
    // isWorkListLoading = !isWorkListLoading;
    // attendanceTracking?.pSwipeIn = "a";
    // isTimeRemainingInSeconds = calculateSeconds("00:10:30");
    // endTime = DateTime.now().millisecondsSinceEpoch + Duration(seconds: isTimeRemainingInSeconds).inMilliseconds;
    // notifyListeners();
  }

  ItgFormsModel? itgFormsModel;
  List<GetOpenNotificationsList>? getOpenNotificationsList;

  //Work List API's & Methods
  Future fetchWorkListCounter(context, {bool showLoading = false}) async {
    try {
      if (showLoading) Utils.showLoading(context);
      GenericResponseModel? genericResponseModel = await DashboardApiClient().getOpenNotifications();
      isWorkListLoading = false;
      getOpenNotificationsList = genericResponseModel?.getOpenNotificationsList;
      workListCounter = genericResponseModel?.pOPENNTFNUMBER ?? 0;
      itgFormsModel = await DashboardApiClient().getItgFormsPendingTask();
      workListCounter = workListCounter + (itgFormsModel?.totalCount ?? 0);
      if (showLoading) Utils.hideLoading(context);
      notifyListeners();
    } catch (ex) {
      isWorkListLoading = false;
      logger.wtf(ex);
      if (showLoading) Utils.hideLoading(context);
      notifyListeners();
      Utils.handleException(ex, context, null);
    }
  }

  //Missing Siwpe API's & Methods
  Future fetchMissingSwipe(context) async {
    try {
      GenericResponseModel? genericResponseModel = await DashboardApiClient().getOpenMissingSwipes();
      isMissingSwipeLoading = false;
      missingSwipeCounter = genericResponseModel!.getOpenMissingSwipesList!.pOpenMissingSwipes ?? 0;
      notifyListeners();
    } catch (ex) {
      isMissingSwipeLoading = false;
      logger.wtf(ex);
      notifyListeners();
      Utils.handleException(ex, context, null);
    }
  }

  //Leave and Ticket Balance API's & Methods
  Future fetchLeaveTicketBalance(context) async {
    try {
      GenericResponseModel? genericResponseModel = await DashboardApiClient().getAccrualBalances();
      isLeaveTicketBalanceLoading = false;
      leaveBalance = genericResponseModel?.getAccrualBalancesList![0].accrualNetEntitlement ?? 0.0;
      ticketBalance = (genericResponseModel?.getAccrualBalancesList![1].accrualNetEntitlement ?? 0.0) + (genericResponseModel?.getAccrualBalancesList![2].accrualNetEntitlement ?? 0.0);
      notifyListeners();
    } catch (ex) {
      isLeaveTicketBalanceLoading = false;
      logger.wtf(ex);
      notifyListeners();
      Utils.handleException(ex, context, null);
    }
  }

  //List Menu API's & Methods
  fetchListMenu() async {
    try {
      GenericResponseModel? genericResponseModel = await DashboardApiClient().getListMenu();
      Map<String, String> map = {};
      print(jsonEncode(genericResponseModel!.listMenu));
      for (int i = 0; i < genericResponseModel.listMenu!.length; i++) {
        print(genericResponseModel.listMenu![i].menuName ?? "");
        map[genericResponseModel.listMenu![i].menuName ?? ""] = i.toString();
      }
      logger.i(map);
      notifyListeners();
    } catch (ex) {
      logger.wtf(ex);
      notifyListeners();
      Utils.handleException(ex, null, null);
    }
  }

  //Menu Entries API's & Methods
  fetchMenuEntries() async {
    try {
      GenericResponseModel? genericResponseModel = await DashboardApiClient().getGetMenuEntries();
      getMenuEntriesList = genericResponseModel!.getMenuEntriesList;
      homeMenus = parseMenues(getMenuEntriesList ?? []);
      isServicesMenusLoading = false;
      notifyListeners();
    } catch (ex) {
      logger.wtf(ex);
      notifyListeners();
      Utils.handleException(ex, null, null);
    }
  }

  List<Menus> parseMenues(List<GetMenuEntriesList> getMenuEntriesList) {
    List<Menus> menus = [];
    for (int i = 0; i < getMenuEntriesList.length; i++) {
      if (getMenuEntriesList[i].parentMenuName!.isEmpty) {
        menus.add(Menus(getMenuEntriesList[i], getMenuEntriesList.where((element) => getMenuEntriesList[i].menuName == element.parentMenuName).toList()));
      }
    }

    // Verify Menus by printing in log
    // for(int i=0;i<menus.length;i++){
    //   logger.i(jsonEncode(menus[i].menuEntry.prompt));
    //   for(int j=0;j<menus[i].menuEntiesList.length;j++){
    //     logger.e(menus[i].menuEntiesList[j].prompt);
    //   }
    // }
    return menus;
  }

  void notify() {
    notifyListeners();
  }
}
