import { useMutation } from "@apollo/client/react";
import { Button, Form, Modal, Space } from "antd";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { INSERT_NEW_PAYMENT, UPDATE_PAYMENT } from "../../graphql/payments.queries";
import { toggleModalVisible } from "../../redux/modals/modals.actions";
import { selectPayment } from "../../redux/modals/modals.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { GenerateDocument } from "../../utils/RenderTemplate";
import { TemplateList } from "../../utils/TemplateConstants";
import PaymentForm from "../payment-form/payment-form.component";
import PaymentMarkForExportButton from "../payment-mark-export-button/payment-mark-export-button-component";
import PaymentReexportButton from "../payment-reexport-button/payment-reexport-button.component";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";

const mapStateToProps = createStructuredSelector({
  paymentModal: selectPayment,
  bodyshop: selectBodyshop
});

const mapDispatchToProps = (dispatch) => ({
  toggleModalVisible: () => dispatch(toggleModalVisible("payment"))
});

function PaymentModalContainer({ paymentModal, toggleModalVisible, bodyshop }) {
  const [form] = Form.useForm();
  const [enterAgain, setEnterAgain] = useState(false);
  const [insertPayment] = useMutation(INSERT_NEW_PAYMENT);
  const [updatePayment] = useMutation(UPDATE_PAYMENT);
  const notification = useNotification();

  const { t } = useTranslation();
  const { context, actions, open } = paymentModal;
  const [loading, setLoading] = useState(false);

  const handleFinish = async (values) => {
    const { sendby, ...paymentObj } = values;

    setLoading(true);
    let updatedPayment; //Moved up from if statement for greater scope.
    try {
      if (!context || (context && !context.id)) {
        const newPayment = await insertPayment({
          variables: {
            paymentInput: {
              ...paymentObj
            }
          }
        });

        if (!newPayment.errors) {
          notification.success({ title: t("payments.successes.payment") });
        } else {
          notification.error({ title: t("payments.errors.payment") });
        }
        const Templates = TemplateList("payment");
        if (sendby !== "none") {
          GenerateDocument(
            {
              name: Templates.payment_receipt.key,
              variables: {
                id: newPayment.data.insert_payments.returning[0].id
              }
            },
            {
              // to: [appData.email],
              replyTo: bodyshop.email,
              subject: Templates.payment_receipt.subject
            },
            sendby === "email" ? "e" : "p",
            paymentObj.jobid,
            notification
          );
        }
      } else {
        updatedPayment = await updatePayment({
          variables: {
            paymentId: context.id,
            payment: paymentObj
          }
        });

        if (!updatedPayment.errors) {
          notification.success({ title: t("payments.successes.paymentupdate") });
        } else {
          notification.error({ title: t("payments.errors.paymentupdate") });
        }
      }

      if (actions.refetch) {
        if (context.refetchRequiresContext) {
          actions.refetch(updatedPayment && updatedPayment.data.update_payments.returning[0]);
        } else {
          actions.refetch();
        }
      }

      if (enterAgain) {
        const prev = form.getFieldsValue(["date"]);

        form.resetFields();
        form.setFieldsValue(prev);
      } else {
        toggleModalVisible();
      }
      setEnterAgain(false);
    } catch (error) {
      console.log("error", error);
    } finally {
      setEnterAgain(false);
      setLoading(false);
    }
  };

  const handleCancel = () => {
    toggleModalVisible();
  };

  useEffect(() => {
    if (open) {
      form.resetFields();
      form.resetFields();
      form.setFieldsValue(context);
    }
  }, [open, form, context]);

  useEffect(() => {
    if (enterAgain) form.submit();
  }, [enterAgain, form]);

  return (
    <Modal
      title={!context || (context && !context.id) ? t("payments.labels.new") : t("payments.labels.edit")}
      open={open}
      destroyOnHidden
      okText={t("general.actions.save")}
      onOk={() => form.submit()}
      width="50%"
      onCancel={handleCancel}
      okButtonProps={{
        loading: loading
      }}
      afterClose={() => form.resetFields()}
      footer={
        <Space>
          <Button onClick={handleCancel}>{t("general.actions.cancel")}</Button>
          <Button loading={loading} onClick={() => form.submit()}>
            {t("general.actions.save")}
          </Button>
          {paymentModal.context?.id ? null : (
            <Button
              type="primary"
              loading={loading}
              onClick={() => {
                setEnterAgain(true);
              }}
            >
              {t("general.actions.saveandnew")}
            </Button>
          )}
        </Space>
      }
    >
      {!context || (context && !context.id) ? null : (
        <Space>
          <PaymentReexportButton payment={context} refetch={actions.refetch} />
          <PaymentMarkForExportButton bodyshop={bodyshop} payment={context} refetch={actions.refetch} />
        </Space>
      )}

      <Form onFinish={handleFinish} autoComplete={"off"} form={form} layout="vertical" disabled={context?.exportedat}>
        <PaymentForm form={form} />
      </Form>
    </Modal>
  );
}

export default connect(mapStateToProps, mapDispatchToProps)(PaymentModalContainer);
