import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart';
import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart';
import 'package:diplomaticquarterapp/models/Appointments/FreeSlot.dart';
import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart';
import 'package:diplomaticquarterapp/models/Appointments/timeSlot.dart';
import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart';
import 'package:diplomaticquarterapp/models/CovidDriveThru/CovidTestProceduresResponse.dart';
import 'package:diplomaticquarterapp/models/CovidDriveThru/DriveThroughTestingCenterModel.dart';
import 'package:diplomaticquarterapp/pages/Covid-DriveThru/covid-payment-alert.dart';
import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart';
import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart';
import 'package:diplomaticquarterapp/services/covid-drivethru/covid-drivethru.dart';
import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart';
import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:syncfusion_flutter_calendar/calendar.dart';

class CovidTimeSlots extends StatefulWidget {
  int? projectID;
  static bool areSlotsAvailable = false;
  static DateTime? selectedAppoDateTime;
  static String? selectedDate;
  static String? selectedTime;
  CovidTestProceduresResponse? selectedProcedure;
  DriveThroughTestingCenterModel? selectedProject;

  int? selectedClinicID;
  int? selectedDoctorID;

  var language;

  PatientShareResponse? patientShareResponse;

  CovidTimeSlots({required this.projectID, required this.selectedProcedure, required this.selectedProject});

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

class _CovidTimeSlotsState extends State<CovidTimeSlots> with TickerProviderStateMixin {
  late Map<DateTime, List> _events;
  late AnimationController _animationController;
  late CalendarController _calendarController;

  AppSharedPreferences sharedPref = new AppSharedPreferences();

  var selectedDate = "";
  dynamic selectedDateJSON;
  dynamic jsonFreeSlots;

  List<TimeSlot> docFreeSlots = [];
  List<TimeSlot> dayEvents = [];

  int selectedButtonIndex = 0;

  dynamic freeSlotsResponse;

  late ScrollController _scrollController;

  late ToDoCountProviderModel toDoProvider;
  late ProjectViewModel projectViewModel;

  @override
  void initState() {
    final _selectedDay = DateTime.now();

    widget.patientShareResponse = new PatientShareResponse();

    _scrollController = new ScrollController();

    _events = {
      _selectedDay: ['Event A0']
    };

    WidgetsBinding.instance.addPostFrameCallback((_) => getCovidFreeSlots(context, widget.projectID!));

    _calendarController = CalendarController();
    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 50),
    );

