import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:patient_manager/components/medicineSearch.dart';
import 'package:patient_manager/components/inputsAndButtons/mihDropdownInput.dart';
import 'package:patient_manager/components/popUpMessages/mihLoadingCircle.dart';
import 'package:patient_manager/components/popUpMessages/mihErrorMessage.dart';
import 'package:patient_manager/components/inputsAndButtons/mihSearchInput.dart';
import 'package:patient_manager/components/inputsAndButtons/mihButton.dart';
import 'package:patient_manager/components/popUpMessages/mihSuccessMessage.dart';
import 'package:patient_manager/env/env.dart';
import 'package:patient_manager/main.dart';
import 'package:patient_manager/objects/appUser.dart';
import 'package:patient_manager/objects/arguments.dart';
import 'package:patient_manager/objects/business.dart';
import 'package:patient_manager/objects/businessUser.dart';
import 'package:patient_manager/objects/patients.dart';
import 'package:patient_manager/objects/perscription.dart';
import 'package:supertokens_flutter/http.dart' as http;

class PrescripInput extends StatefulWidget {
  final TextEditingController medicineController;
  final TextEditingController quantityController;
  final TextEditingController dosageController;
  final TextEditingController timesDailyController;
  final TextEditingController noDaysController;
  final TextEditingController noRepeatsController;
  final TextEditingController outputController;
  final Patient selectedPatient;
  final AppUser signedInUser;
  final Business? business;
  final BusinessUser? businessUser;
  const PrescripInput({
    super.key,
    required this.medicineController,
    required this.quantityController,
    required this.dosageController,
    required this.timesDailyController,
    required this.noDaysController,
    required this.noRepeatsController,
    required this.outputController,
    required this.selectedPatient,
    required this.signedInUser,
    required this.business,
    required this.businessUser,
  });

  @override
  State<PrescripInput> createState() => _PrescripInputState();
}

class _PrescripInputState extends State<PrescripInput> {
  final FocusNode _focusNode = FocusNode();
  List<Perscription> perscriptionObjOutput = [];
  late double width;
  late double height;

  final numberOptions = [
    "0",
    "1",
    "2",
    "3",
    "4",
    "5",
    "6",
    "7",
    "8",
    "9",
    "10",
    "11",
    "12",
    "13",
    "14",
    "15",
    "16",
    "17",
    "18",
    "19",
    "20",
    "21",
    "22",
    "23",
    "24",
    "25",
    "26",
    "27",
    "28",
    "29",
    "30"
  ];

  Future<void> generatePerscription() async {
    //start loading circle
    showDialog(
      context: context,
      builder: (context) {
        return const Mihloadingcircle();
      },
    );

    var response1 = await http.post(
      Uri.parse("${AppEnviroment.baseApiUrl}/minio/generate/perscription/"),
      headers: <String, String>{
        "Content-Type": "application/json; charset=UTF-8"
      },
      body: jsonEncode(<String, dynamic>{
        "app_id": widget.selectedPatient.app_id,
        "fullName":
            "${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}",
        "id_no": widget.selectedPatient.id_no,
        "docfname":
            "DR. ${widget.signedInUser.fname} ${widget.signedInUser.lname}",
        "busName": widget.business!.Name,
        "busAddr": "*TO BE ADDED IN THE FUTURE*",
        "busNo": widget.business!.contact_no,
        "busEmail": widget.business!.bus_email,
        "logo_path": widget.business!.logo_path,
        "sig_path": widget.businessUser!.sig_path,
        "data": perscriptionObjOutput,
      }),
    );
    //print(response1.statusCode);
    DateTime now = new DateTime.now();
    DateTime date = new DateTime(now.year, now.month, now.day);
    String fileName =
        "Perscription-${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}-${date.toString().substring(0, 10)}.pdf";
    if (response1.statusCode == 200) {
      var response2 = await http.post(
        Uri.parse("${AppEnviroment.baseApiUrl}/files/insert/"),
        headers: <String, String>{
          "Content-Type": "application/json; charset=UTF-8"
        },
        body: jsonEncode(<String, dynamic>{
          "file_path":
              "${widget.selectedPatient.app_id}/patient_files/$fileName",
          "file_name": fileName,
          "app_id": widget.selectedPatient.app_id
        }),
      );
      //print(response2.statusCode);
      if (response2.statusCode == 201) {
        setState(() {
          //To do
          widget.medicineController.clear();
          widget.dosageController.clear();
          widget.timesDailyController.clear();
          widget.noDaysController.clear();
          widget.timesDailyController.clear();
          widget.noRepeatsController.clear();
          widget.quantityController.clear();
          widget.outputController.clear();
          // futueFiles = fetchFiles();
        });
        // end loading circle
        Navigator.of(context).pop();
        Navigator.of(context).pop();
        Navigator.of(context).pushNamed('/patient-manager/patient',
            arguments: PatientViewArguments(
              widget.signedInUser,
              widget.selectedPatient,
              widget.businessUser,
              widget.business,
              "business",
            ));
        String message =
            "The perscription $fileName has been successfully generated and added to ${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}'s record. You can now access and download it for their use.";
        successPopUp(message);
      } else {
        internetConnectionPopUp();
      }
    } else {
      internetConnectionPopUp();
    }
  }

