import { DownCircleFilled } from "@ant-design/icons";
import { useApolloClient, useMutation } from "@apollo/client";
import { Button, Dropdown, Menu, notification, Popconfirm } from "antd";
import React, { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { Link, useHistory } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import { logImEXEvent } from "../../firebase/firebase.utils";
import { CANCEL_APPOINTMENTS_BY_JOB_ID } from "../../graphql/appointments.queries";
import { DELETE_JOB, UPDATE_JOB, VOID_JOB } from "../../graphql/jobs.queries";
import { selectJobReadOnly } from "../../redux/application/application.selectors";
import { setModalContext } from "../../redux/modals/modals.actions";
import {
  selectBodyshop,
  selectCurrentUser,
} from "../../redux/user/user.selectors";
import JobsDetailHeaderActionsAddevent from "./jobs-detail-header-actions.addevent";
import AddToProduction from "./jobs-detail-header-actions.addtoproduction.util";
import JobsDetaiLheaderCsi from "./jobs-detail-header-actions.csi.component";
import DuplicateJob from "./jobs-detail-header-actions.duplicate.util";
import JobsDetailHeaderActionsExportcustdataComponent from "./jobs-detail-header-actions.exportcustdata.component";

const mapStateToProps = createStructuredSelector({
  bodyshop: selectBodyshop,
  jobRO: selectJobReadOnly,
  currentUser: selectCurrentUser,
});

const mapDispatchToProps = (dispatch) => ({
  setScheduleContext: (context) =>
    dispatch(setModalContext({ context: context, modal: "schedule" })),
  setBillEnterContext: (context) =>
    dispatch(setModalContext({ context: context, modal: "billEnter" })),
  setPaymentContext: (context) =>
    dispatch(setModalContext({ context: context, modal: "payment" })),
  setJobCostingContext: (context) =>
    dispatch(setModalContext({ context: context, modal: "jobCosting" })),
  setTimeTicketContext: (context) =>
    dispatch(setModalContext({ context: context, modal: "timeTicket" })),
});

export function JobsDetailHeaderActions({
  job,
  bodyshop,
  currentUser,
  refetch,
  setScheduleContext,
  setBillEnterContext,
  setPaymentContext,
  setJobCostingContext,
  jobRO,
  setTimeTicketContext,
}) {
  const { t } = useTranslation();
  const client = useApolloClient();
  const history = useHistory();
  const [deleteJob] = useMutation(DELETE_JOB);
  const [updateJob] = useMutation(UPDATE_JOB);
  const [voidJob] = useMutation(VOID_JOB);
  const [cancelAllAppointments] = useMutation(CANCEL_APPOINTMENTS_BY_JOB_ID);
  const jobInProduction = useMemo(() => {
    return bodyshop.md_ro_statuses.production_statuses.includes(job.status);
  }, [job, bodyshop.md_ro_statuses.production_statuses]);

  const jobInPreProduction = useMemo(() => {
    return bodyshop.md_ro_statuses.pre_production_statuses.includes(job.status);
  }, [job.status, bodyshop.md_ro_statuses.pre_production_statuses]);

  const jobInPostProduction = useMemo(() => {
    return bodyshop.md_ro_statuses.post_production_statuses.includes(
      job.status
    );
  }, [job.status, bodyshop.md_ro_statuses.post_production_statuses]);

  const handleAlertToggle = (e) => {
    logImEXEvent("production_toggle_alert");
    //e.stopPropagation();
    updateJob({
      variables: {
        jobId: job.id,
        job: {
          production_vars: {
            ...job.production_vars,
            alert:
              !!job.production_vars && !!job.production_vars.alert
                ? !job.production_vars.alert
                : true,
          },
        },
      },
    });
  };

  const handleSuspend = (e) => {
    logImEXEvent("production_toggle_alert");
    //e.stopPropagation();
    updateJob({
      variables: {
        jobId: job.id,
        job: {
          suspended: !job.suspended,
        },
      },
    });
  };

  const statusmenu = (
    <Menu key="popovermenu">
      <Menu.Item
        disabled={!jobInPreProduction || !job.converted || jobRO}
        onClick={() => {
          logImEXEvent("job_header_schedule");

          setScheduleContext({
            actions: { refetch: refetch },
            context: {
              jobId: job.id,
              job: job,
              alt_transport: job.alt_transport,
            },
          });
        }}
      >
        {t("jobs.actions.schedule")}
      </Menu.Item>
      <Menu.Item
        disabled={job.status !== bodyshop.md_ro_statuses.default_scheduled}
      >
        <Popconfirm
          title={t("general.labels.areyousure")}
          okText="Yes"
          cancelText="No"
          onClick={(e) => e.stopPropagation()}
          disabled={job.status !== bodyshop.md_ro_statuses.default_scheduled}
          onConfirm={async () => {
            const jobUpdate = await cancelAllAppointments({
              variables: {
                jobid: job.id,
                job: {
                  date_scheduled: null,
                  scheduled_in: null,
                  scheduled_completion: null,
                  status: bodyshop.md_ro_statuses.default_imported,
                },
              },
            });
            if (!jobUpdate.errors) {
              notification["success"]({
                message: t("appointments.successes.canceled"),
              });
              return;
            }
          }}
          getPopupContainer={(trigger) => trigger.parentNode}
        >
          {t("menus.jobsactions.cancelallappointments")}
        </Popconfirm>
      </Menu.Item>
      <Menu.Item
        disabled={
          !!job.intakechecklist ||
          !jobInPreProduction ||
          !job.converted ||
          jobRO
        }
      >
        {!!job.intakechecklist ||
        !jobInPreProduction ||
        !job.converted ||
        jobRO ? (
          t("jobs.actions.intake")
        ) : (
          <Link to={`/manage/jobs/${job.id}/intake`}>
            {t("jobs.actions.intake")}
          </Link>
        )}
      </Menu.Item>
      <Menu.Item disabled={!jobInProduction || jobRO}>
        {!jobInProduction ? (
          t("jobs.actions.deliver")
        ) : (
          <Link to={`/manage/jobs/${job.id}/deliver`}>
            {t("jobs.actions.deliver")}
          </Link>
        )}
      </Menu.Item>
      <Menu.Item disabled={!job.converted}>
        <Link to={`/manage/jobs/${job.id}/checklist`}>
          {t("jobs.actions.viewchecklist")}
        </Link>
      </Menu.Item>
      <Menu.Item
        key="entertimetickets"
        disabled={
          !job.converted ||
          (!bodyshop.tt_allow_post_to_invoiced && job.date_invoiced)
        }
        onClick={() => {
          logImEXEvent("job_header_enter_time_ticekts");

          setTimeTicketContext({
            actions: {},
            context: { jobId: job.id },
          });
        }}
      >
        {t("timetickets.actions.enter")}
      </Menu.Item>
      <Menu.Item
        key="enterpayments"
        disabled={!job.converted}
        onClick={() => {
          logImEXEvent("job_header_enter_payment");

          setPaymentContext({
            actions: {},
            context: { jobid: job.id },
          });
        }}
      >
        {t("menus.header.enterpayment")}
      </Menu.Item>
      <Menu.Item key="cccontract" disabled={jobRO || !job.converted}>
        <Link
          to={{
            pathname: "/manage/courtesycars/contracts/new",
            state: { jobId: job.id },
          }}
        >
          {t("menus.jobsactions.newcccontract")}
        </Link>
      </Menu.Item>
      {job.inproduction ? (
        <Menu.Item
          key="addtoproduction"
          disabled={!job.converted}
          onClick={() => AddToProduction(client, job.id, refetch, true)}
        >
          {t("jobs.actions.removefromproduction")}
        </Menu.Item>
      ) : (
        <Menu.Item
          key="addtoproduction"
          disabled={!job.converted}
          onClick={() => AddToProduction(client, job.id, refetch)}
        >
          {t("jobs.actions.addtoproduction")}
        </Menu.Item>
      )}
      <Menu.Item key="togglesuspend" onClick={handleSuspend}>
        {job.suspended
          ? t("production.actions.unsuspend")
          : t("production.actions.suspend")}
      </Menu.Item>
      <Menu.Item key="toggleAlert" onClick={handleAlertToggle}>
        {job.production_vars && job.production_vars.alert
          ? t("production.labels.alertoff")
          : t("production.labels.alerton")}
      </Menu.Item>
      <Menu.SubMenu key="dupe" title={t("menus.jobsactions.duplicate")}>
        <Menu.Item>
          <Popconfirm
            title={t("jobs.labels.duplicateconfirm")}
            okText="Yes"
            cancelText="No"
            onClick={(e) => e.stopPropagation()}
            onConfirm={() =>
              DuplicateJob(
                client,
                job.id,
                { defaultOpenStatus: bodyshop.md_ro_statuses.default_imported },
                (newJobId) => {
                  history.push(`/manage/jobs/${newJobId}`);
                  notification["success"]({
                    message: t("jobs.successes.duplicated"),
                  });
                },
                true
              )
            }
            getPopupContainer={(trigger) => trigger.parentNode}
          >
            {t("menus.jobsactions.duplicate")}
          </Popconfirm>
        </Menu.Item>
        <Menu.Item>
          <Popconfirm
            title={t("jobs.labels.duplicateconfirm")}
            okText="Yes"
            cancelText="No"
            onClick={(e) => e.stopPropagation()}
            onConfirm={() =>
              DuplicateJob(
                client,
                job.id,
                { defaultOpenStatus: bodyshop.md_ro_statuses.default_imported },
                (newJobId) => {
                  history.push(`/manage/jobs/${newJobId}`);
                  notification["success"]({
                    message: t("jobs.successes.duplicated"),
                  });
                }
              )
            }
            getPopupContainer={(trigger) => trigger.parentNode}
          >
            {t("menus.jobsactions.duplicatenolines")}
          </Popconfirm>
        </Menu.Item>
      </Menu.SubMenu>

      <Menu.Item
        key="postbills"
        disabled={!job.converted}
        onClick={() => {
          logImEXEvent("job_header_enter_bills");

          setBillEnterContext({
            actions: { refetch: refetch },
            context: {
              job: job,
            },
          });
        }}
      >
        {t("jobs.actions.postbills")}
      </Menu.Item>
      <Menu.Item
        key="addtopartsqueue"
        disabled={!job.converted || !jobInProduction || jobRO}
        onClick={async () => {
          const result = await updateJob({
            variables: {
              jobId: job.id,
              job: { queued_for_parts: true },
            },
          });

          if (!!!result.errors) {
            notification["success"]({
              message: t("jobs.successes.partsqueue"),
            });
          } else {
            notification["error"]({
              message: t("jobs.errors.saving", {
                error: JSON.stringify(result.errors),
              }),
            });
          }
        }}
      >
        {t("jobs.actions.addtopartsqueue")}
      </Menu.Item>
      <Menu.Item disabled={!jobInPostProduction} key="closejob">
        {!jobInPostProduction ? (
          t("menus.jobsactions.closejob")
        ) : (
          <Link
            to={{
              pathname: `/manage/jobs/${job.id}/close`,
            }}
          >
            {t("menus.jobsactions.closejob")}
          </Link>
        )}
      </Menu.Item>
      <Menu.Item key="admin">
        <Link
          to={{
            pathname: `/manage/jobs/${job.id}/admin`,
          }}
        >
          {t("menus.jobsactions.admin")}
        </Link>
      </Menu.Item>
      <JobsDetailHeaderActionsExportcustdataComponent job={job} />
      <JobsDetaiLheaderCsi job={job} />
      <Menu.Item
        key="jobcosting"
        disabled={!job.converted}
        onClick={() => {
          logImEXEvent("job_header_job_costing");
          setJobCostingContext({
            actions: { refetch: refetch },
            context: {
              jobId: job.id,
            },
          });
        }}
      >
        {t("jobs.labels.jobcosting")}
      </Menu.Item>
      {job && !job.converted && (
        <Menu.Item>
          <Popconfirm
            title={t("jobs.labels.deleteconfirm")}
            okText={t("general.labels.yes")}
            cancelText={t("general.labels.no")}
            onClick={(e) => e.stopPropagation()}
            onConfirm={async () => {
              //delete the job.
              const result = await deleteJob({ variables: { id: job.id } });

              if (!!!result.errors) {
                notification["success"]({
                  message: t("jobs.successes.delete"),
                });
                //go back to jobs list.
                history.push(`/manage/`);
              } else {
                notification["error"]({
                  message: t("jobs.errors.deleted", {
                    error: JSON.stringify(result.errors),
                  }),
                });
              }
            }}
            getPopupContainer={(trigger) => trigger.parentNode}
          >
            {t("menus.jobsactions.deletejob")}
          </Popconfirm>
        </Menu.Item>
      )}
      <JobsDetailHeaderActionsAddevent jobid={job.id} />
      {!jobRO && job.converted && (
        <Menu.Item>
          <Popconfirm
            title={t("jobs.labels.voidjob")}
            okText="Yes"
            cancelText="No"
            onClick={(e) => e.stopPropagation()}
            onConfirm={async () => {
              //delete the job.
              const result = await voidJob({
                variables: {
                  jobId: job.id,
                  job: {
                    status: bodyshop.md_ro_statuses.default_void,
                    voided: true,
                    scheduled_in: null,
                    scheduled_completion: null,
                    inproduction: false,
                  },
                  note: [
                    {
                      jobid: job.id,
                      created_by: currentUser.email,
                      audit: true,
                      text: t("jobs.labels.voidnote"),
                    },
                  ],
                },
              });

              if (!!!result.errors) {
                notification["success"]({
                  message: t("jobs.successes.voided"),
                });
                //go back to jobs list.
                history.push(`/manage/`);
              } else {
                notification["error"]({
                  message: t("jobs.errors.voiding", {
                    error: JSON.stringify(result.errors),
                  }),
                });
              }
            }}
            getPopupContainer={(trigger) => trigger.parentNode}
          >
            {t("menus.jobsactions.void")}
          </Popconfirm>
        </Menu.Item>
      )}
    </Menu>
  );
  return (
    <Dropdown overlay={statusmenu} trigger={["click"]} key="changestatus">
      <Button>
        <span>{t("general.labels.actions")}</span>

        <DownCircleFilled />
      </Button>
    </Dropdown>
  );
}
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(JobsDetailHeaderActions);
