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/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;
  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
  fetchAttendanceTracking() async {
    try {
      attendanceTracking = await DashbaordApiClient().getAttendanceTracking();
      isAttendanceTrackingLoading = false;
      isTimeRemainingInSeconds = calculateSeconds("00:00:00");
      endTime = DateTime.now().millisecondsSinceEpoch + Duration(seconds: isTimeRemainingInSeconds).inMilliseconds;
      print("isTimeRemainingInSeconds " + isTimeRemainingInSeconds.toString());
      print("endTime " + endTime.toString());

      // notifyListeners();
    } catch (ex) {
      Utils.handleException(ex, null);
    }
  }

  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() {
    isAttendanceTrackingLoading = !isAttendanceTrackingLoading;
    isWorkListLoading = !isWorkListLoading;
    attendanceTracking?.pSwipeIn = "a";
    isTimeRemainingInSeconds = calculateSeconds("00:10:30");
    endTime = DateTime.now().millisecondsSinceEpoch + Duration(seconds: isTimeRemainingInSeconds).inMilliseconds;

    notifyListeners();
  }

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

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

  //Leave and Ticket Balance API's & Methods
  fetchLeaveTicketBalance() async {
    try {
      GenericResponseModel? genericResponseModel = await DashbaordApiClient().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, null);
    }
  }

  //List Menu API's & Methods
  fetchListMenu() async {
    try {
      GenericResponseModel? genericResponseModel = await DashbaordApiClient().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);
    }
  }

  //Menu Entries API's & Methods
  fetchMenuEntries() async {
    try {
      GenericResponseModel? genericResponseModel = await DashbaordApiClient().getGetMenuEntries();
      getMenuEntriesList = genericResponseModel!.getMenuEntriesList;
      homeMenus = parseMenues(getMenuEntriesList ?? []);
      isServicesMenusLoading = false;
      notifyListeners();
    } catch (ex) {
      logger.wtf(ex);
      notifyListeners();
      Utils.handleException(ex, 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;
  }
}