  void internetConnectionPopUp() {
    showDialog(
      context: context,
      builder: (context) {
        return const MIHErrorMessage(errorType: "Internet Connection");
      },
    );
  }

  void successPopUp(String message) {
    showDialog(
      context: context,
      builder: (context) {
        return MIHSuccessMessage(
          successType: "Success",
          successMessage: message,
        );
      },
    );
  }

  void getMedsPopUp(TextEditingController medSearch) {
    showDialog(
      context: context,
      builder: (context) {
        return MedicineSearch(
          searchVlaue: medSearch,
        );
      },
    );
  }

  bool isFieldsFilled() {
    if (widget.medicineController.text.isEmpty ||
        // widget.quantityController.text.isEmpty ||
        widget.dosageController.text.isEmpty ||
        widget.timesDailyController.text.isEmpty ||
        widget.noDaysController.text.isEmpty ||
        widget.noRepeatsController.text.isEmpty) {
      return false;
    } else {
      return true;
    }
  }

  void updatePerscriptionList() {
    String name;
    String unit;
    String form;
    List<String> medNameList = widget.medicineController.text.split("%t");
    if (medNameList.length == 1) {
      name = medNameList[0];
      unit = "";
      form = "";
    } else {
      name = medNameList[0];
      unit = medNameList[1];
      form = medNameList[2];
    }
    int quantityCalc = calcQuantity(
        widget.dosageController.text,
        widget.timesDailyController.text,
        widget.noDaysController.text,
        medNameList[2].toLowerCase());
    Perscription tempObj = Perscription(
      name: name,
      unit: unit,
      form: form,
      fullForm: getFullDoagesForm(form),
      quantity: "$quantityCalc",
      dosage: widget.dosageController.text,
      times: widget.timesDailyController.text,
      days: widget.noDaysController.text,
      repeats: widget.noRepeatsController.text,
    );
    perscriptionObjOutput.add(tempObj);
  }

  String getPerscTitle(int index) {
    return "${perscriptionObjOutput[index].name} - ${perscriptionObjOutput[index].form}";
  }

  String getPerscSubtitle(int index) {
    if (perscriptionObjOutput[index].form.toLowerCase() == "syr") {
      String unit = perscriptionObjOutput[index].unit.toLowerCase();
      if (perscriptionObjOutput[index].unit.toLowerCase().contains("ml")) {
        unit = "ml";
      }
      return "${perscriptionObjOutput[index].dosage} $unit, ${perscriptionObjOutput[index].times} time(s) daily, for ${perscriptionObjOutput[index].days} day(s)\nQuantity: ${perscriptionObjOutput[index].quantity}\nNo. of repeats: ${perscriptionObjOutput[index].repeats}";
    } else {
      return "${perscriptionObjOutput[index].dosage} ${perscriptionObjOutput[index].fullForm}(s), ${perscriptionObjOutput[index].times} time(s) daily, for ${perscriptionObjOutput[index].days} day(s)\nQuantity: ${perscriptionObjOutput[index].quantity}\nNo. of repeats: ${perscriptionObjOutput[index].repeats}";
    }
  }

