import { useMutation } from "@apollo/client/react";
import { Button, Card, Form, Input, Switch } from "antd";
import queryString from "query-string";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { useLocation, useNavigate, useParams } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import { logImEXEvent } from "../../../../firebase/firebase.utils";
import { MARK_APPOINTMENT_ARRIVED, MARK_LATEST_APPOINTMENT_ARRIVED } from "../../../../graphql/appointments.queries";
import { UPDATE_JOB } from "../../../../graphql/jobs.queries";
import { insertAuditTrail } from "../../../../redux/application/application.actions";
import { selectBodyshop, selectCurrentUser } from "../../../../redux/user/user.selectors";
import AuditTrailMapping from "../../../../utils/AuditTrailMappings";
import dayjs from "../../../../utils/day";
import ConfigFormComponents from "../../../config-form-components/config-form-components.component";
import DateTimePicker from "../../../form-date-time-picker/form-date-time-picker.component";
import { useNotification } from "../../../../contexts/Notifications/notificationContext.jsx";

const mapStateToProps = createStructuredSelector({
  bodyshop: selectBodyshop,
  currentUser: selectCurrentUser
});
const mapDispatchToProps = (dispatch) => ({
  insertAuditTrail: ({ jobid, operation, type }) => dispatch(insertAuditTrail({ jobid, operation, type }))
});

