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

import 'package:flutter/widgets.dart';
import 'package:http/http.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/controllers/providers/api/all_requests_provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/enum_extensions.dart';
import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/models/new_models/dashboard_count.dart';
import 'package:test_sa/models/new_models/dashboard_detail.dart' as DD;
import 'package:test_sa/models/new_models/swipe_model.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';

import '../controllers/providers/api/user_provider.dart';

class DashBoardProvider extends ChangeNotifier {
  bool isAllCountLoading = false;
  bool isLoading = false;
  bool _isDetailLoading = false;
  bool _isShowDashBoardCalendar = true;
  DateTime _upcomingFilterSelectedDate = DateTime.now();

  DateTime get upcomingFilterSelectedDate => _upcomingFilterSelectedDate;

  set upcomingFilterSelectedDate(DateTime value) {
    _upcomingFilterSelectedDate = value;
    notifyListeners();
  }

  bool get isShowDashBoardCalendar => _isShowDashBoardCalendar;

  set isShowDashBoardCalendar(bool value) {
    _isShowDashBoardCalendar = value;
    notifyListeners();
  }

  int _status = 0;

  int get status => _status;

  set status(int value) {
    _status = value;
    notifyListeners();
  }

  List<int> listIndex = [];

  int? _currentListIndex;

  int? get currentListIndex => _currentListIndex;

  // Helper method to check if a tab index is UnAssigned
  bool isUnassignedTab(int index) {
    if (index >= 0 && index < tabs.length) {
      return tabs[index].requestType == RequestTypeEnum.unassigned;
    }
    return false;
  }

  // Helper method to get the UnAssigned tab index (returns -1 if not found)
  int getUnassignedTabIndex() {
    for (int i = 0; i < tabs.length; i++) {
      if (tabs[i].requestType == RequestTypeEnum.unassigned) {
        return i;
      }
    }
    return -1;
  }

  set currentListIndex(int? value) {
    _currentListIndex = value;
    if (value == null) {
      listIndex.clear();
    } else {
      // Check if the selected tab is UnAssigned by its requestType
      bool isUnassignedClicked = isUnassignedTab(value);
      int unassignedIndex = getUnassignedTabIndex();
      bool hasUnassignedSelected = unassignedIndex != -1 && listIndex.contains(unassignedIndex);

      if (isUnassignedClicked) {
        // UnAssigned is exclusive - clear all and select only UnAssigned
        listIndex.clear();
        listIndex.add(value);
      } else {
        // Other category clicked
        if (hasUnassignedSelected) {
          // If UnAssigned was selected, remove it first
          listIndex.remove(unassignedIndex);
        }

        // Toggle the selected category
        if (listIndex.contains(value)) {
          listIndex.remove(value);
        } else {
          listIndex.add(value);
        }
      }
    }
    notifyListeners();
  }

  int? stateCode;

  DashboardCount? dashboardCount;

  DD.DashboardDetail? _requestDetailList;

  DD.DashboardDetail? get requestDetailList => _requestDetailList;

  int getStatusCount(RequestTypeEnum requestType) {
    switch (requestType) {
      case RequestTypeEnum.unassigned:
        return dashboardCount?.data?.countUnAssigned ?? 0;
      case RequestTypeEnum.open:
        return dashboardCount?.data?.countOpen ?? 0;
      case RequestTypeEnum.inProgress:
        return dashboardCount?.data?.countInprogress ?? 0;
      case RequestTypeEnum.completed:
        return dashboardCount?.data?.countComplete ?? 0;
      case RequestTypeEnum.pendingAcknowledgment:
        return dashboardCount?.data?.countAcknowledge ?? 0;
      case RequestTypeEnum.canceled:
        return dashboardCount?.data?.countCanceled ?? 0;
      case RequestTypeEnum.closed:
        return dashboardCount?.data?.countClose ?? 0;
      case RequestTypeEnum.overdue:
        return dashboardCount?.data?.countOverdue ?? 0;
      case RequestTypeEnum.highPriority:
        return dashboardCount?.data?.countHighPriority ?? 0;
      default:
        return 0;
    }
  }

  List<CategoryTabs> tabs = [];

  void setTabs({required UsersTypes userType, required BuildContext context}) {
    tabs = CategoryTabs.getTabs(userType: userType, context: context);
  }

  set requestDetailList(DD.DashboardDetail? value) {
    _requestDetailList = value;
    notifyListeners();
  }

  final pageItemNumber = 10;
  int pageNum = 1;
  bool nextPage = true;

