import { useLazyQuery, useMutation } from "@apollo/client/react";
import { Form } from "antd";
import _ from "lodash";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import RbacWrapper from "../../components/rbac-wrapper/rbac-wrapper.component";
import { INSERT_NEW_JOB } from "../../graphql/jobs.queries";
import { QUERY_OWNER_FOR_JOB_CREATION } from "../../graphql/owners.queries";
import { insertAuditTrail, setBreadcrumbs, setSelectedHeader } from "../../redux/application/application.actions";
import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
import InstanceRenderManager from "../../utils/instanceRenderMgr";
import JobsCreateComponent from "./jobs-create.component";
import JobCreateContext from "./jobs-create.context";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
import { logImEXEvent } from "../../firebase/firebase.utils";
import AuditTrailMapping from "../../utils/AuditTrailMappings.js";

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

function JobsCreateContainer({ bodyshop, setBreadcrumbs, setSelectedHeader, currentUser, insertAuditTrail }) {
  const { t } = useTranslation();
  const notification = useNotification();

  const contextState = useState({
    vehicle: {
      new: false,
      search: "",
      selectedid: null,
      vehicleObj: null,
      none: false
    },
    owner: { new: false, search: "", selectedid: null },
    job: null,
    created: false,
    error: null,
    newJobId: null,
    newJobEstNum: null
  });
  const [form] = Form.useForm();
  const [state, setState] = contextState;
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [insertJob] = useMutation(INSERT_NEW_JOB);
  const [loadOwner, remoteOwnerData] = useLazyQuery(QUERY_OWNER_FOR_JOB_CREATION);

  useEffect(() => {
    if (state.owner.selectedid) {
      loadOwner({ variables: { id: state.owner.selectedid } });
    }
  }, [state.owner.selectedid, loadOwner]);

  useEffect(() => {
    document.title = t("titles.jobs-create", {
      app: InstanceRenderManager({
        imex: "$t(titles.imexonline)",
        rome: "$t(titles.romeonline)"
      })
    });
    setSelectedHeader("newjob");
    setBreadcrumbs([
      { link: "/manage/available", label: t("titles.bc.availablejobs") },
      {
        link: "/manage/jobs/new",
        label: t("titles.bc.jobs-new")
      }
    ]);
    logImEXEvent("manual_job_create_start", {});
  }, [t, setBreadcrumbs, setSelectedHeader]);

  const runInsertJob = (job) => {
    insertJob({ variables: { job } })
      .then((resp) => {
        setState({
          ...state,
          created: true,
          error: null,
          newJobId: resp.data.insert_jobs.returning[0].id
        });
        logImEXEvent("manual_job_create_completed", {});
        insertAuditTrail({
          jobid: resp.data.insert_jobs.returning[0].id,
          operation: AuditTrailMapping.jobmanualcreate(),
          type: "jobmanualcreate"
        });
        setIsSubmitting(false);
      })
      .catch((error) => {
        notification.error({
          title: t("jobs.errors.creating", { error: error })
        });
        setState({ ...state, error: error });
        setIsSubmitting(false);
      });
  };

  const handleFinish = (values) => {
    setIsSubmitting(true);
    let job = Object.assign(
      {},
      values,
      { date_open: new Date() },
      { date_estimated: new Date() },
      {
        vehicle: state.vehicle.selectedid || state.vehicle.none ? null : values.vehicle,
        vehicleid: state.vehicle.selectedid || null
      },
      {
        owner: state.owner.selectedid ? null : values.owner,
        ownerid: state.owner.selectedid || null
      },
      {
        status: bodyshop.md_ro_statuses.default_imported || "Open*",
        shopid: bodyshop.id
      }
    );

    let ownerData;
    if (!job.ownerid) {
      // Keep preferred_contact for the nested owner insert...
      job.owner.data.shopid = bodyshop.id;

      // ...but do NOT flatten preferred_contact into the job row.
      ownerData = _.cloneDeep(job.owner.data);
      delete ownerData.preferred_contact;

      delete job.ownerid;
    } else {
      ownerData = _.cloneDeep(remoteOwnerData.data.owners_by_pk);
      delete ownerData.id;
      delete ownerData.__typename;
    }

    if (!state.vehicle.none) {
      if (!job.vehicleid) {
        delete job.vehicleid;
        job.vehicle.data.shopid = bodyshop.id;
        job.plate_no = job.vehicle.data.plate_no;
        job.plate_st = job.vehicle.data.plate_st;
        job.v_vin = job.vehicle.data.v_vin;
        job.v_model_yr = job.vehicle.data.v_model_yr;
        job.v_model_desc = job.vehicle.data.v_model_desc;
        job.v_make_desc = job.vehicle.data.v_make_desc;
        job.v_color = job.vehicle.data.v_color;
      } else {
        job.plate_no = state.vehicle.vehicleObj.plate_no;
        job.plate_st = state.vehicle.vehicleObj.plate_st;
        job.v_vin = state.vehicle.vehicleObj.v_vin;
        job.v_model_yr = state.vehicle.vehicleObj.v_model_yr;
        job.v_model_desc = state.vehicle.vehicleObj.v_model_desc;
        job.v_make_desc = state.vehicle.vehicleObj.v_make_desc;
        job.v_color = state.vehicle.vehicleObj.v_color;
      }
    }

    job = { ...job, ...ownerData };

    if (job.owner === null) delete job.owner;
    if (job.vehicle === null) delete job.vehicle;

    // Associate to the current user if one exists
    if (currentUser?.email) {
      job.created_user_email = currentUser.email;
    }

    runInsertJob(job);
  };

  return (
    <JobCreateContext.Provider value={contextState}>
      <RbacWrapper action="jobs:create">
        <Form
          form={form}
          onFinish={handleFinish}
          layout="vertical"
          autoComplete={"off"}
          initialValues={{
            federal_tax_rate: bodyshop.bill_tax_rates.federal_tax_rate / 100,
            state_tax_rate: bodyshop.bill_tax_rates.state_tax_rate / 100,
            local_tax_rate: bodyshop.bill_tax_rates.local_tax_rate / 100,
            ...InstanceRenderManager({
              imex: {
                parts_tax_rates: {
                  PAA: {
                    prt_type: "PAA",
                    prt_discp: 0,
                    prt_mktyp: false,
                    prt_mkupp: 0,
                    prt_tax_in: true,
                    prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100
                  },
                  PAC: {
                    prt_type: "PAC",
                    prt_discp: 0,
                    prt_mktyp: false,
                    prt_mkupp: 0,
                    prt_tax_in: true,
                    prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100
                  },
                  PAG: {
                    prt_type: "PAG",
                    prt_discp: 0,
                    prt_mktyp: false,
                    prt_mkupp: 0,
                    prt_tax_in: true,
                    prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100
                  },
                  PAL: {
                    prt_type: "PAL",
                    prt_discp: 0,
                    prt_mktyp: false,
                    prt_mkupp: 0,
                    prt_tax_in: true,
                    prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100
                  },
                  PAM: {
                    prt_type: "PAM",
                    prt_discp: 0,
                    prt_mktyp: false,
                    prt_mkupp: 0,
                    prt_tax_in: true,
                    prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100
                  },
                  PAN: {
                    prt_type: "PAN",
                    prt_discp: 0,
                    prt_mktyp: false,
                    prt_mkupp: 0,
                    prt_tax_in: true,
                    prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100
                  },
                  PAR: {
                    prt_type: "PAR",
                    prt_discp: 0,
                    prt_mktyp: false,
                    prt_mkupp: 0,
                    prt_tax_in: true,
                    prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100
                  },
                  PAS: {
                    prt_type: "PAS",
                    prt_discp: 0,
                    prt_mktyp: false,
                    prt_mkupp: 0,
                    prt_tax_in: true,
                    prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100
                  },
                  PASL: {
                    prt_type: "PASL",
                    prt_discp: 0,
                    prt_mktyp: false,
                    prt_mkupp: 0,
                    prt_tax_in: true,
                    prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100
                  },
                  PAP: {
                    prt_type: "PAP",
                    prt_discp: 0,
                    prt_mktyp: false,
                    prt_mkupp: 0,
                    prt_tax_in: true,
                    prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100
                  },
                  PAO: {
                    prt_type: "PAO",
                    prt_discp: 0,
                    prt_mktyp: false,
                    prt_mkupp: 0,
                    prt_tax_in: true,
                    prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100
                  }
                },
                tax_tow_rt: bodyshop.bill_tax_rates.state_tax_rate / 100,
                tax_str_rt: bodyshop.bill_tax_rates.state_tax_rate / 100,
                tax_paint_mat_rt: bodyshop.bill_tax_rates.state_tax_rate / 100,
                tax_shop_mat_rt: bodyshop.bill_tax_rates.state_tax_rate / 100,
                tax_sub_rt: bodyshop.bill_tax_rates.state_tax_rate / 100,
                tax_lbr_rt: bodyshop.bill_tax_rates.state_tax_rate / 100,
                tax_levies_rt: bodyshop.bill_tax_rates.state_tax_rate / 100
              },
              rome: {
                cieca_pft: {
                  ...bodyshop.md_responsibility_centers.taxes.tax_ty1,
                  ...bodyshop.md_responsibility_centers.taxes.tax_ty2,
                  ...bodyshop.md_responsibility_centers.taxes.tax_ty3,
                  ...bodyshop.md_responsibility_centers.taxes.tax_ty4,
                  ...bodyshop.md_responsibility_centers.taxes.tax_ty5
                },
                materials: bodyshop.md_responsibility_centers.cieca_pfm,
                cieca_pfl: bodyshop.md_responsibility_centers.cieca_pfl,
                parts_tax_rates: bodyshop.md_responsibility_centers.parts_tax_rates,
                tax_tow_rt: bodyshop.md_responsibility_centers.tax_tow_rt,
                tax_str_rt: bodyshop.md_responsibility_centers.tax_str_rt,
                tax_paint_mat_rt: bodyshop.md_responsibility_centers.tax_paint_mat_rt,
                tax_shop_mat_rt: bodyshop.md_responsibility_centers.tax_shop_mat_rt,
                tax_sub_rt: bodyshop.md_responsibility_centers.tax_sub_rt,
                tax_lbr_rt: bodyshop.md_responsibility_centers.tax_lbr_rt,
                tax_levies_rt: bodyshop.md_responsibility_centers.tax_levies_rt
              }
            })
          }}
        >
          <JobsCreateComponent form={form} isSubmitting={isSubmitting} />
        </Form>
      </RbacWrapper>
    </JobCreateContext.Provider>
  );
}

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