import 'package:flutter/material.dart';
import 'package:qadirneyriz/models/meetings/meetings_location_model.dart';
import 'package:qadirneyriz/models/meetings/meetings_managers_model.dart';
import 'package:qadirneyriz/models/meetings/meetings_subjects_model.dart';
import 'package:qadirneyriz/models/meetings/meetings_users_model.dart';
import 'package:qadirneyriz/screens/meeting/diolog_meetings_filters.dart';
import 'package:qadirneyriz/setting/setting.dart';
import 'package:qadirneyriz/utils/enums/status.dart';

class GlobalState extends ChangeNotifier {
// users meetings
  Status usersStatus = Status.empty;
  List<UsersModel>? usersModel;
  Future<Status> getUsers({bool refresh = false}) async {
    usersStatus = Status.loading;
    notifyListeners();
    if (refresh) {
      usersStatus = Status.loading;
      notifyListeners();
    }

    if (usersModel != null && usersModel!.isNotEmpty) {
      usersStatus = Status.ready;
      try {
        usersModel = await setting.globalServices.getUsers();
        if (usersModel != null) {
          usersStatus = Status.ready;
        } else {
          usersStatus = Status.empty;
        }
      } catch (e) {
        usersStatus = Status.error;
        // print('$e error usersModel');
      }
      notifyListeners();
    } else {
      try {
        usersModel = await setting.globalServices.getUsers();
        if (usersModel != null) {
          usersStatus = Status.ready;
        } else {
          usersStatus = Status.empty;
        }
        notifyListeners();
      } catch (e) {
        usersStatus = Status.error;
        // print('$e error usersModel');
      }
    }
    notifyListeners();
    // print('$usersStatus usersModel');
    return usersStatus;
  }

// locations meetings
  Status locationsStatus = Status.empty;
  List<LocationsModel>? locationsModel;
  Future<Status> getLocations({bool refresh = false}) async {
    locationsStatus = Status.loading;
    notifyListeners();
    if (refresh) {
      locationsStatus = Status.loading;
      notifyListeners();
    }

    if (locationsModel != null && locationsModel!.isNotEmpty) {
      locationsStatus = Status.ready;
      try {
        locationsModel = await setting.globalServices.getLocation();
        if (locationsModel != null) {
          locationsStatus = Status.ready;
        } else {
          locationsStatus = Status.empty;
        }
      } catch (e) {
        locationsStatus = Status.error;
        // print(e);
      }
      notifyListeners();
    } else {
      try {
        locationsModel = await setting.globalServices.getLocation();
        if (locationsModel != null) {
          locationsStatus = Status.ready;
        } else {
          locationsStatus = Status.empty;
        }
        notifyListeners();
      } catch (e) {
        locationsStatus = Status.error;
        // print(e);
      }
    }
    notifyListeners();
    // print(locationsStatus);
    return locationsStatus;
  }

// subjects meetings
  Status subjectsStatus = Status.empty;

  List<SubjectsModel>? subjectsModel;
  Future<Status> getSubjects({bool refresh = false}) async {
    subjectsStatus = Status.loading;
    notifyListeners();
    if (refresh) {
      subjectsStatus = Status.loading;
      notifyListeners();
    }

    if (subjectsModel != null && subjectsModel!.isNotEmpty) {
      subjectsStatus = Status.ready;
      try {
        subjectsModel = await setting.globalServices.getSubjects();
        if (subjectsModel != null) {
          subjectsStatus = Status.ready;
        } else {
          subjectsStatus = Status.empty;
        }
      } catch (e) {
        subjectsStatus = Status.error;
        // print(e);
      }
      notifyListeners();
    } else {
      try {
        subjectsModel = await setting.globalServices.getSubjects();
        if (subjectsModel != null) {
          subjectsStatus = Status.ready;
        } else {
          subjectsStatus = Status.empty;
        }
        notifyListeners();
      } catch (e) {
        subjectsStatus = Status.error;
        // print(e);
      }
    }
    notifyListeners();
    // print(subjectsStatus);
    return subjectsStatus;
  }

//  managers meetings
  Status meetingsManagerStatus = Status.empty;

  List<MeetingsMangersModel>? meetingsManagerModel;
  Future<Status> getMeetingsManager({bool refresh = false}) async {
    meetingsManagerStatus = Status.loading;
    notifyListeners();
    if (refresh) {
      meetingsManagerStatus = Status.loading;
      notifyListeners();
    }

    if (meetingsManagerModel != null && meetingsManagerModel!.isNotEmpty) {
      meetingsManagerStatus = Status.ready;
      try {
        meetingsManagerModel = await setting.globalServices.getManagers();
        if (meetingsManagerModel != null) {
          meetingsManagerStatus = Status.ready;
        } else {
          meetingsManagerStatus = Status.empty;
        }
      } catch (e) {
        meetingsManagerStatus = Status.error;
        // print(e);
      }
      notifyListeners();
    } else {
      try {
        meetingsManagerModel = await setting.globalServices.getManagers();
        if (meetingsManagerModel != null) {
          meetingsManagerStatus = Status.ready;
        } else {
          meetingsManagerStatus = Status.empty;
        }
        notifyListeners();
      } catch (e) {
        meetingsManagerStatus = Status.error;
        // print(e);
      }
    }
    notifyListeners();
    // print(meetingsManagerStatus);
    return meetingsManagerStatus;
  }

