import { BranchesOutlined, ExclamationCircleFilled, PauseCircleOutlined, WarningFilled } from "@ant-design/icons";
import { useMutation } from "@apollo/client/react";
import { Card, Checkbox, Col, Divider, Row, Space, Tag, Tooltip } from "antd";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { Link } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
import { UPDATE_JOB } from "../../graphql/jobs.queries";
import { insertAuditTrail } from "../../redux/application/application.actions.js";
import { selectIsPartsEntry, selectJobReadOnly } from "../../redux/application/application.selectors";
import { setModalContext } from "../../redux/modals/modals.actions";
import { selectBodyshop } from "../../redux/user/user.selectors";
import AuditTrailMapping from "../../utils/AuditTrailMappings.js";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
import { DateTimeFormatter, DateTimeFormatterFunction } from "../../utils/DateFormatter";
import dayjs from "../../utils/day";
import PhoneNumberFormatter from "../../utils/PhoneFormatter";
import ChatOpenButton from "../chat-open-button/chat-open-button.component";
import DataLabel from "../data-label/data-label.component";
import JobAltTransportChange from "../job-at-change/job-at-change.component";
import JobEmployeeAssignments from "../job-employee-assignments/job-employee-assignments.container";
import JobsRelatedRos from "../jobs-related-ros/jobs-related-ros.component";
import { OwnerNameDisplayFunction } from "../owner-name-display/owner-name-display.component";
import PinnedJobNotes from "../pinned-job-notes/pinned-job-notes.component.jsx";
import ProductionListColumnComment from "../production-list-columns/production-list-columns.comment.component";
import ProductionListColumnProductionNote from "../production-list-columns/production-list-columns.productionnote.component";
import VehicleVinDisplay from "../vehicle-vin-display/vehicle-vin-display.component";
import "./jobs-detail-header.styles.scss";
import getPartsBasePath from "../../utils/getPartsBasePath.js";
import { bodyshopHasDmsKey } from "../../utils/dmsUtils.js";

const mapStateToProps = createStructuredSelector({
  jobRO: selectJobReadOnly,
  bodyshop: selectBodyshop,
  isPartsEntry: selectIsPartsEntry
});

const mapDispatchToProps = (dispatch) => ({
  setPrintCenterContext: (context) =>
    dispatch(
      setModalContext({
        context: context,
        modal: "printCenter"
      })
    ),
  insertAuditTrail: ({ jobid, operation, type }) =>
    dispatch(
      insertAuditTrail({
        jobid,
        operation,
        type
      })
    )
});