  String getFullDoagesForm(String abr) {
    var dosageFormList = {
      "liq": "liquid",
      "tab": "tablet",
      "cap": "capsule",
      "cps": "capsule",
      "oin": "ointment",
      "lit": "lotion",
      "lot": "lotion",
      "inj": "injection",
      "syr": "syrup",
      "dsp": "effervescent tablet",
      "eft": "effervescent tablet",
      "ear": "drops",
      "drp": "drops",
      "opd": "drops",
      "udv": "vial",
      "sus": "suspension",
      "susp": "suspension",
      "cal": "calasthetic",
      "sol": "solution",
      "sln": "solution",
      "neb": "nebuliser",
      "inh": "inhaler",
      "spo": "inhaler",
      "inf": "infusion",
      "chg": "chewing Gum",
      "vac": "vacutainer",
      "vag": "vaginal gel",
      "jel": "gel",
      "eyo": "eye ointment",
      "vat": "vaginal cream",
      "poi": "injection",
      "ped": "powder",
      "pow": "powder",
      "por": "powder",
      "sac": "sachet",
      "sup": "suppository",
      "cre": "cream",
      "ptd": "patch",
      "ect": "tablet",
      "nas": "spray",
    };
    String form;
    if (dosageFormList[abr.toLowerCase()] == null) {
      form = abr;
    } else {
      form = dosageFormList[abr.toLowerCase()]!;
    }
    return form;
  }

  int calcQuantity(String dosage, String times, String days, String form) {
    var dosageFormList = [
      "tab",
      "cap",
      "cps",
      "dsp",
      "eft",
      "udv",
      "chg",
      "sac",
      "sup",
      "ptd",
      "ect",
    ];
    if (dosageFormList.contains(form)) {
      return int.parse(dosage) * int.parse(times) * int.parse(days);
    } else {
      return 1;
    }
  }

  Widget displayMedInput() {
    return Column(
      children: [
        KeyboardListener(
          focusNode: _focusNode,
          autofocus: true,
          onKeyEvent: (event) async {
            if (event is KeyDownEvent &&
                event.logicalKey == LogicalKeyboardKey.enter) {
              getMedsPopUp(widget.medicineController);
            }
          },
          child: SizedBox(
            width: 300,
            child: MIHSearchField(
              controller: widget.medicineController,
              hintText: "Medicine",
              required: true,
              editable: true,
              onTap: () {
                getMedsPopUp(widget.medicineController);
              },
            ),
          ),
        ),
        const SizedBox(height: 10.0),
        // SizedBox(
        //   width: 300,
        //   child: MIHDropdownField(
        //     controller: widget.quantityController,
        //     hintText: "Quantity",
        //     dropdownOptions: numberOptions,
        //     required: true,
        //     editable: true,
        //   ),
        // ),
        // const SizedBox(height: 10.0),
        SizedBox(
          width: 300,
          child: MIHDropdownField(
            controller: widget.dosageController,
            hintText: "Dosage",
            dropdownOptions: numberOptions,
            required: true,
            editable: true,
          ),
        ),
        const SizedBox(height: 10.0),
        SizedBox(
          width: 300,
          child: MIHDropdownField(
            controller: widget.timesDailyController,
            hintText: "Times Daily",
            dropdownOptions: numberOptions,
            required: true,
            editable: true,
          ),
        ),
        const SizedBox(height: 10.0),
        SizedBox(
          width: 300,
          child: MIHDropdownField(
            controller: widget.noDaysController,
            hintText: "No. Days",
            dropdownOptions: numberOptions,
            required: true,
            editable: true,
          ),
        ),
        const SizedBox(height: 10.0),
        SizedBox(
          width: 300,
          child: MIHDropdownField(
            controller: widget.noRepeatsController,
            hintText: "No. Repeats",
            dropdownOptions: numberOptions,
            required: true,
            editable: true,
          ),
        ),
        const SizedBox(height: 30.0),
        SizedBox(
          width: 300,
          height: 50,
          child: MIHButton(
            buttonText: "Add",
            buttonColor:
                MzanziInnovationHub.of(context)!.theme.secondaryColor(),
            textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
            onTap: () {
              if (isFieldsFilled()) {
                // int quantity;
                // int.parse(widget.dosageController.text) *
                //     int.parse(widget.timesDailyController.text) *
                //     int.parse(widget.noDaysController.text);
                setState(() {
                  //widget.quantityController.text = "$quantity";
                  updatePerscriptionList();
                  widget.medicineController.clear();
                  widget.quantityController.clear();
                  widget.dosageController.clear();
                  widget.timesDailyController.clear();
                  widget.noDaysController.clear();
                  widget.noRepeatsController.clear();
                });

                //addPatientAPICall();
              } else {
                showDialog(
                  context: context,
                  builder: (context) {
                    return const MIHErrorMessage(errorType: "Input Error");
                  },
                );
              }
            },
          ),
        )
      ],
    );
  }

