import { PageHeader } from "@ant-design/pro-layout";
import { useMutation, useQuery } from "@apollo/client/react";
import { useTreatmentsWithConfig } from "@splitsoftware/splitio-react";
import { Button, Form, Modal, Space } from "antd";
import { useEffect, useState, useRef } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
import { QUERY_ACTIVE_EMPLOYEES } from "../../graphql/employees.queries";
import { INSERT_NEW_TIME_TICKET, UPDATE_TIME_TICKET } from "../../graphql/timetickets.queries";
import { toggleModalVisible } from "../../redux/modals/modals.actions";
import { selectTimeTicket } from "../../redux/modals/modals.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors";
import dayjs from "../../utils/day";
import TimeTicketsCommitToggleComponent from "../time-tickets-commit-toggle/time-tickets-commit-toggle.component";
import TimeTicketModalComponent from "./time-ticket-modal.component";
import { insertAuditTrail } from "../../redux/application/application.actions.js";
import AuditTrailMapping from "../../utils/AuditTrailMappings";
import { buildTimeTicketAuditSummary } from "../../utils/auditTrailDetails.js";

const mapStateToProps = createStructuredSelector({
  timeTicketModal: selectTimeTicket,
  bodyshop: selectBodyshop
});
const mapDispatchToProps = (dispatch) => ({
  toggleModalVisible: () => dispatch(toggleModalVisible("timeTicket")),
  insertAuditTrail: ({ jobid, operation, type }) => dispatch(insertAuditTrail({ jobid, operation, type }))
});

