import { useMutation, useQuery } from "@apollo/client/react";
import { Button, Card, Form, InputNumber, Popover, Select, Space } from "antd";
import axios from "axios";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { logImEXEvent } from "../../firebase/firebase.utils";
import { GET_LINE_TICKET_BY_PK } from "../../graphql/jobs-lines.queries";
import { UPDATE_JOB_STATUS } from "../../graphql/jobs.queries";
import { UPDATE_TIME_TICKET } from "../../graphql/timetickets.queries";
import { selectTechnician } from "../../redux/tech/tech.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { CalculateAllocationsTotals } from "../labor-allocations-table/labor-allocations-table.utility";
import TechJobClockoutDelete from "../tech-job-clock-out-delete/tech-job-clock-out-delete.component";
import { LaborAllocationContainer } from "../time-ticket-modal/time-ticket-modal.component";
import { useTreatmentsWithConfig } from "@splitsoftware/splitio-react";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
import { bodyshopHasDmsKey } from "../../utils/dmsUtils.js";

const mapStateToProps = createStructuredSelector({
  bodyshop: selectBodyshop,
  technician: selectTechnician
});

export function TechClockOffButton({
  bodyshop,
  technician,
  jobId,
  timeTicketId,
  completedCallback,
  isShiftTicket,
  otherBtnProps
}) {
  const [loading, setLoading] = useState(false);
  const [updateTimeticket] = useMutation(UPDATE_TIME_TICKET);
  const [updateJobStatus] = useMutation(UPDATE_JOB_STATUS);
  const notification = useNotification();
  const [form] = Form.useForm();

  const {
    treatments: { Enhanced_Payroll }
  } = useTreatmentsWithConfig({
    attributes: {},
    names: ["Enhanced_Payroll"],
    splitKey: bodyshop.imexshopid
  });

  const id = jobId ?? null;

  const { loading: queryLoading, data: lineTicketData } = useQuery(GET_LINE_TICKET_BY_PK, {
    variables: { id },
    skip: !id,
    fetchPolicy: "network-only",
    nextFetchPolicy: "network-only"
  });

  const { t } = useTranslation();

  const emps = bodyshop.employees.filter((e) => e.id === technician?.id)[0];
  const hasDmsKey = bodyshopHasDmsKey(bodyshop);

  const handleFinish = async (values) => {
    logImEXEvent("tech_clock_out_job");
    const status = values.status;
    delete values.status;
    setLoading(true);

    const result = await updateTimeticket({
      variables: {
        timeticketId: timeTicketId,
        timeticket: {
          clockoff: (await axios.post("/utils/time")).data,
          ...values,
          rate: emps && emps.rates.filter((r) => r.cost_center === values.cost_center)[0]?.rate,
          flat_rate: emps && emps.flat_rate,
          ciecacode:
            bodyshop.cdk_dealerid ||
            bodyshop.pbs_serialnumber ||
            bodyshop.rr_dealerid ||
            Enhanced_Payroll.treatment === "on"
              ? values.cost_center
              : Object.keys(bodyshop.md_responsibility_centers.defaults.costs).find((key) => {
                  return bodyshop.md_responsibility_centers.defaults.costs[key] === values.cost_center;
                })
        }
      }
    });

    if (result.errors) {
      notification.error({
        title: t("timetickets.errors.clockingout", {
          message: JSON.stringify(result.errors)
        })
      });
    } else {
      notification.success({
        title: t("timetickets.successes.clockedout")
      });
    }

    if (!isShiftTicket) {
      const job_update_result = await updateJobStatus({
        variables: {
          jobId: id,
          status: status
        }
      });

      if (job_update_result.errors) {
        notification.error({
          title: t("jobs.errors.updating", {
            message: JSON.stringify(result.errors)
          })
        });
      } else {
        notification.success({
          title: t("jobs.successes.updated")
        });
      }
    }

    setLoading(false);
    if (completedCallback) completedCallback();
  };

  const overlay = (
    <Card>
      <div>
        <Form
          form={form}
          layout="vertical"
          onFinish={handleFinish}
          initialValues={{
            cost_center: isShiftTicket ? "timetickets.labels.shift" : technician ? technician.cost_center : null
          }}
        >
          <Space orientation="vertical">
            {!isShiftTicket ? (
              <div>
                <Form.Item
                  label={t("timetickets.fields.actualhrs")}
                  name="actualhrs"
                  rules={[
                    {
                      required: true
                    }
                  ]}
                >
                  <InputNumber min={0} precision={1} />
                </Form.Item>
                <Form.Item
                  label={t("timetickets.fields.productivehrs")}
                  name="productivehrs"
                  rules={[
                    {
                      required: true
                    },
                    ({ getFieldValue }) => ({
                      validator(rule, value) {
                        if (!bodyshop.tt_enforce_hours_for_tech_console) {
                          return Promise.resolve();
                        }
                        if (!value || getFieldValue("cost_center") === null || !lineTicketData)
                          return Promise.resolve();

                        //Check the cost center,
                        const totals = CalculateAllocationsTotals(
                          bodyshop,
                          lineTicketData.joblines,
                          lineTicketData.timetickets,
                          lineTicketData.jobs_by_pk.lbr_adjustments
                        );

                        const fieldTypeToCheck = hasDmsKey ? "mod_lbr_ty" : "cost_center";

                        const costCenterDiff =
                          Math.round(
                            totals.find((total) => total[fieldTypeToCheck] === getFieldValue("cost_center"))
                              ?.difference * 10
                          ) / 10;

                        if (value > costCenterDiff)
                          return Promise.reject(t("timetickets.validation.hoursenteredmorethanavailable"));
                        return Promise.resolve();
                      }
                    })
                  ]}
                >
                  <InputNumber min={0} precision={1} />
                </Form.Item>
              </div>
            ) : null}

            <Form.Item
              name="cost_center"
              label={t("timetickets.fields.cost_center")}
              rules={[
                {
                  required: true
                }
              ]}
            >
              <Select disabled={isShiftTicket}
                options={
                  isShiftTicket
                    ? [{ value: "timetickets.labels.shift", label: t("timetickets.labels.shift") }]
                    : emps &&
                      emps.rates.map((item) => ({
                        value: item.cost_center,
                        label:
                          item.cost_center === "timetickets.labels.shift"
                            ? t(item.cost_center)
                            : hasDmsKey
                              ? t(`joblines.fields.lbr_types.${item.cost_center.toUpperCase()}`)
                              : item.cost_center
                      }))
                }
              />
            </Form.Item>

            {isShiftTicket ? (
              <div></div>
            ) : (
              <Form.Item
                name="status"
                label={t("jobs.fields.status")}
                initialValue={lineTicketData && lineTicketData.jobs_by_pk.status}
                rules={[
                  {
                    required: true
                  }
                ]}
              >
                <Select
                  options={bodyshop.md_ro_statuses.production_statuses.map((item) => ({
                    value: item,
                    label: item
                  }))}
                />
              </Form.Item>
            )}

            <Button type="primary" htmlType="submit" loading={loading}>
              {t("general.actions.save")}
            </Button>

            <TechJobClockoutDelete completedCallback={completedCallback} timeTicketId={timeTicketId} />

            {!isShiftTicket && (
              <LaborAllocationContainer jobid={id || null} loading={queryLoading} lineTicketData={lineTicketData} />
            )}
          </Space>
        </Form>
      </div>
    </Card>
  );

  return (
    <Popover
      content={<div style={{ maxHeight: "75vh", overflowY: "auto" }}>{overlay}</div>}
      trigger="click"
      getPopupContainer={() => document.querySelector("#time-ticket-modal")}
    >
      <Button loading={loading} {...otherBtnProps}>
        {t("timetickets.actions.clockout")}
      </Button>
    </Popover>
  );
}

export default connect(mapStateToProps, null)(TechClockOffButton);
