import 'package:doctor_app_flutter/config/config.dart';
import 'package:doctor_app_flutter/config/shared_pref_kay.dart';
import 'package:doctor_app_flutter/config/size_config.dart';
import 'package:doctor_app_flutter/core/enum/master_lookup_key.dart';
import 'package:doctor_app_flutter/core/enum/view_state.dart';
import 'package:doctor_app_flutter/core/model/SOAP/master_key_model.dart';
import 'package:doctor_app_flutter/core/model/SOAP/physical_exam/post_physical_exam_request_model.dart';
import 'package:doctor_app_flutter/core/model/SOAP/selected_items/my_selected_examination.dart';
import 'package:doctor_app_flutter/core/model/doctor/doctor_profile_model.dart';
import 'package:doctor_app_flutter/core/model/patient/patiant_info_model.dart';
import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart';
import 'package:doctor_app_flutter/screens/base/base_view.dart';
import 'package:doctor_app_flutter/screens/patients/profile/soap_update/soap_utils.dart';
import 'package:doctor_app_flutter/utils/translations_delegate_base_utils.dart';
import 'package:doctor_app_flutter/utils/utils.dart';
import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart';
import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart';
import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart';
import 'package:flutter/material.dart';

import '../shared_soap_widgets/SOAP_open_items.dart';
import '../shared_soap_widgets/SOAP_step_header.dart';
import '../shared_soap_widgets/expandable_SOAP_widget.dart';
import 'add_examination_page.dart';
import 'examination_item_card.dart';
import 'objective_call_back.dart';

class UpdateObjectivePage extends StatefulWidget {
  final Function changePageViewIndex;
  final Function changeLoadingState;
  final int currentIndex;
  final PatiantInformtion patientInfo;

  UpdateObjectivePage({Key? key, required this.changePageViewIndex, required this.patientInfo, required this.changeLoadingState, required this.currentIndex});

  @override
  _UpdateObjectivePageState createState() => _UpdateObjectivePageState();
}

class _UpdateObjectivePageState extends State<UpdateObjectivePage> implements ObjectiveCallBack {
  bool isSysExaminationExpand = false;
  List<MySelectedExamination> mySelectedExamination = [];

  BoxDecoration containerBorderDecoration(Color containerColor, Color borderColor) {
    return BoxDecoration(
      color: containerColor,
      shape: BoxShape.rectangle,
      borderRadius: BorderRadius.all(Radius.circular(6)),
      border: Border.fromBorderSide(BorderSide(
        color: borderColor,
        width: 0.5,
      )),
    );
  }