  void reset() {
    pageNum = 1;
    nextPage = true;
    stateCode = null;
    _requestDetailList = null;
    dashboardCount = null;
  }

  void refreshDashboard({required UsersTypes userType, required BuildContext context}) {
    setTabs(userType: userType, context: context);
    getDashBoardCount(usersType: userType);
    resetRequestDataList();
    if (listIndex.isEmpty) {
      Provider.of<AllRequestsProvider>(context, listen: false)
        ..reset()
        ..getAllRequests(context);
    } else if (listIndex.length == 1 && isUnassignedTab(listIndex[0])) {
      // UnAssigned only - check by requestType, not by index
      getRequestDetail(usersType: userType, status: tabs[listIndex[0]].tag, tabId: tabs[listIndex[0]].id);
    } else {
      // Multiple categories selected
      getMultiSelectCategoryRequests(usersType: userType, context: context);
    }
    // notifyListeners();
  }

  void resetRequestDataList() {
    pageNum = 1;
    nextPage = true;
    stateCode = null;
    _requestDetailList = null;
  }

  void getAllRequests(UsersTypes userTypes) {
    getDashBoardCount(usersType: userTypes);
    // getRequestDetail(usersType: userTypes);
  }

  Future<int> getDashBoardCount({required UsersTypes usersType}) async {
    isAllCountLoading = true;
    notifyListeners();
    String url = '';

    // if (usersType == UsersTypes.qualityUser) {
    //   url = URLs.qaAuditorCount;
    // } else if (usersType == UsersTypes.engineer || usersType == UsersTypes.assessor || usersType == UsersTypes.assessorTl) {
    //   url = URLs.engineerDashboardCountUrl;
    // } else {
    //   url = URLs.nurseDashboardCountUrl;
    // }
    final urlMap = {
      UsersTypes.qualityUser: URLs.qaAuditorCount,
      UsersTypes.commissioningEngineer: URLs.commissioningEngineerCount,
      UsersTypes.engineer: URLs.engineerDashboardCountUrl,
      UsersTypes.houseKeeper: URLs.engineerDashboardCountUrl,
      UsersTypes.assessor: URLs.engineerDashboardCountUrl,
      UsersTypes.assessorTl: URLs.engineerDashboardCountUrl,
    };
    url = urlMap[usersType] ?? URLs.nurseDashboardCountUrl;
    Response response;
    try {
      response = await ApiManager.instance.post(url, body: {});
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        dashboardCount = DashboardCount.fromJson(json.decode(response.body));
      }

      isAllCountLoading = false;
      notifyListeners();
      return response.statusCode;
    } catch (error) {
      isAllCountLoading = false;
      stateCode = -1;
      notifyListeners();
      return -1;
    }
  }

  Future<int> getWorkOrderById(int id) async {
    isLoading = true;
    notifyListeners();
    Response response;
    try {
      response = await ApiManager.instance.get(URLs.getWorkOrderByIdUrl + "?workOrderId=$id");

      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        dashboardCount = DashboardCount.fromJson(json.decode(response.body));
      }

      isAllCountLoading = false;
      notifyListeners();
      return response.statusCode;
    } catch (error) {
      isAllCountLoading = false;
      stateCode = -1;
      notifyListeners();
      return -1;
    }
  }

  void getHighPriorityRequests({bool showLoader = true, required UsersTypes usersType}) {
    getRequestDetail(
      showLoader: showLoader,
      usersType: usersType,
      isHighPriority: true,
    );
  }

  void getOverdueRequests({bool showLoader = true, required UsersTypes usersType}) {
    getRequestDetail(showLoader: showLoader, usersType: usersType, isOverdue: true);
  }

  void getOpenRequests({bool showLoader = true, required UsersTypes usersType}) {
    getRequestDetail(showLoader: showLoader, usersType: usersType, status: 1);
  }

  void getInProgressRequests({bool showLoader = true, required UsersTypes usersType}) {
    getRequestDetail(showLoader: showLoader, usersType: usersType, status: 2);
  }

  void getCompletedRequests({bool showLoader = true, required UsersTypes usersType}) {
    getRequestDetail(showLoader: showLoader, usersType: usersType, status: 3);
  }

  void getAcknowledgeRequests({bool showLoader = true, required UsersTypes usersType}) {
    getRequestDetail(showLoader: showLoader, usersType: usersType, status: 3);
  }

  void getClosedRequests({bool showLoader = true, required UsersTypes usersType}) {
    getRequestDetail(showLoader: showLoader, usersType: usersType, status: 4);
  }

  void getMultiSelectCategoryRequests({
    bool showLoader = true,
    required UsersTypes usersType,
    required BuildContext context,
    bool? isAscending,
  }) {
    // Build filter arrays based on selected tabs
    List<int> statusTransaction = [];
    List<int> priority = [];
    List<int> displayData = [];

    for (int index in listIndex) {
      if (index >= 0 && index < tabs.length) {
        CategoryTabs tab = tabs[index];

        // High Priority
        if (tab.isHighPriority) {
          if (!priority.contains(1)) priority.add(1);
        }

        // Overdue
        if (tab.isOverDue) {
          if (!displayData.contains(1)) displayData.add(1);
        }

        // Status categories (Open, InProgress, Completed, Closed)
        if (!tab.isHighPriority && !tab.isOverDue && tab.requestType != RequestTypeEnum.unassigned) {
          // Map requestType to status value
          switch (tab.requestType) {
            case RequestTypeEnum.open:
              if (!statusTransaction.contains(1)) statusTransaction.add(1);
              break;
            case RequestTypeEnum.inProgress:
              if (!statusTransaction.contains(2)) statusTransaction.add(2);
              break;
            case RequestTypeEnum.completed:
              if (!statusTransaction.contains(4)) statusTransaction.add(4);
              break;
            case RequestTypeEnum.closed:
              if (!statusTransaction.contains(4)) statusTransaction.add(4);
              break;
            case RequestTypeEnum.canceled:
              if (!statusTransaction.contains(5)) statusTransaction.add(5);
              break;
            case RequestTypeEnum.pendingAcknowledgment:
              if (!statusTransaction.contains(4)) statusTransaction.add(4);
              break;
            case RequestTypeEnum.unassigned:
            case RequestTypeEnum.highPriority:
            case RequestTypeEnum.overdue:
              // These are handled separately above
              break;
          }
        }
      }
    }

    // Call the multi-filter API
    Provider.of<AllRequestsProvider>(context, listen: false).getDashboardMultifilterRequests(
      context,
      pagination: false,
      statusTransaction: statusTransaction,
      priority: priority,
      displayData: displayData,
      isAscending: isAscending,
    );
  }

  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());

      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        swipeResponse = SwipeModel.fromJson(json.decode(response.body));
      }

      isAllCountLoading = false;
      notifyListeners();
      return swipeResponse;
    } catch (error) {
      isAllCountLoading = false;
      stateCode = -1;
      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);

      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {}

      isAllCountLoading = false;
      notifyListeners();
      return response.statusCode;
    } catch (error) {
      isAllCountLoading = false;
      stateCode = -1;
      notifyListeners();
      return -1;
    }
  }

  String getDashboardUrl({required UsersTypes usersType, int? status, int? tabId}) {
    switch (usersType) {
      case UsersTypes.qualityUser:
        return URLs.qaAuditorDetails;
      case UsersTypes.commissioningEngineer:
        return URLs.commissioningEngineerDetails;
      case UsersTypes.engineer:
      case UsersTypes.assessor:
      case UsersTypes.assessorTl:
      case UsersTypes.houseKeeper:
        if (status == 0) {
          return URLs.engineerDashboardUpcoming;
        } else if (status == 1 && tabId == 1) {
          return URLs.engineerDashboardNotAssignDetails;
        } else {
          // status == 1 && tabId == 2 OR any other case
          return URLs.engineerDashboardDetailsUrl;
        }
      default:
        return URLs.nurseDashboardDetailsUrl;
    }
  }

  Future<int> getRequestDetail(
      {bool showLoader = true, required UsersTypes usersType, int? status, bool isHighPriority = false, bool isOverdue = false, String? date, int? tabId, bool? isAscending}) async {
    if (showLoader) {
      isDetailLoading = showLoader;
      notifyListeners();
    }

    Response response;
    String url = '';
    // if (usersType == UsersTypes.qualityUser) {
    //   url = URLs.qaAuditorDetails;
    // } else if (usersType == UsersTypes.engineer || usersType == UsersTypes.assessor || usersType == UsersTypes.assessorTl) {
    //   //need to check pagination for not assigned task @waseem.
    //
    //   //these checks are to call different apis for dashboard for engineer...
    //   if (status == 0) {
    //     url = URLs.engineerDashboardUpcoming;
    //   } else if (status == 1 && tabId == 1) {
    //     url = URLs.engineerDashboardNotAssignDetails;
    //   } else if (status == 1 && tabId == 2) {
    //     url = URLs.engineerDashboardDetailsUrl;
    //   } else {
    //     url = URLs.engineerDashboardDetailsUrl;
    //   }
    // } else {
    //   url = URLs.nurseDashboardDetailsUrl;
    // }
    url = getDashboardUrl(usersType: usersType, status: status, tabId: tabId);

    try {
      Map<String, dynamic> body = {"pageNumber": pageNum, "pageSize": pageItemNumber};

      if (status != null && status == 0) {
        body["date"] = date ?? upcomingFilterSelectedDate.toIso8601String();
      } else if (status == 1 && tabId == 1) {
      } else {
        body["statusValue"] = status;
      }
      if (isHighPriority) {
        body["isHighPriority"] = true;
        body["statusValue"] = null;
      }
      if (isOverdue) {
        body["isOverdue"] = true;
        body["statusValue"] = null;
      }
      if (isAscending != null) body["isAscending"] = isAscending;
      response = await ApiManager.instance.post(url, body: body);
      stateCode = response.statusCode;

      if (response.statusCode >= 200 && response.statusCode < 300) {
        if (_requestDetailList == null) {
          _requestDetailList = DD.DashboardDetail.fromJson(json.decode(response.body));
        } else {
          _requestDetailList!.data!.addAll(DD.DashboardDetail.fromJson(json.decode(response.body)).data ?? []);
        }
        if (_requestDetailList!.data!.length >= pageItemNumber) {
          nextPage = true;
        } else {
          nextPage = false;
        }
      } else {
        requestDetailList = null;
      }
      if (showLoader) {
        isDetailLoading = false;
      }
      notifyListeners();
      return response.statusCode;
    } catch (error) {
      if (showLoader) {
        isDetailLoading = false;
      }
      stateCode = -1;
      notifyListeners();
      return -1;
    }
  }

  // Future<int> getDashboardEngineerUpcoming({bool showLoader = true, required  String date}) async {
  //   if (showLoader) {
  //     isDetailLoading = showLoader;
  //     notifyListeners();
  //   }
  //
  //
  //   Response response;
  //
  //   try {
  //     Map<String, dynamic> body = {"pageNumber": pageNum, "pageSize": pageItemNumber};
  //     response = await ApiManager.instance.post(URLs.engineerDashboardNotAssignDetails, body: body);
  //     stateCode = response.statusCode;
  //     if (response.statusCode >= 200 && response.statusCode < 300) {
  //       if (_requestDetailList == null) {
  //         _requestDetailList = DD.DashboardDetail.fromJson(json.decode(response.body));
  //       } else {
  //         _requestDetailList!.data!.addAll(DD.DashboardDetail.fromJson(json.decode(response.body)).data ?? []);
  //       }
  //       if (_requestDetailList!.data!.length >= pageItemNumber) {
  //         nextPage = true;
  //       } else {
  //         nextPage = false;
  //       }
  //     } else {
  //       requestDetailList = null;
  //     }
  //     if (showLoader) {
  //       isDetailLoading = false;
  //     }
  //     notifyListeners();
  //     return response.statusCode;
  //   } catch (error) {
  //     if (showLoader) {
  //       isDetailLoading = false;
  //     }
  //     stateCode = -1;
  //     notifyListeners();
  //     return -1;
  //   }
  // }

  bool get isDetailLoading => _isDetailLoading;

  set isDetailLoading(bool value) {
    _isDetailLoading = value;
    notifyListeners();
  }
}