  // load all items together
  Status allFiltersStatus = Status.empty;

  Future<Status> getAllFiltersItems({bool refresh = false}) async {
    final int role = setting.userLocalDb.getUser().role ?? -1;

    allFiltersStatus = Status.loading;
    notifyListeners();

    if (_isDataAlreadyLoaded(role) && !refresh) {
      allFiltersStatus = Status.ready;
    } else {
      allFiltersStatus = Status.loading;
    }

    notifyListeners();

    await _fetchAllData(role: role, refresh: refresh);

    _updateAllFiltersStatus(role);
    notifyListeners();

    return allFiltersStatus;
  }

  bool _isDataAlreadyLoaded(int role) {
    return locationsModel != null &&
        locationsModel!.isNotEmpty &&
        subjectsModel != null &&
        subjectsModel!.isNotEmpty &&
        (role == 1 || (usersModel != null && usersModel!.isNotEmpty)) &&
        (role == 1 ||
            (meetingsManagerModel != null && meetingsManagerModel!.isNotEmpty));
  }

  Future<void> _fetchAllData({required int role, required bool refresh}) async {
    final List<Future<void>> tasks = [
      getLocations(refresh: refresh),
      getSubjects(refresh: refresh),
    ];

    // Only add getUsers if role is not 1
    if (role != 1) {
      tasks.add(getUsers(refresh: refresh));
    }

    // Only add getMeetingsManager if role is not 1
    if (role != 1) {
      tasks.add(getMeetingsManager(refresh: refresh));
    }

    await Future.wait(tasks);
  }

  void _updateAllFiltersStatus(int role) {
    if (locationsStatus == Status.ready &&
        subjectsStatus == Status.ready &&
        (role == 1 || usersStatus == Status.ready) &&
        (role == 1 || meetingsManagerStatus == Status.ready)) {
      allFiltersStatus = Status.ready;
    } else {
      allFiltersStatus = Status.error;
    }
  }

// add new subject
  Status statusAddNewSubject = Status.empty;
  String? messageAddNewSubject;
  Map? errorsAddNewSubject;

  Future<Status> addNewSubject(
      {required String subject, required String enSubject}) async {
    statusAddNewSubject = Status.loading;
    notifyListeners();
    try {
      final result = await setting.globalServices
          .addNewSubject(subject: subject, enSubject: enSubject);
      if (result.isOk) {
        statusAddNewSubject = Status.ready;
        messageAddNewSubject = result.message;
      } else if (result.isOk == false) {
        errorsAddNewSubject = result.errors;
        messageAddNewSubject = result.message;
        statusAddNewSubject = Status.error;
      } else {
        statusAddNewSubject = Status.error;
      }
      notifyListeners();
    } catch (e) {
      statusAddNewSubject = Status.error;
    }
    notifyListeners();

    return statusAddNewSubject;
  }

// add new address

  Status statusAddNewAddress = Status.empty;
  String? messageAddNewAddress;
  Map? errorsAddNewAddress;

  Future<Status> addNewAddress(
      {required String address, required String addressEn}) async {
    statusAddNewAddress = Status.loading;
    notifyListeners();
    try {
      final result = await setting.globalServices
          .addNewLocation(address: address, addressEn: addressEn);
      if (result.isOk) {
        statusAddNewAddress = Status.ready;
        messageAddNewAddress = result.message;
      } else if (result.isOk == false) {
        errorsAddNewAddress = result.errors;
        messageAddNewAddress = result.message;
        statusAddNewAddress = Status.error;
      } else {
        statusAddNewAddress = Status.error;
      }
      notifyListeners();
    } catch (e) {
      statusAddNewAddress = Status.error;
    }
    notifyListeners();

    return statusAddNewAddress;
  }

// add new user
  Status statusAddNewUser = Status.empty;
  String? messageAddNewUser;
  Map? errorsAddNewUser;

  Future<Status> addNewUser(
      {required String name,
      required String mobile,
      required String password,
      required int role}) async {
    statusAddNewUser = Status.loading;
    notifyListeners();
    try {
      final result = await setting.globalServices.addNewUser(
          mobile: mobile, name: name, password: password, role: role);
      if (result.isOk) {
        statusAddNewUser = Status.ready;
        messageAddNewUser = result.message;
      } else if (result.isOk == false) {
        errorsAddNewUser = result.errors;
        messageAddNewUser = result.message;
        statusAddNewUser = Status.error;
      } else {
        statusAddNewUser = Status.error;
      }
      notifyListeners();
    } catch (e) {
      statusAddNewUser = Status.error;
    }
    notifyListeners();

    return statusAddNewUser;
  }
}