  @override
  Widget build(BuildContext context) {
    return BaseView<SOAPViewModel>(
      onModelReady: (model) async {
        WidgetsBinding.instance.addPostFrameCallback((_) async {
        model.setObjectiveCallBack(this);
        mySelectedExamination.clear();
        model.isAddExamInProgress = true;

        await model.getPatientPhysicalExam(widget.patientInfo);
        if (model.patientPhysicalExamList.isNotEmpty) {
          if (model.physicalExaminationList.length == 0) {
            await model.getMasterLookup(MasterKeysService.PhysicalExamination);
          }
          model.patientPhysicalExamList.forEach((element) {
            MasterKeyModel? examMaster = model.getOneMasterKey(
              masterKeys: MasterKeysService.PhysicalExamination,
              id: element.examId,
            );
            MySelectedExamination tempEam = SoapUtils.generateMySelectedExamination(
              examination: examMaster,
              remark: element.remarks,
              isNormal: element.isNormal,
              createdBy: element.createdBy,
              createdOn: element.createdOn,
              editedOn: element.editedOn,
              notExamined: element.notExamined,
              isNew: element.isNew,
              isLocal: false,
              isAbnormal: element.isAbnormal,
            );
            mySelectedExamination.add(tempEam);
          });
        }
        widget.changeLoadingState(false);});
      },
      builder: (_, model, w) => AppScaffold(
        isShowAppBar: false,
        backgroundColor: Theme.of(context).scaffoldBackgroundColor,
        body: SingleChildScrollView(
          physics: ScrollPhysics(),
          child: Center(
            child: FractionallySizedBox(
              widthFactor: 0.9,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.start,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  SOAPStepHeader(
                    currentIndex: widget.currentIndex,
                    changePageViewIndex: widget.changePageViewIndex,
                    patientInfo: widget.patientInfo,
                  ),
                  ExpandableSOAPWidget(
                    headerTitle: TranslationBase.of(context).physicalSystemExamination,
                    onTap: () {
                      setState(() {
                        isSysExaminationExpand = !isSysExaminationExpand;
                      });
                    },
                    child: Column(
                      children: [
                        SOAPOpenItems(
                          label: "${TranslationBase.of(context).addExamination}",
                          onTap: () {
                            openExaminationList(context);
                          },
                        ),
                        if (mySelectedExamination.isNotEmpty && mySelectedExamination.first.isLocal)
                          Row(
                            children: [
                              AppText(
                                "New",
                                fontWeight: FontWeight.w600,
                                fontFamily: 'Poppins',
                                color: Color(0xFFCC9B14),
                              ),
                            ],
                          ),
                        Column(
                          children: mySelectedExamination
                              .sublist(0, model.getFirstIndexForOldExamination(mySelectedExamination) == -1 ? 0 : model.getFirstIndexForOldExamination(mySelectedExamination))
                              .map((examination) {
                            return ExaminationItemCard(examination, () {
                              removeExamination(examination.selectedExamination!);
                            });
                          }).toList(),
                        ),
                        if (mySelectedExamination.isNotEmpty && model.getFirstIndexForOldExamination(mySelectedExamination) > -1)
                          Row(
                            children: [
                              AppText(
                                "Verified",
                                fontWeight: FontWeight.w600,
                                fontFamily: 'Poppins',
                                color: AppGlobal.appGreenColor,
                              ),
                            ],
                          ),
                        Column(
                          children: mySelectedExamination
                              .sublist(model.getFirstIndexForOldExamination(mySelectedExamination) == -1 ? 0 : model.getFirstIndexForOldExamination(mySelectedExamination))
                              .map((examination) {
                            return ExaminationItemCard(examination, () {
                              removeExamination(examination.selectedExamination!);
                            });
                          }).toList(),
                        )
                      ],
                    ),
                    isExpanded: isSysExaminationExpand,
                  ),
                  SizedBox(
                    height: SizeConfig.heightMultiplier! * (SizeConfig.isHeightVeryShort ? 14 : 12),
                  )
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

  submitUpdateObjectivePage(SOAPViewModel model) async {
    if (mySelectedExamination.isNotEmpty) {
      if (!model.isAddExamInProgress && widget.patientInfo.admissionNo != null && widget.patientInfo.admissionNo!.isNotEmpty) {
        Navigator.of(context).pop();
      } else {
        widget.changeLoadingState(true);
        Map<String, dynamic> profile = await sharedPref.getObj(DOCTOR_PROFILE);

        DoctorProfileModel doctorProfile = DoctorProfileModel.fromJson(profile);
        PostPhysicalExamRequestModel postPhysicalExamRequestModel = new PostPhysicalExamRequestModel();
        mySelectedExamination.forEach((exam) {
          if (postPhysicalExamRequestModel.listHisProgNotePhysicalExaminationVM == null) postPhysicalExamRequestModel.listHisProgNotePhysicalExaminationVM = [];
          ListHisProgNotePhysicalExaminationVM listHisProgNotePhysicalExaminationVM = ListHisProgNotePhysicalExaminationVM(
            patientMRN: widget.patientInfo.patientMRN,
            episodeId: widget.patientInfo.episodeNo == null ? 0 : widget.patientInfo.episodeNo,
            appointmentNo: widget.patientInfo.appointmentNo == null ? 0 : widget.patientInfo.appointmentNo,
            remarks: exam.remark ?? '',
            createdBy: exam.createdBy ?? doctorProfile.doctorID,
            createdOn: exam.createdOn ?? DateTime.now().toIso8601String(),
            editedBy: doctorProfile.doctorID,
            editedOn: DateTime.now().toIso8601String(),
            examId: exam.selectedExamination!.id,
            examType: exam.selectedExamination!.typeId,
            isAbnormal: exam.isAbnormal,
            isNormal: exam.isNormal,
            notExamined: exam.notExamined,
            examinationType: exam.isNormal
                ? 1
                : exam.isAbnormal
                    ? 2
                    : 3,
            examinationTypeName: exam.isNormal
                ? "Normal"
                : exam.isAbnormal
                    ? 'AbNormal'
                    : "Not Examined",
            isNew: exam.isNew,
          );
          if (widget.patientInfo.admissionNo != null && widget.patientInfo.admissionNo!.isNotEmpty) {
            listHisProgNotePhysicalExaminationVM.admissionNo = int.parse(widget.patientInfo.admissionNo!);
          } else {
            listHisProgNotePhysicalExaminationVM.admissionNo = 0;
          }
          postPhysicalExamRequestModel.listHisProgNotePhysicalExaminationVM!.add(listHisProgNotePhysicalExaminationVM);
        });

        if (model.patientPhysicalExamList.isEmpty) {
          await model.postPhysicalExam(postPhysicalExamRequestModel);
        } else {
          await model.patchPhysicalExam(postPhysicalExamRequestModel);
        }

        if (model.state == ViewState.ErrorLocal) {
          widget.changeLoadingState(false);
          Utils.showErrorToast(model.error);
          if (widget.patientInfo.admissionNo != null && widget.patientInfo.admissionNo!.isNotEmpty) {
            // Navigator.of(context).pop();
            model.isAddExamInProgress = false;
          }
        } else {
          if (widget.patientInfo.admissionNo != null && widget.patientInfo.admissionNo!.isNotEmpty) {
            // Navigator.of(context).pop();
            widget.changeLoadingState(false);
            model.isAddExamInProgress = false;
          } else {
            widget.changeLoadingState(true);
            widget.changePageViewIndex(2);
          }
        }
      }
    } else {
      Utils.showErrorToast(TranslationBase.of(context).examinationErrorMsg);
    }
  }

  removeExamination(MasterKeyModel masterKey) {
    Iterable<MySelectedExamination> history = mySelectedExamination.where((element) => masterKey.id == element.selectedExamination!.id && masterKey.typeId == element.selectedExamination!.typeId);

    if (history.length > 0) {
      setState(() {
        if (history.first.isLocal) {
          mySelectedExamination.remove(history.first);
        } else {
          history.first.notExamined = true;
          history.first.isNormal = false;
          history.first.isAbnormal = false;
        }
      });
    }
  }

  openExaminationList(BuildContext context) {
    Navigator.push(
      context,
      FadePage(
        page: AddExaminationPage(
            mySelectedExamination: mySelectedExamination,
            addSelectedExamination: (List<MySelectedExamination> mySelectedExaminationLocal) {
              mySelectedExaminationLocal.forEach((element) {
                if (mySelectedExamination.singleWhere((it) => it.selectedExamination!.id == element.selectedExamination!.id, orElse: () => MySelectedExamination()) == MySelectedExamination()) {
                  mySelectedExamination.insert(0, element);
                }
              });

              /// remove items.
              List<MySelectedExamination> removedList = [];
              mySelectedExamination.forEach((element) {
                if (mySelectedExaminationLocal.singleWhere((it) => it.selectedExamination!.id == element.selectedExamination!.id, orElse: () => MySelectedExamination()) == MySelectedExamination()) {
                  removedList.add(element);
                }
              });

              removedList.forEach((element) {
                removeExamination(element.selectedExamination!);
              });
              Navigator.of(context).pop();
              setState(() {});
            },
            removeExamination: (masterKey) => removeExamination(masterKey)),
      ),
    );
  }

  @override
  nextFunction(model) async {
    await submitUpdateObjectivePage(model);
  }
}
