import 'package:doctor_app_flutter/core/enum/view_state.dart';
import 'package:doctor_app_flutter/core/model/sick_leave/sick_leave_patient_model.dart';
import 'package:doctor_app_flutter/core/service/patient/patient_service.dart';
import 'package:doctor_app_flutter/core/service/patient_medical_file/sick_leave/sickleave_service.dart';
import 'package:doctor_app_flutter/core/model/patient/patiant_info_model.dart';
import 'package:doctor_app_flutter/core/model/sickleave/add_sickleave_request.dart';
import 'package:doctor_app_flutter/core/model/sickleave/get_all_sickleave_response.dart';
import 'package:doctor_app_flutter/core/model/sickleave/sick_leave_statisitics_model.dart';

import '../../locator.dart';
import 'base_view_model.dart';

class SickLeaveViewModel extends BaseViewModel {
  SickLeaveService _sickLeaveService = locator<SickLeaveService>();
  PatientService _patientService = locator<PatientService>();

  SickLeaveStatisticsModel get sickLeaveStatistics => _sickLeaveService.sickLeavestatisitics;

  get getAllSIckLeave => _sickLeaveService.getAllSickLeave;

  List get allOffTime => _sickLeaveService.getOffTimeList;

  List get allReasons => _sickLeaveService.getReasons;

  List get coveringDoctors => _sickLeaveService.coveringDoctorsList;

  List get sickLeaveDoctor => _sickLeaveService.getAllSickLeaveDoctor;

  get getReschduleLeave => _sickLeaveService.getAllRescheduleLeave;

  get postSechedule => _sickLeaveService.postReschedule;

  get getAllSIckLeavePatient => removeDuplicates([..._sickLeaveService.getAllSickLeaveDoctor, ..._sickLeaveService.getAllSickLeavePatient]);

  Future addSickLeave(AddSickLeaveRequest addSickLeaveRequest) async {
    setState(ViewState.BusyLocal);
    await _sickLeaveService.addSickLeave(addSickLeaveRequest);
    if (_sickLeaveService.hasError) {
      error = _sickLeaveService.error;
      setState(ViewState.ErrorLocal);
    } else
      setState(ViewState.Idle);
  }

  Future extendSickLeave(GetAllSickLeaveResponse extendSickLeaveRequest) async {
    setState(ViewState.BusyLocal);
    await _sickLeaveService.extendSickLeave(extendSickLeaveRequest);
    if (_sickLeaveService.hasError) {
      error = _sickLeaveService.error;
      setState(ViewState.ErrorLocal);
    } else
      setState(ViewState.Idle);
  }

  Future preSickLeaveStatistics(appoNo, patientMRN) async {
    setState(ViewState.Busy);
    await _sickLeaveService.getStatistics(appoNo, patientMRN);
    if (_sickLeaveService.hasError) {
      error = _sickLeaveService.error;
      setState(ViewState.Error);
    } else
      setState(ViewState.Idle);
  }

  Future getSickLeave(patientMRN) async {
    setState(ViewState.Busy);
    await _sickLeaveService.getSickLeave(patientMRN);
    if (_sickLeaveService.hasError) {
      error = _sickLeaveService.error;
      setState(ViewState.Error);
    } else
      setState(ViewState.Idle);
  }

  Future getSickLeavePatient(patientMRN, {bool isLocalBusy = false}) async {
    if (isLocalBusy)
      setState(ViewState.BusyLocal);
    else
      setState(ViewState.Busy);
    await _sickLeaveService.getSickLeavePatient(patientMRN);
    if (_sickLeaveService.hasError) {
      error = _sickLeaveService.error;
      setState(ViewState.ErrorLocal);
    } else
      setState(ViewState.Idle);
  }

  Future getSickLeaveForPatient(PatiantInformtion patient, {bool isLocalBusy = false}) async {
    if (isLocalBusy)
      setState(ViewState.BusyLocal);
    else
      setState(ViewState.Busy);
    var patientMRN = patient.patientMRN ?? patient.patientId;
    var services = [_sickLeaveService.getSickLeavePatient(patientMRN), _sickLeaveService.getSickLeaveDoctor(patientMRN)];

    final results = await Future.wait(services);
    if (_sickLeaveService.hasError) {
      error = _sickLeaveService.error;
      // if (isLocalBusy)
      setState(ViewState.ErrorLocal);
      // else
      //   setState(ViewState.Error);

    } else
      setState(ViewState.Idle);
  }

  Future getSickLeaveDoctor(patientMRN) async {
    setState(ViewState.Busy);
    await _sickLeaveService.getSickLeaveDoctor(patientMRN);
    if (_sickLeaveService.hasError) {
      error = _sickLeaveService.error;
      setState(ViewState.ErrorLocal);
    } else
      setState(ViewState.Idle);
  }

  Future getRescheduleLeave() async {
    setState(ViewState.Busy);
    await _sickLeaveService.getRescheduleLeave();
    if (_sickLeaveService.hasError) {
      error = _sickLeaveService.error;
      setState(ViewState.Error);
    } else
      setState(ViewState.Idle);
  }

  Future getOffTime() async {
    setState(ViewState.Busy);
    await _sickLeaveService.getOffTime();
    if (_sickLeaveService.hasError) {
      error = _sickLeaveService.error;
      setState(ViewState.Error);
    } else
      setState(ViewState.Idle);
  }

  Future getReasons(id) async {
    setState(ViewState.Busy);
    await _sickLeaveService.getReasonsByID(id: id);
    if (_sickLeaveService.hasError) {
      error = _sickLeaveService.error;
      setState(ViewState.Error);
    } else
      setState(ViewState.Idle);
  }

  Future getCoveringDoctors() async {
    //setState(ViewState.Busy);
    await _sickLeaveService.getCoveringDoctors();
    if (_sickLeaveService.hasError) {
      error = _sickLeaveService.error;
      // setState(ViewState.Error);
    }
    //else
    // setState(ViewState.Idle);
  }

  Future addReschedule(request) async {
    setState(ViewState.Busy);
    await _sickLeaveService.addReschedule(request);

    if (_sickLeaveService.hasError) {
      error = _sickLeaveService.error;
      setState(ViewState.Error);
    } else
      setState(ViewState.Idle);
  }

  Future updateReschedule(request) async {
    setState(ViewState.Busy);
    await _sickLeaveService.updateReschedule(request);
    if (_sickLeaveService.hasError) {
      error = _sickLeaveService.error;
      setState(ViewState.Error);
    } else
      setState(ViewState.Idle);
  }

  List<SickLeavePatientModel> removeDuplicates(List<SickLeavePatientModel> items) {
    List<SickLeavePatientModel> uniqueItems = [];
    var uniqueIDs = items.map((e) => e.appointmentNo).toSet();
    uniqueIDs.forEach((e) {
      uniqueItems.add(items.firstWhere((i) => i.appointmentNo == e));
    });
    return uniqueItems;
  }
}
