import "package:collection/collection.dart";
import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/core/viewModels/ancillary_orders_view_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart';
import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart';
import 'package:diplomaticquarterapp/models/anicllary-orders/ancillary_order_proc_model.dart';
import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart';
import 'package:diplomaticquarterapp/pages/base/base_view.dart';
import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart';
import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
import 'package:diplomaticquarterapp/widgets/dialogs/alert_dialog.dart';
import 'package:diplomaticquarterapp/widgets/dragable_sheet.dart';
import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class AnicllaryOrdersDetails extends StatefulWidget {
  final dynamic appoNo;
  final dynamic orderNo;
  final dynamic projectID;

  AnicllaryOrdersDetails(this.appoNo, this.orderNo, this.projectID);

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

class _AnicllaryOrdersState extends State<AnicllaryOrdersDetails> with SingleTickerProviderStateMixin {
  ProjectViewModel projectViewModel;
  bool _agreeTerms = false;
  String selectedPaymentMethod;
  MyInAppBrowser browser;
  String transID = "";

  List<AncillaryOrderProcDetailsList> selectedProcList = [];

  void initState() {
    super.initState();
  }

  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    projectViewModel = Provider.of(context);
    return BaseView<AnciallryOrdersViewModel>(
      onModelReady: (model) => model.getOrdersDetails(widget.appoNo, widget.orderNo, widget.projectID),
      builder: (_, model, widget) => AppScaffold(
        isShowAppBar: true,
        showNewAppBar: true,
        showNewAppBarTitle: true,
        baseViewModel: model,
        appBarTitle: TranslationBase.of(context).anicllaryOrders,
        body: SingleChildScrollView(
          padding: EdgeInsets.all(12),
          child: model.ancillaryListsDetails.length > 0
              ? Column(children: [
                  getPatientInfo(model),
                  getAncillaryDetails(model),
                ])
              : getNoDataWidget(context),
        ),
        bottomSheet: model.ancillaryListsDetails.length > 0
            ? Container(
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)),
                  boxShadow: [
                    BoxShadow(
                      color: Colors.grey.withOpacity(0.5),
                      spreadRadius: 5,
                      blurRadius: 7,
                      offset: Offset(0, 3), // changes position of shadow
                    ),
                  ],
                ),
                padding: EdgeInsets.only(left: 21, right: 21, top: 15, bottom: 15),
                width: double.infinity,
                // color: Colors.white,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    SizedBox(height: 12),
                    Text(
                      TranslationBase.of(context).YouCanPayByTheFollowingOptions,
                      style: TextStyle(
                        fontSize: 16.0,
                        fontWeight: FontWeight.w600,
                        color: Color(0xff2B353E),
                        letterSpacing: -0.64,
                      ),
                    ),
                    SizedBox(
                      width: MediaQuery.of(context).size.width * 0.75,
                      child: getPaymentMethods(),
                    ),
                    _amountView(TranslationBase.of(context).patientShareTotalToDo, getTotalValue() + " " + TranslationBase.of(context).sar, isBold: true, isTotal: true),
                    SizedBox(height: 12),
                    DefaultButton(
                      TranslationBase.of(context).payNow.toUpperCase(),
                      selectedProcList.length > 0 && getTotalValue() != "0.00"
                          ? () {
                              makePayment();
                            }
                          : null,
                      color: CustomColors.green,
                      disabledColor: CustomColors.grey2,
                    ),
                  ],
                ),
              )
            : Container(),
      ),
    );
  }

  _getNormalText(text, {bool isBold = false, bool isTotal = false}) {
    return Text(
      text,
      style: TextStyle(
        fontSize: isBold
            ? isTotal
                ? 16
                : 12
            : 11,
        letterSpacing: -0.5,
        color: isBold ? Color(0xff2E303A) : Color(0xff575757),
        fontWeight: isTotal ? FontWeight.bold : FontWeight.w600,
      ),
    );
  }

  _amountView(String title, String value, {bool isBold = false, bool isTotal = false}) {
    return Padding(
      padding: const EdgeInsets.only(top: 10, bottom: 10),
      child: Row(children: [
        Expanded(
          child: _getNormalText(title),
        ),
        Expanded(
          child: _getNormalText(value, isBold: isBold, isTotal: isTotal),
        ),
      ]),
    );
  }

  Widget getPatientInfo(AnciallryOrdersViewModel model) {
    return Padding(
      child: Column(
        children: [
          Container(
            width: double.infinity,
            child: Container(
              decoration: cardRadius(12),
              margin: EdgeInsets.zero,
              child: Padding(
                padding: const EdgeInsets.all(12.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Row(
                      children: [
                        Text(
                          TranslationBase.of(context).patientName + ":",
                          style: TextStyle(
                            fontWeight: FontWeight.w600,
                            fontSize: 10,
                            letterSpacing: -0.6,
                            color: CustomColors.grey,
                          ),
                        ),
                        mWidth(3),
                        Text(
                          projectViewModel.user.firstName + " " + projectViewModel.user.lastName,
                          style: TextStyle(
                            fontWeight: FontWeight.w600,
                            fontSize: 12,
                            letterSpacing: -0.48,
                          ),
                        ),
                      ],
                    ),
                    Row(
                      children: [
                        Text(
                          TranslationBase.of(context).mrn + ":",
                          style: TextStyle(
                            fontWeight: FontWeight.w600,
                            fontSize: 10,
                            letterSpacing: -0.6,
                            color: CustomColors.grey,
                          ),
                        ),
                        mWidth(3),
                        Text(
                          projectViewModel.user.patientID.toString(),
                          style: TextStyle(
                            fontWeight: FontWeight.w600,
                            fontSize: 12,
                            letterSpacing: -0.48,
                          ),
                        ),
                      ],
                    ),
                    Row(
                      children: [
                        Text(
                          TranslationBase.of(context).nationalIdNumber + ":",
                          style: TextStyle(
                            fontWeight: FontWeight.w600,
                            fontSize: 10,
                            letterSpacing: -0.6,
                            color: CustomColors.grey,
                          ),
                        ),
                        mWidth(3),
                        Text(
                          projectViewModel.user.patientIdentificationNo,
                          style: TextStyle(
                            fontWeight: FontWeight.w600,
                            fontSize: 12,
                            letterSpacing: -0.48,
                          ),
                        ),
                      ],
                    ),
                    Row(
                      children: [
                        Text(
                          TranslationBase.of(context).appointmentNo + ":",
                          style: TextStyle(
                            fontWeight: FontWeight.w600,
                            fontSize: 10,
                            letterSpacing: -0.6,
                            color: CustomColors.grey,
                          ),
                        ),
                        mWidth(3),
                        Text(
                          model.ancillaryListsDetails[0].appointmentNo.toString(),
                          style: TextStyle(
                            fontWeight: FontWeight.w600,
                            fontSize: 12,
                            letterSpacing: -0.48,
                          ),
                        ),
                      ],
                    ),
                    mWidth(3),
                    Row(
                      children: [
                        Text(
                          TranslationBase.of(context).orderNo + ":",
                          style: TextStyle(
                            fontWeight: FontWeight.w600,
                            fontSize: 10,
                            letterSpacing: -0.6,
                            color: CustomColors.grey,
                          ),
                        ),
                        mWidth(3),
                        Text(
                          model.ancillaryListsDetails[0].ancillaryOrderProcDetailsList[0].orderNo.toString(),
                          style: TextStyle(
                            fontWeight: FontWeight.w600,
                            fontSize: 12,
                            letterSpacing: -0.48,
                          ),
                        ),
                      ],
                    ),
                  ],
                ),
              ),
            ),
          ),
          Divider()
        ],
      ),
      padding: EdgeInsets.only(top: 5.0, bottom: 10.0),
    );
  }

  Widget getAncillaryDetails(model) {
    Map newMap = groupBy(model.ancillaryListsDetails[0].ancillaryOrderProcDetailsList, (obj) => obj.procedureCategoryName);
    return Padding(padding: EdgeInsets.only(top: 0, bottom: 200), child: getHeaderDetails(newMap));
  }

  Widget getHeaderDetails(newMap) {
    List<Widget> list = [];
    newMap.forEach((key, value) {
      list.add(
        Container(
          child: Text(key, style: TextStyle(color: Colors.black, letterSpacing: -0.64, fontSize: 18.0, fontWeight: FontWeight.bold)),
        ),
      );
      list.add(
        Container(
          decoration: cardRadius(12),
          margin: EdgeInsets.only(left: 0, top: 8, right: 0, bottom: 16),
          child: Padding(
            padding: const EdgeInsets.all(12.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Table(
                  columnWidths: {
                    0: FlexColumnWidth(1.0),
                    1: FlexColumnWidth(2.5),
                    2: FlexColumnWidth(1.5),
                    3: FlexColumnWidth(1.5),
                    4: FlexColumnWidth(1.5),
                  },
                  children: fullData(context, value),
                ),
              ],
            ),
          ),
        ),
      );
    });

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: list,
    );
  }

  String getTotalValue() {
    double total = 0.0;
    selectedProcList.forEach((result) => {total += result.patientShareWithTax});
    return total.toStringAsFixed(2);
  }

  List<TableRow> fullData(context, value) {
    List<TableRow> tableRow = [];

    tableRow.add(
      TableRow(
        children: [
          Utils.tableColumnTitle(""),
          Utils.tableColumnTitle(TranslationBase.of(context).procedure),
          Utils.tableColumnTitle(TranslationBase.of(context).price),
          Utils.tableColumnTitle(TranslationBase.of(context).vat),
          Utils.tableColumnTitle(TranslationBase.of(context).total),
        ],
      ),
    );

    for (int i = 0; i < value.length; i++) {
      tableRow.add(
        TableRow(children: [
          Checkbox(
              value: checkIfProcedureSelected(value[i]),
              onChanged: (v) {
                setState(() {
                  addSelectedProcedure(value[i]);
                });
              }),
          Utils.tableColumnValue('${value[i].procedureName}', isLast: true, isCapitable: false, mProjectViewModel: projectViewModel),
          Utils.tableColumnValue('${value[i].patientShare.toString() + " " + TranslationBase.of(context).sar.toUpperCase()}', isLast: true, isCapitable: false, mProjectViewModel: projectViewModel),
          Utils.tableColumnValue('${value[i].patientTaxAmount.toString() + " " + TranslationBase.of(context).sar.toUpperCase()}',
              isLast: true, isCapitable: false, mProjectViewModel: projectViewModel),
          Utils.tableColumnValue('${value[i].patientShareWithTax.toString() + " " + TranslationBase.of(context).sar.toUpperCase()}',
              isLast: true, isCapitable: false, mProjectViewModel: projectViewModel),
        ]),
      );
    }
    return tableRow;
  }

  makePayment() {
    showDraggableDialog(context, PaymentMethod(
      onSelectedMethod: (String method) {
        selectedPaymentMethod = method;
        print(selectedPaymentMethod);
        openPayment(selectedPaymentMethod, projectViewModel.authenticatedUserObject.user, double.parse(getTotalValue()), null);
      },
    ));
  }

  openPayment(String paymentMethod, AuthenticatedUser authenticatedUser, double amount, AppoitmentAllHistoryResultList appo) {
    browser = new MyInAppBrowser(onExitCallback: onBrowserExit, appo: appo, onLoadStartCallback: onBrowserLoadStart);

    transID = Utils.getAdvancePaymentTransID(widget.projectID, projectViewModel.authenticatedUserObject.user.patientID);

    browser.openPaymentBrowser(
        amount,
        "Ancillary Orders Payment",
        transID,
        widget.projectID.toString(),
        projectViewModel.authenticatedUserObject.user.emailAddress,
        paymentMethod,
        projectViewModel.authenticatedUserObject.user.patientType,
        projectViewModel.authenticatedUserObject.user.firstName + " " + projectViewModel.authenticatedUserObject.user.lastName,
        projectViewModel.authenticatedUserObject.user.patientID,
        authenticatedUser,
        browser,
        false,
        "3",
        "");
  }

  onBrowserLoadStart(String url) {
    print("onBrowserLoadStart");
    print(url);

    MyInAppBrowser.successURLS.forEach((element) {
      if (url.contains(element)) {
        if (browser.isOpened()) browser.close();
        MyInAppBrowser.isPaymentDone = true;
        return;
      }
    });

    MyInAppBrowser.errorURLS.forEach((element) {
      if (url.contains(element)) {
        if (browser.isOpened()) browser.close();
        MyInAppBrowser.isPaymentDone = false;
        return;
      }
    });
  }

  onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) {
    print("onBrowserExit Called!!!!");
    if (isPaymentMade) checkPaymentStatus(appo);
  }

  checkPaymentStatus(AppoitmentAllHistoryResultList appo) {
    GifLoaderDialogUtils.showMyDialog(AppGlobal.context);
    DoctorsListService service = new DoctorsListService();
    service.checkPaymentStatus(transID, AppGlobal.context).then((res) {
      String paymentInfo = res['Response_Message'];
      if (paymentInfo == 'Success') {
        createAdvancePayment(res, appo);
      } else {
        GifLoaderDialogUtils.hideDialog(AppGlobal.context);
        AppToast.showErrorToast(message: res['Response_Message']);
      }
    }).catchError((err) {
      GifLoaderDialogUtils.hideDialog(AppGlobal.context);
      AppToast.showErrorToast(message: err);
      print(err);
    });
  }

  createAdvancePayment(res, AppoitmentAllHistoryResultList appo) {
    DoctorsListService service = new DoctorsListService();
    String paymentReference = res['Fort_id'].toString();
    service.HIS_createAdvancePayment(
            appo,
            widget.projectID.toString(),
            res['Amount'],
            res['Fort_id'],
            res['PaymentMethod'],
            projectViewModel.authenticatedUserObject.user.patientType,
            projectViewModel.authenticatedUserObject.user.firstName + " " + projectViewModel.authenticatedUserObject.user.lastName,
            projectViewModel.authenticatedUserObject.user.patientID,
            AppGlobal.context)
        .then((res) {
      addAdvancedNumberRequest(res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), paymentReference, 0, appo);
    }).catchError((err) {
      GifLoaderDialogUtils.hideDialog(AppGlobal.context);
      AppToast.showErrorToast(message: err);
      print(err);
    });
  }

  addAdvancedNumberRequest(String advanceNumber, String paymentReference, dynamic appointmentID, AppoitmentAllHistoryResultList appo) {
    DoctorsListService service = new DoctorsListService();
    service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, AppGlobal.context).then((res) {
      autoGenerateInvoice();
    }).catchError((err) {
      GifLoaderDialogUtils.hideDialog(AppGlobal.context);
      AppToast.showErrorToast(message: err.toString());
      print(err);
    });
  }

  autoGenerateInvoice() {
    List<dynamic> selectedProcListAPI = [];
    Map<dynamic, dynamic> selectedProcListAPIMap;

    selectedProcList.forEach((element) {
      selectedProcListAPI.add({
        "ApprovalLineItemNo": element.approvalLineItemNo,
        "OrderLineItemNo": element.orderLineItemNo,
        "ProcedureID": element.procedureID,
      });
    });

    DoctorsListService service = new DoctorsListService();
    service.autoGenerateAncillaryOrdersInvoice(widget.orderNo, widget.projectID, widget.appoNo, selectedProcListAPI, AppGlobal.context).then((res) {
      GifLoaderDialogUtils.hideDialog(AppGlobal.context);
      showAlertDialog(res['AncillaryOrderInvoiceList'][0]['InvoiceNo']);
    }).catchError((err) {
      GifLoaderDialogUtils.hideDialog(AppGlobal.context);
      AppToast.showErrorToast(message: err);
      print(err);
    });
  }

  showAlertDialog(dynamic invoiceNo) {
    AlertDialogBox(
        context: context,
        confirmMessage: TranslationBase.of(context).ancillaryOrderPaymentSuccess + invoiceNo.toString(),
        okText: TranslationBase.of(context).ok,
        okFunction: () {
          AlertDialogBox.closeAlertDialog(context);
          Navigator.of(context).pop();
        }).showAlertDialog(context);
  }

  bool checkIfProcedureSelected(AncillaryOrderProcDetailsList ancillaryOrderProcDetailsList) {
    if (selectedProcList.length > 0) {
      if (selectedProcList.contains(ancillaryOrderProcDetailsList)) {
        return true;
      } else {
        return false;
      }
    } else {
      return false;
    }
  }

  addSelectedProcedure(AncillaryOrderProcDetailsList ancillaryOrderProcDetailsList) {
    if (!checkIfProcedureSelected(ancillaryOrderProcDetailsList)) {
      selectedProcList.add(ancillaryOrderProcDetailsList);
    } else {
      selectedProcList.remove(ancillaryOrderProcDetailsList);
    }
  }
}