class CategoryTabs {
  String label;
  int tag;
  int id;
  RequestTypeEnum requestType;
  String icon;
  Color iconColor;
  bool isHighPriority;
  bool isOverDue;

  CategoryTabs({this.isHighPriority = false, this.isOverDue = false, required this.label, required this.tag, required this.id, required this.requestType, required this.icon, required this.iconColor});

  static List<CategoryTabs> getTabs({required UsersTypes userType, required BuildContext context}) {
    List<CategoryTabs> tabs = [];
    if (userType == UsersTypes.engineer) {
      // Order: 1-UnAssigned, 2-HighPriority, 3-Overdue, 4-Open, 5-InProgress, 6-Completed
      tabs.add(CategoryTabs(label: 'UnAssigned', tag: 1, id: 1, requestType: RequestTypeEnum.unassigned, icon: "dashboard/unassigned", iconColor: AppColor.unassignedStatus(context)));
      tabs.add(CategoryTabs(label: context.translation.highPriority, tag: 3, id: 4, requestType: RequestTypeEnum.highPriority, icon: "high_priority", iconColor: AppColor.red30, isHighPriority: true));
      tabs.add(CategoryTabs(label: context.translation.overdue, tag: 3, id: 4, requestType: RequestTypeEnum.overdue, icon: "overdue", iconColor: AppColor.yellowIcon(context), isOverDue: true));
      tabs.add(CategoryTabs(label: 'Open', tag: 1, id: 2, requestType: RequestTypeEnum.open, icon: "dashboard/open_icon", iconColor: AppColor.openColor));
      tabs.add(CategoryTabs(label: 'In Progress', tag: 2, id: 3, requestType: RequestTypeEnum.inProgress, icon: "dashboard/inprogress_icon", iconColor: AppColor.primary10));
      tabs.add(CategoryTabs(label: 'Completed', tag: 3, id: 4, requestType: RequestTypeEnum.completed, icon: "complete_request", iconColor: AppColor.completedColor));

      return tabs;
    }
    if (userType == UsersTypes.houseKeeper) {
      // tabs.add(CategoryTabs(label: 'Upcoming', tag: 0, id: 0));
      // tabs.add(CategoryTabs('Open', 1));
      // tabs.add(CategoryTabs(label: 'UnAssigned', tag: 1, id: 1));
      // tabs.add(CategoryTabs(label: 'In Progress', tag: 2, id: 2));
      // tabs.add(CategoryTabs(label: 'Completed', tag: 4, id: 3));

      tabs.add(CategoryTabs(label: 'In Progress', tag: 2, id: 2, requestType: RequestTypeEnum.inProgress, icon: "dashboard/inprogress_icon", iconColor: AppColor.primary10));
      tabs.add(CategoryTabs(label: 'Completed', tag: 4, id: 3, requestType: RequestTypeEnum.completed, icon: "complete_request", iconColor: AppColor.completedColor));
      return tabs;
    }

    if (userType == UsersTypes.qualityUser) {
      tabs.add(CategoryTabs(label: 'Open', tag: 1, id: 2, requestType: RequestTypeEnum.open, icon: "dashboard/open_icon", iconColor: AppColor.openColor));
      tabs.add(CategoryTabs(label: 'In Progress', tag: 2, id: 3, requestType: RequestTypeEnum.inProgress, icon: "dashboard/inprogress_icon", iconColor: AppColor.primary10));
      tabs.add(CategoryTabs(label: 'Closed', tag: 3, id: 4, requestType: RequestTypeEnum.closed, icon: "complete_request", iconColor: AppColor.completedColor));
      return tabs;
    }
    if (userType == UsersTypes.commissioningEngineer) {
      tabs.add(CategoryTabs(label: 'Open', tag: 1, id: 2, requestType: RequestTypeEnum.open, icon: "dashboard/open_icon", iconColor: AppColor.openColor));
      tabs.add(CategoryTabs(label: 'In Progress', tag: 2, id: 3, requestType: RequestTypeEnum.inProgress, icon: "dashboard/inprogress_icon", iconColor: AppColor.primary10));
      tabs.add(CategoryTabs(label: 'Closed', tag: 3, id: 4, requestType: RequestTypeEnum.closed, icon: "complete_request", iconColor: AppColor.completedColor));
      return tabs;
    }

    tabs.add(CategoryTabs(label: 'Open', tag: 1, id: 2, requestType: RequestTypeEnum.open, icon: "dashboard/open_icon", iconColor: AppColor.openColor));
    tabs.add(CategoryTabs(label: 'In Progress', tag: 2, id: 3, requestType: RequestTypeEnum.inProgress, icon: "dashboard/inprogress_icon", iconColor: AppColor.primary10));
    // tabs.add(CategoryTabs(label: 'Pending Acknowledgement', tag: 3, id: 1, requestType: RequestTypeEnum.pendingAcknowledgment, icon: "complete_request", iconColor: AppColor.overdueColor));
    tabs.add(CategoryTabs(label: 'Acknowledgement', tag: 4, id: 1, requestType: RequestTypeEnum.pendingAcknowledgment, icon: "complete_request", iconColor: AppColor.overdueColor));
    tabs.add(CategoryTabs(label: 'Canceled', tag: 6, id: 4, requestType: RequestTypeEnum.canceled, icon: "dashboard/unassigned", iconColor: AppColor.red30));
    return tabs;
  }
}