export function TimeTicketModalContainer({ timeTicketModal, toggleModalVisible, bodyshop, insertAuditTrail }) {
  const [form] = Form.useForm();
  const [loading, setLoading] = useState(false);
  const { t } = useTranslation();
  const [enterAgain, setEnterAgain] = useState(false);

  const lastSubmittedRef = useRef(null);

  const [lineTicketRefreshKey, setLineTicketRefreshKey] = useState(0);

  const [insertTicket] = useMutation(INSERT_NEW_TIME_TICKET);
  const [updateTicket] = useMutation(UPDATE_TIME_TICKET);
  const {
    treatments: { Enhanced_Payroll }
  } = useTreatmentsWithConfig({
    attributes: {},
    names: ["Enhanced_Payroll"],
    splitKey: bodyshop.imexshopid
  });
  const notification = useNotification();

  const { data: EmployeeAutoCompleteData } = useQuery(QUERY_ACTIVE_EMPLOYEES, {
    skip: !timeTicketModal.open,
    fetchPolicy: "network-only",
    nextFetchPolicy: "network-only"
  });
  const employees = EmployeeAutoCompleteData?.employees ?? [];

  const handleFinish = (values) => {
    lastSubmittedRef.current = values;
    setLoading(true);
    const isEdit = Boolean(timeTicketModal.context.id);
    const emps = employees.filter((employee) => employee.id === values.employeeid);
    const mutation = isEdit
      ? updateTicket({
          variables: {
            timeticketId: timeTicketModal.context.id,
            timeticket: {
              ...values,
              rate:
                emps.length === 1 ? emps[0].rates.filter((r) => r.cost_center === values.cost_center)[0]?.rate : null
            }
          }
        })
      : insertTicket({
          variables: {
            timeTicketInput: [
              {
                ...values,
                rate:
                  emps.length === 1 ? emps[0].rates.filter((r) => r.cost_center === values.cost_center)[0].rate : null,
                bodyshopid: bodyshop.id,
                created_by: timeTicketModal.context.created_by
              }
            ]
          }
        });

    mutation.then((result) => handleMutationSuccess(result, isEdit)).catch(handleMutationError);
  };

  const handleMutationSuccess = (result, isEdit) => {
    notification.success({
      title: t("timetickets.successes.created")
    });

    const savedTicket =
      result?.data?.update_timetickets?.returning?.[0] ?? result?.data?.insert_timetickets?.returning?.[0] ?? {};
    const originalTicket = timeTicketModal.context?.timeticket ?? {};
    const submittedValues = {
      ...(lastSubmittedRef.current ?? {}),
      date: lastSubmittedRef.current?.date ?? savedTicket.date ?? originalTicket.date ?? null,
      employeeid: lastSubmittedRef.current?.employeeid ?? savedTicket.employeeid ?? originalTicket.employeeid ?? null,
      jobid:
        lastSubmittedRef.current?.jobid ??
        savedTicket.jobid ??
        timeTicketModal.context.jobId ??
        originalTicket.job?.id ??
        originalTicket.jobid ??
        null
    };
    const auditSummary = buildTimeTicketAuditSummary({
      originalTicket,
      submittedValues,
      employees
    });

    if (auditSummary.jobid) {
      insertAuditTrail({
        jobid: auditSummary.jobid,
        operation: isEdit
          ? AuditTrailMapping.timeticketupdated(auditSummary.employeeName, auditSummary.date, auditSummary.details)
          : AuditTrailMapping.timeticketcreated(auditSummary.employeeName, auditSummary.date, auditSummary.details),
        type: isEdit ? "timeticketupdated" : "timeticketcreated"
      });
    }

    // Refresh parent screens (Job Labor tab, etc.)
    if (timeTicketModal.actions.refetch) timeTicketModal.actions.refetch();

    // Refresh the modal "bottom section" (allocations + embedded ticket list) for the current job
    setLineTicketRefreshKey((k) => k + 1);

    if (enterAgain) {
      // Capture existing information and repopulate it.
      // (Include jobid so Save & New stays on the same RO if it was selected in-form.)
      const prev = form.getFieldsValue(["jobid", "date", "employeeid", "flat_rate"]);

      form.resetFields();

      form.setFieldsValue(prev);
    } else {
      toggleModalVisible();
    }
    setEnterAgain(false);
    setLoading(false);
  };

  const handleMutationError = (error) => {
    setEnterAgain(false);
    notification.error({
      title: t("timetickets.errors.creating", {
        message: JSON.stringify(error)
      })
    });
    setLoading(false);
  };

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

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

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

  const handleFieldsChange = (changedFields) => {
    if (!!changedFields.employeeid && !!EmployeeAutoCompleteData) {
      const emps = EmployeeAutoCompleteData.employees.filter((e) => e.id === changedFields.employeeid);
      form.setFieldsValue({
        cost_center: emps.length > 0 ? emps[0].cost_center : "",
        ciecacode:
          Object.keys(bodyshop.md_responsibility_centers.defaults.costs).find(
            (key) => bodyshop.md_responsibility_centers.defaults.costs[key] === emps[0].cost_center
          ) || "LAB"
      });
    }
    if (!!changedFields.cost_center && !!EmployeeAutoCompleteData) {
      form.setFieldsValue({
        ciecacode:
          bodyshop.cdk_dealerid ||
          bodyshop.pbs_serialnumber ||
          bodyshop.rr_dealerid ||
          Enhanced_Payroll.treatment === "on"
            ? changedFields.cost_center
            : Object.keys(bodyshop.md_responsibility_centers.defaults.costs).find(
                (key) => bodyshop.md_responsibility_centers.defaults.costs[key] === changedFields.cost_center
              )
      });
    }
  };

  return (
    <Modal
      title={
        timeTicketModal.context && timeTicketModal.context.id
          ? t("timetickets.labels.edit")
          : t("timetickets.labels.new")
      }
      width={"90%"}
      open={timeTicketModal.open}
      forceRender
      onCancel={handleCancel}
      afterClose={() => form.resetFields()}
      footer={
        <Space>
          <Button onClick={handleCancel}>{t("general.actions.cancel")}</Button>
          <Button
            loading={loading}
            disabled={timeTicketModal.context?.timeticket?.committed_at}
            onClick={() => form.submit()}
          >
            {t("general.actions.save")}
          </Button>
          {timeTicketModal.context && timeTicketModal.context.id ? null : (
            <Button
              type="primary"
              loading={loading}
              onClick={() => {
                setEnterAgain(true);
              }}
            >
              {t("general.actions.saveandnew")}
            </Button>
          )}
        </Space>
      }
      destroyOnHidden
      id="time-ticket-modal"
    >
      <Form
        onFinish={handleFinish}
        layout="vertical"
        autoComplete={"off"}
        form={form}
        onFinishFailed={() => setEnterAgain(false)}
        disabled={timeTicketModal.context?.timeticket?.committed_at}
        initialValues={
          timeTicketModal.context.timeticket
            ? {
                ...timeTicketModal.context.timeticket,
                jobid:
                  (timeTicketModal.context.timeticket.job && timeTicketModal.context.timeticket.job.id) ||
                  timeTicketModal.context.timeticket.jobid ||
                  null,
                date: timeTicketModal.context.timeticket.date ? dayjs(timeTicketModal.context.timeticket.date) : null
              }
            : { jobid: timeTicketModal.context.jobId || null }
        }
        onValuesChange={handleFieldsChange}
      >
        <PageHeader
          extra={
            <Space>
              {Enhanced_Payroll.treatment === "on" && (
                <TimeTicketsCommitToggleComponent timeticket={timeTicketModal.context?.timeticket} />
              )}
              <Button onClick={handleCancel}>{t("general.actions.cancel")}</Button>
              <Button loading={loading} onClick={() => form.submit()}>
                {t("general.actions.save")}
              </Button>
              {timeTicketModal.context && timeTicketModal.context.id ? null : (
                <Button
                  type="primary"
                  loading={loading}
                  onClick={() => {
                    setEnterAgain(true);
                  }}
                >
                  {t("general.actions.saveandnew")}
                </Button>
              )}
            </Space>
          }
        />

        <TimeTicketModalComponent
          isEdit={timeTicketModal.context.id}
          form={form}
          disabled={timeTicketModal.context?.timeticket?.committed_at}
          employeeAutoCompleteOptions={EmployeeAutoCompleteData && EmployeeAutoCompleteData.employees}
          employeeSelectDisabled={
            timeTicketModal.context?.timeticket?.committed_at ||
            (timeTicketModal.context?.timeticket?.employeeid && !timeTicketModal.context.id ? true : false)
          }
          lineTicketRefreshKey={lineTicketRefreshKey}
          isOpen={timeTicketModal.open}
        />
      </Form>
    </Modal>
  );
}

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