import { useMutation, useQuery } from "@apollo/client";
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 { useSplitTreatments } from "@splitsoftware/splitio-react";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";

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 }
  } = useSplitTreatments({
    attributes: {},
    names: ["Enhanced_Payroll"],
    splitKey: bodyshop.imexshopid
  });

  const { queryLoading, data: lineTicketData } = useQuery(GET_LINE_TICKET_BY_PK, {
    variables: {
      id: jobId
    },
    skip: !jobId,
    fetchPolicy: "network-only",
    nextFetchPolicy: "network-only"
  });
  const { t } = useTranslation();
  const emps = bodyshop.employees.filter((e) => e.id === (technician && technician.id))[0];

  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 || 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"]({
        message: t("timetickets.errors.clockingout", {
          message: JSON.stringify(result.errors)
        })
      });
    } else {
      notification["success"]({
        message: t("timetickets.successes.clockedout")
      });
    }
    if (!isShiftTicket) {
      const job_update_result = await updateJobStatus({
        variables: {
          jobId: jobId,
          status: status
        }
      });

      if (job_update_result.errors) {
        notification["error"]({
          message: t("jobs.errors.updating", {
            message: JSON.stringify(result.errors)
          })
        });
      } else {
        notification["success"]({
          message: 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 direction="vertical">
            {!isShiftTicket ? (
              <div>
                <Form.Item
                  label={t("timetickets.fields.actualhrs")}
                  name="actualhrs"
                  rules={[
                    {
                      required: true
                      //message: t("general.validation.required"),
                    }
                  ]}
                >
                  <InputNumber min={0} precision={1} />
                </Form.Item>
                <Form.Item
                  label={t("timetickets.fields.productivehrs")}
                  name="productivehrs"
                  rules={[
                    {
                      required: true
                      //message: t("general.validation.required"),
                    },
                    ({ 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 =
                          bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber ? "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"));
                        else {
                          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
                  //message: t("general.validation.required"),
                }
              ]}
            >
              <Select disabled={isShiftTicket}>
                {isShiftTicket ? (
                  <Select.Option value="timetickets.labels.shift">{t("timetickets.labels.shift")}</Select.Option>
                ) : (
                  emps &&
                  emps.rates.map((item) => (
                    <Select.Option key={item.cost_center}>
                      {item.cost_center === "timetickets.labels.shift"
                        ? t(item.cost_center)
                        : bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber
                          ? t(`joblines.fields.lbr_types.${item.cost_center.toUpperCase()}`)
                          : item.cost_center}
                    </Select.Option>
                  ))
                )}
              </Select>
            </Form.Item>
            {isShiftTicket ? (
              <div></div>
            ) : (
              <Form.Item
                name="status"
                label={t("jobs.fields.status")}
                initialValue={lineTicketData && lineTicketData.jobs_by_pk.status}
                rules={[
                  {
                    required: true
                    //message: t("general.validation.required"),
                  }
                ]}
              >
                <Select>
                  {bodyshop.md_ro_statuses.production_statuses.map((item) => (
                    <Select.Option key={item}></Select.Option>
                  ))}
                </Select>
              </Form.Item>
            )}
            <Button type="primary" htmlType="submit" loading={loading}>
              {t("general.actions.save")}
            </Button>
            <TechJobClockoutDelete completedCallback={completedCallback} timeTicketId={timeTicketId} />
            {!isShiftTicket && (
              <LaborAllocationContainer jobid={jobId || 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);