export function JobsDetailHeader({ job, bodyshop, disabled, insertAuditTrail, isPartsEntry }) {
  const { t } = useTranslation();
  const { notification } = useNotification();
  const [notesClamped, setNotesClamped] = useState(true);
  const [updateJob] = useMutation(UPDATE_JOB);
  const basePath = getPartsBasePath(isPartsEntry);

  const colSpan = {
    xs: { span: 24 },
    sm: { span: 24 },
    md: { span: 12 },
    lg: { span: 12 },
    xl: { span: isPartsEntry ? 8 : 6 }
  };

  const vehicleTitle =
    `${job.v_model_yr || ""} ${job.v_color || ""} ${job.v_make_desc || ""} ${job.v_model_desc || ""}`.trim();
  const bodyHrs = job.joblines.filter((j) => j.mod_lbr_ty !== "LAR").reduce((acc, val) => acc + val.mod_lb_hrs, 0);
  const refinishHrs = job.joblines
    .filter((line) => line.mod_lbr_ty === "LAR")
    .reduce((acc, val) => acc + val.mod_lb_hrs, 0);
  const ownerTitle = OwnerNameDisplayFunction(job).trim();

  const employeeData = bodyshop.associations.find((a) => a.useremail === job.admin_clerk)?.user?.employee ?? null;

  // Handle checkbox changes
  const handleCheckboxChange = async (field, checked) => {
    const value = checked ? dayjs().toISOString() : null;
    try {
      const ret = await updateJob({
        variables: {
          jobId: job.id,
          job: { [field]: value }
        },
        refetchQueries: ["GET_JOB_BY_PK"],
        awaitRefetchQueries: true
      });
      insertAuditTrail({
        jobid: job.id,
        operation: AuditTrailMapping.jobfieldchange(
          field,
          ret.data.update_jobs.returning[0][field]
            ? DateTimeFormatterFunction(ret.data.update_jobs.returning[0][field])
            : checked
        ),
        type: "jobfieldchange"
      });
    } catch (error) {
      notification.error({
        title: t("jobs.errors.saving", { error: error.message })
      });
    }
  };

  return (
    <>
      <Row gutter={[16, 16]} style={{ alignItems: "stretch" }}>
        <Col {...colSpan}>
          <Card title={"Job Status"} style={{ height: "100%" }}>
            <div>
              <DataLabel label={t("jobs.fields.status")}>
                <Space wrap>
                  {job.status}
                  {job.inproduction && <Tag color="#f50">{t("jobs.labels.inproduction")}</Tag>}
                  {job.suspended && <PauseCircleOutlined style={{ color: "orangered" }} />}
                  {job.iouparent && (
                    <Link to={`/manage/jobs/${job.iouparent}`}>
                      <Tooltip title={t("jobs.labels.iou")}>
                        <BranchesOutlined style={{ color: "orangered" }} />
                      </Tooltip>
                    </Link>
                  )}
                  {job.production_vars && job.production_vars.alert ? (
                    <ExclamationCircleFilled className="production-alert" />
                  ) : null}
                  {job.status === bodyshop.md_ro_statuses.default_scheduled && job.scheduled_in ? (
                    <Tag>
                      <Link to={`/manage/schedule?date=${dayjs(job.scheduled_in).format("YYYY-MM-DD")}`}>
                        <DateTimeFormatter>{job.scheduled_in}</DateTimeFormatter>
                      </Link>
                    </Tag>
                  ) : null}
                </Space>
              </DataLabel>
              <DataLabel
                label={t("jobs.fields.comment")}
                styles={{ value: { overflow: "hidden", textOverflow: "ellipsis" } }}
              >
                <ProductionListColumnComment record={job} usePortal={true} />
              </DataLabel>
              {!isPartsEntry && <DataLabel label={t("jobs.fields.ins_co_nm_short")}>{job.ins_co_nm}</DataLabel>}
              <DataLabel label={t("jobs.fields.clm_no")}>{job.clm_no}</DataLabel>
              <DataLabel label={t("jobs.fields.ponumber")} hideIfNull>
                {job.po_number}
              </DataLabel>
              {!isPartsEntry && (
                <DataLabel label={t("jobs.fields.repairtotal")}>
                  <CurrencyFormatter>{job.clm_total}</CurrencyFormatter>
                  <span style={{ margin: "0rem .5rem" }}>/</span>
                  <CurrencyFormatter>{job.owner_owing}</CurrencyFormatter>
                </DataLabel>
              )}
              {!isPartsEntry && (
                <>
                  <DataLabel label={t("jobs.fields.alt_transport")}>
                    {job.alt_transport}
                    <JobAltTransportChange job={job} />
                  </DataLabel>
                  {job?.cccontracts?.length > 0 && (
                    <DataLabel label={t("jobs.labels.contracts")}>
                      {job.cccontracts.map((c, index) => (
                        <Space key={c.id} wrap>
                          <Link to={`/manage/courtesycars/contracts/${c.id}`}>
                            {`${c.agreementnumber} - ${c.courtesycar.fleetnumber} ${c.courtesycar.year} ${c.courtesycar.make} ${c.courtesycar.model} ${c.courtesycar.plate} - ${t(c.status)}`}
                            {index !== job.cccontracts.length - 1 ? "," : null}
                          </Link>
                        </Space>
                      ))}
                    </DataLabel>
                  )}
                  <DataLabel label={t("jobs.fields.production_vars.note")}>
                    <ProductionListColumnProductionNote record={job} usePortal={true} />
                  </DataLabel>
                  <DataLabel label={t("jobs.fields.estimate_sent_approval")}>
                    <Space>
                      <Checkbox
                        checked={!!job.estimate_sent_approval}
                        onChange={(e) => handleCheckboxChange("estimate_sent_approval", e.target.checked)}
                        disabled={disabled || isPartsEntry}
                      >
                        {job.estimate_sent_approval && (
                          <span style={{ color: "#888" }}>
                            <DateTimeFormatter>{job.estimate_sent_approval}</DateTimeFormatter>
                          </span>
                        )}
                      </Checkbox>
                    </Space>
                  </DataLabel>
                  <DataLabel label={t("jobs.fields.estimate_approved")}>
                    <Space>
                      <Checkbox
                        checked={!!job.estimate_approved}
                        onChange={(e) => handleCheckboxChange("estimate_approved", e.target.checked)}
                        disabled={disabled || isPartsEntry}
                      >
                        {job.estimate_approved && (
                          <span style={{ color: "#888" }}>
                            <DateTimeFormatter>{job.estimate_approved}</DateTimeFormatter>
                          </span>
                        )}
                      </Checkbox>
                    </Space>
                  </DataLabel>
                  <Space wrap>
                    {job.special_coverage_policy && (
                      <Tag color="tomato">
                        <Space>
                          <WarningFilled />
                          <span>{t("jobs.labels.specialcoveragepolicy")}</span>
                        </Space>
                      </Tag>
                    )}
                    {job.ca_gst_registrant && (
                      <Tag color="geekblue">
                        <Space>
                          <WarningFilled />
                          <span>{t("jobs.fields.ca_gst_registrant")}</span>
                        </Space>
                      </Tag>
                    )}
                    {job.hit_and_run && (
                      <Tag color="green">
                        <Space>
                          <WarningFilled />
                          <span>{t("jobs.fields.hit_and_run")}</span>
                        </Space>
                      </Tag>
                    )}
                  </Space>
                </>
              )}
            </div>
          </Card>
        </Col>
        <Col {...colSpan}>
          <Card
            style={{ height: "100%" }}
            title={
              disabled || isPartsEntry ? (
                <>{ownerTitle.length > 0 ? ownerTitle : t("owner.labels.noownerinfo")}</>
              ) : (
                <Link to={`/manage/owners/${job.owner.id}`}>
                  {ownerTitle.length > 0 ? ownerTitle : t("owner.labels.noownerinfo")}
                </Link>
              )
            }
          >
            <div>
              <DataLabel key="2" label={t("jobs.fields.ownr_ph1")}>
                {disabled || isPartsEntry ? (
                  <PhoneNumberFormatter type={job.ownr_ph1_ty}>{job.ownr_ph1}</PhoneNumberFormatter>
                ) : (
                  <ChatOpenButton type={job.ownr_ph1_ty} phone={job.ownr_ph1} jobid={job.id} />
                )}
              </DataLabel>
              <DataLabel key="3" label={t("jobs.fields.ownr_ph2")}>
                {disabled || isPartsEntry ? (
                  <PhoneNumberFormatter type={job.ownr_ph2_ty}>{job.ownr_ph2}</PhoneNumberFormatter>
                ) : (
                  <ChatOpenButton type={job.ownr_ph2_ty} phone={job.ownr_ph2} jobid={job.id} />
                )}
              </DataLabel>
              <DataLabel key="4" label={t("owners.fields.address")}>
                {`${job.ownr_addr1 || ""} ${job.ownr_addr2 || ""} ${
                  job.ownr_city || ""
                } ${job.ownr_st || ""} ${job.ownr_zip || ""}`}
              </DataLabel>
              <DataLabel key="5" label={t("owners.fields.ownr_ea")}>
                {disabled || isPartsEntry ? (
                  <>{job.ownr_ea || ""}</>
                ) : job.ownr_ea ? (
                  <a href={`mailto:${job.ownr_ea}`}>{job.ownr_ea}</a>
                ) : null}
              </DataLabel>
              {job.owner?.tax_number && (
                <DataLabel key="6" label={t("owners.fields.tax_number")}>
                  {job.owner?.tax_number || ""}
                </DataLabel>
              )}
              <DataLabel
                label={t("owners.fields.note")}
                styles={{ value: { overflow: "hidden", textOverflow: "ellipsis" } }}
                key="7"
              >
                {job.owner?.note || ""}
              </DataLabel>
            </div>
          </Card>
        </Col>
        <Col {...colSpan}>
          <Card
            style={{ height: "100%" }}
            title={
              job.vehicle ? (
                disabled ? (
                  <>{vehicleTitle.length > 0 ? vehicleTitle : t("vehicles.labels.novehinfo")} </>
                ) : (
                  <Link to={job.vehicle && `${basePath}/vehicles/${job.vehicle.id}`}>
                    {vehicleTitle.length > 0 ? vehicleTitle : t("vehicles.labels.novehinfo")}
                  </Link>
                )
              ) : (
                <span></span>
              )
            }
          >
            <div>
              <DataLabel key="2" label={t("vehicles.fields.plate_no")}>
                {`${job.plate_no || t("general.labels.na")} (${`${job.plate_st || t("general.labels.na")}`})`}
              </DataLabel>
              <DataLabel key="4" label={t("vehicles.fields.v_vin")}>
                <VehicleVinDisplay>{`${job.v_vin || t("general.labels.na")}`}</VehicleVinDisplay>
                {bodyshopHasDmsKey(bodyshop) ? (
                  job.v_vin?.length !== 17 ? (
                    <WarningFilled style={{ color: "tomato", marginLeft: ".3rem" }} />
                  ) : null
                ) : null}
              </DataLabel>
              <DataLabel label={t("jobs.fields.regie_number")}>{job.regie_number || t("general.labels.na")}</DataLabel>
              <DataLabel label={t("jobs.labels.relatedros")}>
                <JobsRelatedRos jobid={job.id} job={job} disabled={disabled} />
              </DataLabel>
              {job.vehicle?.notes && (
                <DataLabel
                  label={t("vehicles.fields.notes")}
                  styles={{ value: { whiteSpace: "pre-wrap" } }}
                  valueClassName={notesClamped ? "clamp" : ""}
                  onValueClick={() => setNotesClamped(!notesClamped)}
                >
                  {job.vehicle.notes}
                </DataLabel>
              )}
              {job.vehicle?.v_paint_codes && (
                <DataLabel label={t("vehicles.fields.v_paint_codes", { number: "" })}>
                  <span style={{ whiteSpace: "pre" }}>
                    {Object.keys(job.vehicle.v_paint_codes)
                      .filter(
                        (key) =>
                          job.vehicle.v_paint_codes[key] !== "" &&
                          job.vehicle.v_paint_codes[key] !== null &&
                          job.vehicle.v_paint_codes[key] !== undefined
                      )
                      .map((key, idx) => (
                        <Tag key={idx}>{job.vehicle.v_paint_codes[key]}</Tag>
                      ))}
                  </span>
                </DataLabel>
              )}
            </div>
          </Card>
        </Col>
        {!isPartsEntry && (
          <Col {...colSpan}>
            <Card
              style={{ height: "100%" }}
              title={<span id="job-employee-assignments-title">{t("jobs.labels.employeeassignments")}</span>}
              id={"job-employee-assignments"}
            >
              <div>
                <JobEmployeeAssignments job={job} />
                {job.admin_clerk && (
                  <>
                    <Divider style={{ margin: ".5rem" }} />
                    <DataLabel label={t("jobs.fields.admin_clerk")}>
                      {employeeData?.displayName ?? job.admin_clerk}
                    </DataLabel>
                  </>
                )}
                <Divider style={{ margin: ".5rem" }} />
                <DataLabel label={t("jobs.labels.labor_hrs")}>
                  {bodyHrs.toFixed(1)} / {refinishHrs.toFixed(1)} / {(bodyHrs + refinishHrs).toFixed(1)}
                </DataLabel>
              </div>
            </Card>
          </Col>
        )}
      </Row>
      <PinnedJobNotes job={job} />
    </>
  );
}

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