  Widget displayPerscList() {
    return Column(
      children: [
        Container(
          width: 550,
          height: 350,
          decoration: BoxDecoration(
            color: MzanziInnovationHub.of(context)!.theme.primaryColor(),
            borderRadius: BorderRadius.circular(25.0),
            border: Border.all(
                color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
                width: 3.0),
          ),
          child: ListView.separated(
            separatorBuilder: (BuildContext context, int index) {
              return const Padding(
                padding: EdgeInsets.symmetric(horizontal: 10.0),
                child: Divider(),
              );
            },
            itemCount: perscriptionObjOutput.length,
            itemBuilder: (context, index) {
              //final patient = widget.patients[index].id_no.contains(widget.searchString);
              return ListTile(
                title: Text(
                  getPerscTitle(index),
                  style: TextStyle(
                    color:
                        MzanziInnovationHub.of(context)!.theme.secondaryColor(),
                  ),
                ),
                subtitle: Text(
                  getPerscSubtitle(index),
                  style: TextStyle(
                    color:
                        MzanziInnovationHub.of(context)!.theme.secondaryColor(),
                  ),
                ),
                //onTap: () {},
                trailing: IconButton(
                  icon: Icon(
                    Icons.delete_forever_outlined,
                    color:
                        MzanziInnovationHub.of(context)!.theme.secondaryColor(),
                  ),
                  onPressed: () {
                    setState(() {
                      perscriptionObjOutput.removeAt(index);
                    });
                  },
                ),
              );
            },
          ),
        ),
        const SizedBox(height: 30.0),
        SizedBox(
          width: 300,
          height: 50,
          child: MIHButton(
            onTap: () async {
              if (perscriptionObjOutput.isNotEmpty) {
                //print(jsonEncode(perscriptionObjOutput));
                await generatePerscription();
                Navigator.pop(context);
              } else {
                showDialog(
                  context: context,
                  builder: (context) {
                    return const MIHErrorMessage(errorType: "Input Error");
                  },
                );
              }
            },
            buttonText: "Generate",
            buttonColor: MzanziInnovationHub.of(context)!.theme.successColor(),
            textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
          ),
        )
      ],
    );
  }

  @override
  void dispose() {
    _focusNode.dispose();
    super.dispose();
  }

  @override
  void initState() {
    //futueMeds = getMedList(endpointMeds);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    var size = MediaQuery.of(context).size;
    setState(() {
      width = size.width;
      height = size.height;
    });
    return Container(
      //width: ,
      height: (height / 3) * 1.5,
      child: SingleChildScrollView(
        child: Wrap(
          direction: Axis.horizontal,
          alignment: WrapAlignment.center,
          spacing: 10,
          runSpacing: 10,
          // mainAxisAlignment: MainAxisAlignment.center,
          // mainAxisSize: MainAxisSize.max,
          // crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            displayMedInput(),
            displayPerscList(),
          ],
        ),
      ),
    );
  }
}
