import { DeleteFilled, PlusCircleFilled } from "@ant-design/icons";
import { useMutation } from "@apollo/client/react";
import { Button, Col, Popover, Row, Select, Space, Spin } from "antd";
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 { UPDATE_JOB } from "../../graphql/jobs.queries";
import { insertAuditTrail } from "../../redux/application/application.actions";
import { selectBodyshop } from "../../redux/user/user.selectors";
import AuditTrailMapping from "../../utils/AuditTrailMappings";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";

const iconStyle = { marginLeft: ".3rem" };
const mapStateToProps = createStructuredSelector({
  bodyshop: selectBodyshop
});
const mapDispatchToProps = (dispatch) => ({
  insertAuditTrail: ({ jobid, operation, type }) => dispatch(insertAuditTrail({ jobid, operation, type }))
});

export function ProductionListEmpAssignment({ insertAuditTrail, bodyshop, record, refetch, type }) {
  const { t } = useTranslation();
  const [updateJob] = useMutation(UPDATE_JOB);
  const [loading, setLoading] = useState(false);
  const notification = useNotification();

  const handleAdd = async (assignment) => {
    setLoading(true);
    const { operation, employeeid, name } = assignment;
    logImEXEvent("job_assign_employee", { operation });

    let empAssignment = determineFieldName(operation);

    const result = await updateJob({
      variables: { jobId: record.id, job: { [empAssignment]: employeeid } }
    });

    insertAuditTrail({
      jobid: record.id,
      operation: AuditTrailMapping.jobassignmentchange(empAssignment, name),
      type: "jobassignmentchange"
    });

    if (result.errors) {
      notification.error({
        title: t("jobs.errors.assigning", {
          message: JSON.stringify(result.errors)
        })
      });
    }

    await refetch();

    setAssignment({ operation: null, employeeid: null });
    setLoading(false);
  };
  const handleRemove = async (operation) => {
    setLoading(true);
    logImEXEvent("job_unassign_employee", { operation });

    let empAssignment = determineFieldName(operation);
    const result = await updateJob({
      variables: { jobId: record.id, job: { [empAssignment]: null } },

      awaitRefetchQueries: true
    });

    insertAuditTrail({
      jobid: record.id,
      operation: AuditTrailMapping.jobassignmentremoved(empAssignment),
      type: "jobassignmentremoved"
    });

    if (result.errors) {
      notification.error({
        title: t("jobs.errors.assigning", {
          message: JSON.stringify(result.errors)
        })
      });
    }

    await refetch();

    setAssignment({ operation: null, employeeid: null });
    setLoading(false);
  };

  const [assignment, setAssignment] = useState({
    operation: null,
    employeeid: null
  });

  const [visibility, setVisibility] = useState(false);
  const onChange = (e, option) => {
    setAssignment({ ...assignment, employeeid: e, name: option.label });
  };

  const employeeOptions = bodyshop.employees
    .filter((emp) => emp.active)
    .map((emp) => ({
      value: emp.id,
      label: `${emp.first_name} ${emp.last_name}`,
      name: `${emp.first_name} ${emp.last_name}`
    }));

  const popContent = (
    <Row gutter={[16, 16]}>
      <Col span={24}>
        <Select
          id="employeeSelector"
          showSearch={{
            optionFilterProp: "label",
            filterOption: (input, option) => option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
          }}
          style={{ width: 200 }}
          value={assignment.employeeid}
          onChange={onChange}
          options={employeeOptions}
        />
      </Col>
      <Col span={24}>
        <Space wrap>
          <Button
            type="primary"
            disabled={!assignment.employeeid}
            onClick={() => {
              handleAdd(assignment);
              setVisibility(false);
            }}
          >
            Assign
          </Button>
          <Button onClick={() => setVisibility(false)}>Close</Button>
        </Space>
      </Col>
    </Row>
  );

  let theEmployee;

  if (record[type]) theEmployee = bodyshop.employees.find((e) => e.id === record[type]);

  return (
    <Spin spinning={loading}>
      {record[type] ? (
        <div style={{ cursor: "pointer" }}>
          <span>{`${theEmployee?.first_name || ""} ${theEmployee?.last_name || ""}`}</span>
          <DeleteFilled style={iconStyle} onClick={() => handleRemove(type)} />
        </div>
      ) : (
        <Popover destroyOnHidden content={popContent} open={visibility} trigger="click">
          <PlusCircleFilled
            style={{ ...iconStyle, cursor: "pointer" }}
            className="muted-button"
            onClick={() => {
              setAssignment({ operation: type, employeeid: null });
              setVisibility(true);
            }}
          />
        </Popover>
      )}
    </Spin>
  );
}

const determineFieldName = (operation) => {
  switch (operation) {
    case "employee_body":
      return "employee_body";
    case "employee_prep":
      return "employee_prep";
    case "employee_refinish":
      return "employee_refinish";
    case "employee_csr":
      return "employee_csr";
    default:
      return null;
  }
};

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