export function JobChecklistForm({ insertAuditTrail, formItems, bodyshop, currentUser, type, job, readOnly = false }) {
  const { t } = useTranslation();
  const [intakeJob] = useMutation(UPDATE_JOB);
  const [loading, setLoading] = useState(false);
  const [markAptArrived] = useMutation(MARK_APPOINTMENT_ARRIVED);
  const [markLatestAptArrived] = useMutation(MARK_LATEST_APPOINTMENT_ARRIVED);
  const notification = useNotification();

  const { jobId } = useParams();
  const history = useNavigate();
  const search = queryString.parse(useLocation().search);
  const [form] = Form.useForm();

  const handleFinish = async (values) => {
    setLoading(true);
    logImEXEvent("job_complete_intake");

    const result = await intakeJob({
      variables: {
        jobId: jobId,
        job: {
          ...(type === "intake" && { inproduction: values.addToProduction }),
          status:
            (type === "intake" && bodyshop.md_ro_statuses.default_arrived) ||
            (type === "deliver" && bodyshop.md_ro_statuses.default_delivered),
          ...(type === "intake" && { actual_in: new Date() }),
          ...(type === "intake" && {
            production_vars: {
              ...(job ? job.production_vars : {}),

              note:
                values.production_vars && values.production_vars.note && values.production_vars.note !== ""
                  ? values && values.production_vars && values.production_vars.note
                  : job && job.production_vars && job.production_vars.note
            }
          }),
          ...(type === "intake" && {
            scheduled_completion: values.scheduled_completion
          }),
          ...(type === "intake" &&
            bodyshop.intakechecklist &&
            bodyshop.intakechecklist.next_contact_hours &&
            bodyshop.intakechecklist.next_contact_hours > 0 && {
              date_next_contact: dayjs().add(bodyshop.intakechecklist.next_contact_hours, "hour")
            }),
          ...(type === "deliver" && {
            actual_completion: values.actual_completion
          }),

          [(type === "intake" && "intakechecklist") || (type === "deliver" && "deliverchecklist")]: {
            ...values,
            form: formItems.map((fi) => {
              return {
                ...fi,
                value: values[fi.name]
              };
            }),
            completed_by: currentUser.email,
            completed_at: new Date()
          },

          ...(type === "intake" &&
            values.scheduled_delivery && {
              scheduled_delivery: values.scheduled_delivery
            }),
          ...(type === "deliver" && {
            scheduled_delivery: values.scheduled_delivery,
            actual_delivery: values.actual_delivery
          }),
          ...(type === "deliver" &&
            values.removeFromProduction && {
              inproduction: false
            })
        }
      }
    });
    if (search.appointmentId) {
      const appUpdate = await markAptArrived({
        variables: { appointmentId: search.appointmentId }
      });

      if (appUpdate.errors) {
        notification.error({
          title: t("checklist.errors.complete", {
            error: JSON.stringify(result.errors)
          })
        });
      }
    } else if (type === "intake" && !search.appointmentId) {
      const appUpdate = await markLatestAptArrived({
        variables: { jobId: jobId }
      });

      if (appUpdate.errors) {
        notification.error({
          title: t("checklist.errors.complete", {
            error: JSON.stringify(result.errors)
          })
        });
      }
    }

    setLoading(false);

    if (!result.errors) {
      notification.success({ title: t("checklist.successes.completed") });
      history(`/manage/jobs/${jobId}`);

      insertAuditTrail({
        jobid: jobId,
        operation: AuditTrailMapping.jobchecklist(
          type,
          // eslint-disable-next-line no-constant-binary-expression
          (type === "deliver" && values.removeFromProduction && false) || (type === "intake" && values.addToProduction),
          (type === "intake" && bodyshop.md_ro_statuses.default_arrived) ||
            (type === "deliver" && bodyshop.md_ro_statuses.default_delivered)
        ),
        type: "jobchecklist"
      });
    } else {
      notification.error({
        title: t("checklist.errors.complete", {
          error: JSON.stringify(result.errors)
        })
      });
    }
  };

  return (
    <Card
      title={t("checklist.labels.checklist")}
      extra={
        !readOnly && (
          <Button loading={loading} type="primary" onClick={() => form.submit()}>
            {t("general.actions.submit")}
          </Button>
        )
      }
    >
      <Form
        form={form}
        onFinish={handleFinish}
        initialValues={{
          ...(type === "intake" && {
            addToProduction: true,
            scheduled_completion:
              (job && job.scheduled_completion && dayjs(job.scheduled_completion)) ||
              (job &&
                job.labhrs &&
                job.larhrs &&
                dayjs().businessDaysAdd(
                  (job.labhrs.aggregate.sum.mod_lb_hrs || 0 + job.larhrs.aggregate.sum.mod_lb_hrs || 0) /
                    bodyshop.target_touchtime,
                  "day"
                )),
            scheduled_delivery: job.scheduled_delivery && dayjs(job.scheduled_delivery),
            production_vars: job.production_vars
          }),
          ...(type === "deliver" && {
            removeFromProduction: true,
            actual_completion: job && job.actual_completion && dayjs(job.actual_completion),
            actual_delivery: job && job.actual_delivery && dayjs(job.actual_delivery)
          }),
          ...formItems
            .filter((fi) => fi.value)
            .reduce((acc, fi) => {
              acc[fi.name] = fi.value;
              return acc;
            }, {})
        }}
      >
        <ConfigFormComponents componentList={formItems} readOnly={readOnly} />

        {type === "intake" && (
          <div>
            <Form.Item
              name="addToProduction"
              valuePropName="checked"
              label={t("checklist.labels.addtoproduction")}
              disabled={readOnly}
            >
              <Switch disabled={readOnly} />
            </Form.Item>
            <Form.Item
              name="scheduled_completion"
              label={t("jobs.fields.scheduled_completion")}
              disabled={readOnly}
              rules={[
                {
                  required: true
                  //message: t("general.validation.required"),
                }
              ]}
            >
              <DateTimePicker disabled={readOnly} />
            </Form.Item>
            <Form.Item name="scheduled_delivery" label={t("jobs.fields.scheduled_delivery")} disabled={readOnly}>
              <DateTimePicker disabled={readOnly} />
            </Form.Item>
            <Form.Item
              name={["production_vars", "note"]}
              label={t("jobs.fields.production_vars.note")}
              disabled={readOnly}
              trigger="onChange"
            >
              <Input.TextArea rows={3} disabled={readOnly} />
            </Form.Item>
          </div>
        )}
        {type === "deliver" && (
          <div>
            <Form.Item
              name="actual_completion"
              label={t("jobs.fields.actual_completion")}
              disabled={readOnly}
              rules={[
                {
                  required: true
                  //message: t("general.validation.required"),
                }
              ]}
            >
              <DateTimePicker disabled={readOnly} />
            </Form.Item>
            <Form.Item
              name="actual_delivery"
              label={t("jobs.fields.actual_delivery")}
              rules={[
                {
                  required: bodyshop.deliverchecklist.actual_delivery
                    ? bodyshop.deliverchecklist.actual_delivery
                    : false
                  //message: t("general.validation.required"),
                }
              ]}
              disabled={readOnly}
            >
              <DateTimePicker disabled={readOnly} />
            </Form.Item>
            <Form.Item
              name="removeFromProduction"
              valuePropName="checked"
              label={t("checklist.labels.removefromproduction")}
              disabled={readOnly}
            >
              <Switch disabled={readOnly} defaultChecked={true} />
            </Form.Item>
          </div>
        )}
      </Form>
    </Card>
  );
}

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