    _animationController.forward();
    super.initState();
  }

  @override
  void dispose() {
    _animationController.dispose();
    _calendarController.dispose();
    super.dispose();
  }

  void _onDaySelected(DateTime day, ProjectViewModel projectViewModel) {
    final DateFormat formatter = DateFormat('yyyy-MM-dd');
    setState(() {
      this.selectedDate = DateUtil.getWeekDayMonthDayYearDateFormatted(day, projectViewModel.isArabic ? "ar" : "en");
      openTimeSlotsPickerForDate(day, docFreeSlots);
      CovidTimeSlots.selectedDate = formatter.format(day);
      _calendarController.selectedDate = day;
      print(CovidTimeSlots.selectedDate);
    });
  }

  @override
  Widget build(BuildContext context) {
    projectViewModel = Provider.of(context);
    toDoProvider = Provider.of<ToDoCountProviderModel>(context);
    return AppScaffold(
      appBarTitle: TranslationBase.of(context).covidTest,
      isShowAppBar: true,
      showNewAppBar: true,
      showNewAppBarTitle: true,
      backgroundColor: CustomColors.appBackgroudGrey2Color,
      body: Column(
        children: [
          Expanded(
            child: SingleChildScrollView(
              child: Container(
                margin: EdgeInsets.fromLTRB(15.0, 15.0, 15.0, 0.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Container(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        mainAxisSize: MainAxisSize.max,
                        children: <Widget>[
                          Text(
                            TranslationBase.of(context).selectAppo,
                            style: TextStyle(
                              color: Colors.black,
                              fontSize: 16.0,
                              letterSpacing: -0.64,
                              fontWeight: FontWeight.w600,
                            ),
                          ),
                          mHeight(12),
                          Container(
                            decoration: cardRadius(12),
                            child: _buildTableCalendarWithBuilders(projectViewModel),
                          ),
                          mHeight(12),
                          Text(
                            selectedDate,
                            style: TextStyle(
                              fontSize: 16.0,
                              fontWeight: FontWeight.bold,
                              letterSpacing: -0.64,
                            ),
                          ),
                          mHeight(8),
                          CovidTimeSlots.areSlotsAvailable
                              ? Container(
                                  height: 40,
                                  child: ListView.builder(
                                    controller: _scrollController,
                                    scrollDirection: Axis.horizontal,
                                    itemCount: dayEvents.length,
                                    itemBuilder: (context, index) {
                                      return Container(
                                        margin: EdgeInsets.only(right: (index == dayEvents.length - 1) ? 0 : 5.0, left: index == 0 ? 0 : 5),
                                        child: ButtonTheme(
                                            shape: RoundedRectangleBorder(
                                              borderRadius: BorderRadius.circular(5.0),
                                              side: BorderSide(
                                                color: index == selectedButtonIndex ? CustomColors.green : Colors.black, //Color of the border
                                                style: BorderStyle.solid, //Style of the border
                                                width: 1.5, //width of the border
                                              ),
                                            ),
                                            minWidth: MediaQuery.of(context).size.width * 0.2,
                                            child: index == selectedButtonIndex ? getSelectedButton(index) : getNormalButton(index)),
                                      );
                                    },
                                  ),
                                )
                              : Center(
                                  child: Padding(
                                  padding: const EdgeInsets.only(left: 12.0, right: 12.0),
                                  child: Text(TranslationBase.of(context).noSlotsError, style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: CustomColors.grey)),
                                )),
                        ],
                      ),
                    ),
                    SizedBox(
                      height: 100.0,
                    ),
                  ],
                ),
              ),
            ),
          ),
          Container(
            margin: EdgeInsets.zero,
            decoration: cardRadius(0),
            child: Container(
              width: double.infinity,
              padding: EdgeInsets.all(12),
              child: ButtonTheme(
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(10.0),
                ),
                minWidth: MediaQuery.of(context).size.width * 0.7,
                height: 45.0,
                child: CustomTextButton(
                  backgroundColor: CustomColors.green,
                  elevation: 0,
                  onPressed: () {
                    bookCovidTestAppointment();
                  },
                  child: Text(
                    TranslationBase.of(context).bookAppo,
                    style: TextStyle(fontSize: 16.0, letterSpacing: -0.64, color: Colors.white),
                  ),
                ),
              ),
            ),
          )
        ],
      ),
    );
  }

  Widget _buildTableCalendarWithBuilders(ProjectViewModel projectViewModel) {
    return SfCalendar(
      controller: _calendarController,
      minDate: DateTime.now(),
      showNavigationArrow: true,
      headerStyle: CalendarHeaderStyle(textAlign: TextAlign.center, textStyle: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600, letterSpacing: -0.46)),
      viewHeaderStyle: ViewHeaderStyle(dayTextStyle: TextStyle(fontSize: 12.0, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: CustomColors.black)),
      view: CalendarView.month,
      todayHighlightColor: CustomColors.green,
      selectionDecoration: containerColorRadiusBorderWidthCircular(Colors.transparent, 4, CustomColors.green, 2.5),
      cellBorderColor: Colors.white,
      dataSource: MeetingDataSource(_getDataSource()),
      monthViewSettings: const MonthViewSettings(appointmentDisplayMode: MonthAppointmentDisplayMode.indicator, showTrailingAndLeadingDates: false, appointmentDisplayCount: 1),
      onTap: (CalendarTapDetails details) {
        _calendarController.selectedDate = details.date;
        _onDaySelected(details.date!, projectViewModel);
      },
    );
  }

  List<Meeting> _getDataSource() {
    final List<Meeting> meetings = <Meeting>[];
    _events.forEach((key, value) {
      final DateTime startTime = DateTime(key.year, key.month, key.day, 9, 0, 0);
      final DateTime endTime = startTime.add(const Duration(minutes: 20));
      meetings.add(Meeting("", startTime, endTime, CustomColors.green, false, ""));
    });
    return meetings;
  }

  openTimeSlotsPickerForDate(DateTime dateStart, List<TimeSlot> freeSlots) {
    dayEvents.clear();
    DateTime dateStartObj = new DateTime(dateStart.year, dateStart.month, dateStart.day, 0, 0, 0, 0, 0);

    freeSlots.forEach((v) {
      if (v.start == dateStartObj) dayEvents.add(v);
    });

    setState(() {
      if (dayEvents.length != 0) {
        CovidTimeSlots.areSlotsAvailable = true;
        selectedButtonIndex = 0;
        CovidTimeSlots.selectedTime = dayEvents[selectedButtonIndex].isoTime;
      } else
        CovidTimeSlots.areSlotsAvailable = false;
    });
  }

  Future<Map<DateTime, List>> _getJSONSlots() async {
    Map<DateTime, List> _eventsParsed;
    List<FreeSlot> slotsList = [];
    DateTime date;
    final DateFormat formatter = DateFormat('HH:mm');
    final DateFormat dateFormatter = DateFormat('yyyy-MM-dd');
    for (var i = 0; i < freeSlotsResponse.length; i++) {
      date = DateUtil.convertStringToDate(freeSlotsResponse[i]['FreeTimeSlots']);
      slotsList.add(FreeSlot(date, ['slot']));
      docFreeSlots.add(TimeSlot(isoTime: formatter.format(date), start: new DateTime(date.year, date.month, date.day, 0, 0, 0, 0), end: date));
    }
    _eventsParsed = Map.fromIterable(slotsList, key: (e) => e.slot, value: (e) => e.event);
    setState(() {
      CovidTimeSlots.selectedDate = dateFormatter.format(DateUtil.convertStringToDate(freeSlotsResponse[0]['FreeTimeSlots']));
      selectedDate = DateUtil.getMonthDayYearDateFormatted(DateUtil.convertStringToDate(freeSlotsResponse[0]['FreeTimeSlots']));
      selectedDateJSON = freeSlotsResponse[0]['FreeTimeSlots'];
    });
    openTimeSlotsPickerForDate(DateUtil.convertStringToDate(selectedDateJSON), docFreeSlots);
    _calendarController.selectedDate = DateUtil.convertStringToDate(selectedDateJSON);
    return _eventsParsed;
  }

  // Widget _buildEventsMarker(DateTime date, List events) {
  //   return Container(
  //     // decoration: BoxDecoration(
  //     //   shape: BoxShape.circle,
  //     //   color: _calendarController.isSelected(date)
  //     //       ? Colors.green[400]
  //     //       : _calendarController.isToday(date)
  //     //           ? Colors.brown[300]
  //     //           : Colors.blue[400],
  //     // ),
  //
  //     decoration: containerColorRadiusBorderWidth(
  //         _calendarController.isSelected(date)
  //             ? CustomColors.green
  //             : _calendarController.isToday(date)
  //             ? CustomColors.green.withOpacity(0.5)
  //             : Colors.white,
  //         200,
  //         _calendarController.isSelected(date) ? CustomColors.green : Colors.black,
  //         2),
  //     width: 40.0,
  //     height: 40.0,
  //     child: Center(
  //       child: Text(
  //         '${date.day}',
  //         style: TextStyle().copyWith(
  //           color: _calendarController.isSelected(date) ? Colors.white : Colors.black,
  //           fontSize: 13.0,
  //         ),
  //       ),
  //     ),
  //   );
  // }

  Widget getNormalButton(int index) {
    return CustomTextButton(
      backgroundColor: Colors.white,
      elevation: 0,
      onPressed: () {
        setState(() {
          selectedButtonIndex = index;
          CovidTimeSlots.selectedTime = dayEvents[index].isoTime;
          print(CovidTimeSlots.selectedTime);
        });
      },
      child: Text(dayEvents[index].isoTime!, style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.bold, color: Color(0xFF60686b))),
    );
  }

  Widget getSelectedButton(int index) {
    return CustomTextButton(
      backgroundColor: CustomColors.green,
      elevation: 0,
      onPressed: () {
        setState(() {
          selectedButtonIndex = index;
          CovidTimeSlots.selectedTime = dayEvents[index].isoTime;
          print(CovidTimeSlots.selectedTime);
        });
      },
      child: Text(dayEvents[index].isoTime!, style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.bold, color: Color(0xFF60686b))),
    );
  }

  bookCovidTestAppointment() {
    if (CovidTimeSlots.areSlotsAvailable) {
      var messageEn = "This Appointment is being booked for patient " +
          projectViewModel.authenticatedUserObject.user!.firstName! +
          " " +
          projectViewModel.authenticatedUserObject.user!.lastName! +
          ", Having file number " +
          projectViewModel.authenticatedUserObject.user!.patientID.toString() +
          ". Please confirm!";
      var messageAr = "يتم حجز هذا الموعد المراجع " +
          projectViewModel.authenticatedUserObject.user!.firstName! +
          " " +
          projectViewModel.authenticatedUserObject.user!.lastName! +
          ", وجود رقم الملف " +
          projectViewModel.authenticatedUserObject.user!.patientID.toString() +
          ". يرجى تأكيد!";
      ConfirmDialog dialog = new ConfirmDialog(
          context: context,
          confirmMessage: projectViewModel.isArabic ? messageAr : messageEn,
          okText: TranslationBase.of(context).confirm,
          cancelText: TranslationBase.of(context).cancel_nocaps,
          okFunction: () {
            GifLoaderDialogUtils.showMyDialog(context);
            DoctorList docObject = new DoctorList();
            docObject.doctorID = widget.selectedDoctorID;
            docObject.clinicID = widget.selectedClinicID;
            docObject.projectID = widget.projectID;
            insertCovidQuestionnaire(context, docObject);
          },
          cancelFunction: () => {});
      dialog.showAlertDialog(context);
    } else {
      AppToast.showErrorToast(message: TranslationBase.of(context).selectSlot);
    }
  }

  insertCovidQuestionnaire(context, DoctorList docObject) async {
    DoctorsListService service = new DoctorsListService();
    List qa = await sharedPref.getObject(COVID_QA_LIST);
    service.insertCovidQuestionnaire(qa, widget.projectID!, widget.selectedProject!.testTypeEnum!, projectViewModel.isArabic ? 1 : 2, widget.selectedProject!.testProcedureEnum!).then((res) {
      insertAppointmentCovidTest(context, docObject);
    }).catchError((err) {
      print(err);
    });
  }

  updateCovidQuestionnaire(context, String appoNo) async {
    DoctorsListService service = new DoctorsListService();
    service.updateCovidQuestionnaire(appoNo, widget.projectID!, widget.selectedProject!.testTypeEnum!, widget.selectedProject!.testProcedureEnum!).then((res) {}).catchError((err) {
      print(err);
    });
  }

  insertAppointmentCovidTest(context, DoctorList docObject) {
    DoctorsListService service = new DoctorsListService();
    AppoitmentAllHistoryResultList appo;
    service
        .insertAppointment(docObject.doctorID!, docObject.clinicID!, docObject.projectID!, CovidTimeSlots.selectedTime!, CovidTimeSlots.selectedDate!, 0, projectViewModel.isArabic ? 1 : 2, context,
            widget.selectedProcedure!.procedureID!, widget.selectedProject!.testTypeEnum!, widget.selectedProject!.testProcedureEnum)
        .then((res) {
      if (res['MessageStatus'] == 1) {
        AppToast.showSuccessToast(message: TranslationBase.of(context).bookedSuccess);
        getToDoCount();
        getPatientShare(context, res['AppointmentNo'], docObject.clinicID!, docObject.projectID!, docObject);
      } else {
        GifLoaderDialogUtils.hideDialog(context);
        appo = new AppoitmentAllHistoryResultList();
        appo.appointmentNo = res['SameClinicApptList'][0]['AppointmentNo'];
        appo.clinicID = res['SameClinicApptList'][0]['DoctorID'];
        appo.projectID = res['SameClinicApptList'][0]['ProjectID'];
        appo.endTime = res['SameClinicApptList'][0]['EndTime'];
        appo.startTime = res['SameClinicApptList'][0]['StartTime'];
        appo.doctorID = res['SameClinicApptList'][0]['DoctorID'];
        appo.isLiveCareAppointment = false;
        appo.originalClinicID = 0;
        appo.originalProjectID = 0;
        appo.appointmentDate = res['SameClinicApptList'][0]['AppointmentDate'];

        ConfirmDialog dialog = new ConfirmDialog(
            context: context,
            confirmMessage: res['ErrorEndUserMessage'],
            okText: TranslationBase.of(context).confirm,
            cancelText: TranslationBase.of(context).cancel_nocaps,
            okFunction: () => {cancelAppointment(docObject, appo, context)},
            cancelFunction: () => {});
        dialog.showAlertDialog(context);
      }
    }).catchError((err) {
      AppToast.showErrorToast(message: err);
      GifLoaderDialogUtils.hideDialog(context);
      print(err);
    });
  }

  getToDoCount() {
    toDoProvider.setState(0, 0, true, toDoProvider.notificationsCount);
    ClinicListService service = new ClinicListService();
    service.getActiveAppointmentNo(context).then((res) {
      print(res['AppointmentActiveNumber']);
      if (res['MessageStatus'] == 1) {
        toDoProvider.setState(res['AppointmentActiveNumber'], res['AncillaryOrderListCount'], true, toDoProvider.notificationsCount);
        // toDoProvider.setState(res['AppointmentActiveNumber'], true, toDoProvider.notificationsCount);
      } else {}
    }).catchError((err) {
      print(err);
    });
  }

  cancelAppointment(DoctorList docObject, AppoitmentAllHistoryResultList appo, BuildContext context) {
    ConfirmDialog.closeAlertDialog(context);
    GifLoaderDialogUtils.showMyDialog(context);
    DoctorsListService service = new DoctorsListService();
    service.cancelAppointment(appo, context).then((res) {
      if (res['MessageStatus'] == 1) {
        // Future.delayed(new Duration(milliseconds: 1500), () {
        insertAppointmentCovidTest(context, docObject);
        // });
      } else {
        GifLoaderDialogUtils.hideDialog(context);
        AppToast.showErrorToast(message: res['ErrorEndUserMessage']);
      }
    }).catchError((err) {
      print(err);
    });
  }

  getPatientShare(context, String appointmentNo, int clinicID, int projectID, DoctorList docObject) {
    int languageID = projectViewModel.isArabic ? 1 : 2;
    DoctorsListService service = new DoctorsListService();
    service.getPatientShare(appointmentNo, clinicID, projectID, languageID, context).then((res) {
      GifLoaderDialogUtils.hideDialog(context);
        res = res['OnlineCheckInAppointments'][0];
      widget.patientShareResponse =  PatientShareResponse.fromJson(res);
      updateCovidQuestionnaire(context, appointmentNo);
      navigateToPaymentAlert();
    }).catchError((err) {
      GifLoaderDialogUtils.hideDialog(context);
      print(err);
    });
  }

  navigateToPaymentAlert() {
    Navigator.push(
      context,
      FadePage(
        page: CovidPaymentAlert(patientShareResponse: widget.patientShareResponse!),
      ),
    );
  }

  getCovidFreeSlots(BuildContext context, int projectID) {
    CovidDriveThruService service = new CovidDriveThruService();
    GifLoaderDialogUtils.showMyDialog(context);
    service.getCovidFreeSlots(context, projectID, widget.selectedProject!.testTypeEnum!, widget.selectedProject!.testProcedureEnum!).then((res) {
      GifLoaderDialogUtils.hideDialog(context);
      if (res['MessageStatus'] == 1) {
        if (res['COVID19_FreeTimeSlots'].length != 0) {
          freeSlotsResponse = res['COVID19_FreeTimeSlots'];
          _getJSONSlots().then((value) => {
                setState(() => {widget.selectedClinicID = freeSlotsResponse[0]['ClinicID'], widget.selectedDoctorID = freeSlotsResponse[0]['DoctorID'], _events.clear(), _events = value})
              });
        } else {}
      } else {
        GifLoaderDialogUtils.hideDialog(context);
        AppToast.showErrorToast(message: res['ErrorEndUserMessage']);
      }
    }).catchError((err) {
      GifLoaderDialogUtils.hideDialog(context);
      AppToast.showErrorToast(message: err.toString());
      print(err);
    });
  }
}

class MeetingDataSource extends CalendarDataSource {
  MeetingDataSource(List<Meeting> source) {
    appointments = source;
  }

  @override
  DateTime getStartTime(int index) {
    return _getMeetingData(index)!.from;
  }

  @override
  DateTime getEndTime(int index) {
    return _getMeetingData(index)!.to;
  }

  @override
  String getSubject(int index) {
    return _getMeetingData(index)!.eventName;
  }

  @override
  Color getColor(int index) {
    return _getMeetingData(index)!.background;
  }

  @override
  bool isAllDay(int index) {
    return _getMeetingData(index)!.isAllDay;
  }

  Meeting? _getMeetingData(int index) {
    final dynamic meeting = appointments![index];
    Meeting? meetingData;
    if (meeting is Meeting) {
      meetingData = meeting;
    }
    return meetingData;
  }
}

class Meeting {
  Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay, this.notes);

  String eventName;
  DateTime from;
  DateTime to;
  Color background;
  bool isAllDay;
  String notes;
}
