import { DeleteFilled } from "@ant-design/icons";
import { useApolloClient, useMutation, useQuery } from "@apollo/client";
import { Button, Card, Form, Input, InputNumber, notification, Select, Switch, Table } from "antd";
import { useForm } from "antd/es/form/Form";
import dayjs from "../../utils/day";
import React, { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { useLocation, useNavigate } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import { logImEXEvent } from "../../firebase/firebase.utils";
import {
  CHECK_EMPLOYEE_NUMBER,
  DELETE_VACATION,
  INSERT_EMPLOYEES,
  QUERY_EMPLOYEE_BY_ID,
  QUERY_USERS_BY_EMAIL,
  UPDATE_EMPLOYEE
} from "../../graphql/employees.queries";
import { selectBodyshop } from "../../redux/user/user.selectors";
import CiecaSelect from "../../utils/Ciecaselect";
import { DateFormatter } from "../../utils/DateFormatter";
import AlertComponent from "../alert/alert.component";
import FormDatePicker from "../form-date-picker/form-date-picker.component";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import ShopEmployeeAddVacation from "./shop-employees-add-vacation.component";
import queryString from "query-string";
import { useSplitTreatments } from "@splitsoftware/splitio-react";

const mapStateToProps = createStructuredSelector({
  bodyshop: selectBodyshop
});
const mapDispatchToProps = (dispatch) => ({
  //setUserLanguage: language => dispatch(setUserLanguage(language))
});

export function ShopEmployeesFormComponent({ bodyshop }) {
  const { t } = useTranslation();
  const [form] = useForm();
  const history = useNavigate();
  const search = queryString.parse(useLocation().search);
  const [deleteVacation] = useMutation(DELETE_VACATION);
  const { error, data } = useQuery(QUERY_EMPLOYEE_BY_ID, {
    variables: { id: search.employeeId },
    skip: !search.employeeId || search.employeeId === "new",
    fetchPolicy: "network-only",
    nextFetchPolicy: "network-only"
  });

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

  const client = useApolloClient();
  useEffect(() => {
    if (data && data.employees_by_pk) form.setFieldsValue(data.employees_by_pk);
    else {
      form.resetFields();
    }
  }, [form, data, search.employeeId]);

  const [updateEmployee] = useMutation(UPDATE_EMPLOYEE);
  const [insertEmployees] = useMutation(INSERT_EMPLOYEES);

  const handleFinish = (values) => {
    if (search.employeeId && search.employeeId !== "new") {
      //Update a record.
      logImEXEvent("shop_employee_update");

      updateEmployee({
        variables: {
          id: search.employeeId,
          employee: {
            ...values,
            user_email: values.user_email === "" ? null : values.user_email
          }
        }
      })
        .then((r) => {
          notification["success"]({
            message: t("employees.successes.save")
          });
        })
        .catch((error) => {
          notification["error"]({
            message: t("employees.errors.save", {
              message: JSON.stringify(error)
            })
          });
        });
    } else {
      //New record, insert it.
      logImEXEvent("shop_employee_insert");

      insertEmployees({
        variables: { employees: [{ ...values, shopid: bodyshop.id }] },
        refetchQueries: ["QUERY_EMPLOYEES"]
      }).then((r) => {
        search.employeeId = r.data.insert_employees.returning[0].id;
        history({ search: queryString.stringify(search) });
        notification["success"]({
          message: t("employees.successes.save")
        });
      });
    }
  };

  if (!search.employeeId) return null;
  if (error) return <AlertComponent message={error.message} type="error" />;

  const columns = [
    {
      title: t("employees.fields.vacation.start"),
      dataIndex: "start",
      key: "start",
      render: (text, record) => <DateFormatter>{text}</DateFormatter>
    },
    {
      title: t("employees.fields.vacation.end"),
      dataIndex: "end",
      key: "end",
      render: (text, record) => <DateFormatter>{text}</DateFormatter>
    },
    {
      title: t("employees.fields.vacation.length"),
      dataIndex: "length",
      key: "length",
      render: (text, record) => dayjs(record.end).diff(dayjs(record.start), "day", true).toFixed(1)
    },
    {
      title: t("general.labels.actions"),
      dataIndex: "actions",
      key: "actions",
      render: (text, record) => (
        <Button
          onClick={async () => {
            await deleteVacation({
              variables: { id: record.id },
              update(cache) {
                cache.modify({
                  id: cache.identify({
                    id: data.employees_by_pk.id,
                    __typename: "employees"
                  }),

                  fields: {
                    employee_vacations(ex, { readField }) {
                      return ex.filter((vacaref) => record.id !== readField("id", vacaref));
                    }
                  }
                });
              }
            });
          }}
        >
          <DeleteFilled />
        </Button>
      )
    }
  ];

  return (
    <Card
      extra={
        <Button type="primary" onClick={() => form.submit()}>
          {t("general.actions.save")}
        </Button>
      }
    >
      <Form onFinish={handleFinish} autoComplete={"off"} layout="vertical" form={form}>
        <LayoutFormRow>
          <Form.Item
            name="first_name"
            label={t("employees.fields.first_name")}
            rules={[
              {
                required: true
                //message: t("general.validation.required"),
              }
            ]}
          >
            <Input />
          </Form.Item>
          <Form.Item
            label={t("employees.fields.last_name")}
            name="last_name"
            rules={[
              {
                required: true
                //message: t("general.validation.required"),
              }
            ]}
          >
            <Input />
          </Form.Item>
          <Form.Item
            name="employee_number"
            label={t("employees.fields.employee_number")}
            validateTrigger="onBlur"
            hasFeedback
            rules={[
              {
                required: true
                //message: t("general.validation.required"),
              },
              ({ getFieldValue }) => ({
                async validator(rule, value) {
                  if (value) {
                    const response = await client.query({
                      query: CHECK_EMPLOYEE_NUMBER,
                      variables: {
                        employeenumber: value
                      }
                    });

                    if (response.data.employees_aggregate.aggregate.count === 0) {
                      return Promise.resolve();
                    } else if (
                      response.data.employees_aggregate.nodes.length === 1 &&
                      response.data.employees_aggregate.nodes[0].id === form.getFieldValue("id")
                    ) {
                      return Promise.resolve();
                    }
                    return Promise.reject(t("employees.validation.unique_employee_number"));
                  } else {
                    return Promise.resolve();
                  }
                }
              })
            ]}
          >
            <Input />
          </Form.Item>
          <Form.Item
            label={t("employees.fields.pin")}
            name="pin"
            rules={[
              {
                required: true
                //message: t("general.validation.required"),
              }
            ]}
          >
            <Input />
          </Form.Item>
        </LayoutFormRow>
        <LayoutFormRow>
          <Form.Item label={t("employees.fields.active")} valuePropName="checked" name="active">
            <Switch />
          </Form.Item>
          <Form.Item label={t("employees.fields.flat_rate")} name="flat_rate" valuePropName="checked">
            <Switch />
          </Form.Item>
          <Form.Item
            name="hire_date"
            label={t("employees.fields.hire_date")}
            rules={[
              {
                required: true
                //message: t("general.validation.required"),
              }
            ]}
          >
            <FormDatePicker />
          </Form.Item>
          <Form.Item label={t("employees.fields.termination_date")} name="termination_date">
            <FormDatePicker />
          </Form.Item>
          <Form.Item
            label={t("employees.fields.user_email")}
            name="user_email"
            validateTrigger="onBlur"
            rules={[
              ({ getFieldValue }) => ({
                async validator(rule, value) {
                  const user_email = getFieldValue("user_email");

                  if (user_email && value) {
                    const response = await client.query({
                      query: QUERY_USERS_BY_EMAIL,
                      variables: {
                        email: user_email
                      }
                    });

                    if (response.data.users.length === 1) {
                      return Promise.resolve();
                    }
                    return Promise.reject(t("bodyshop.validation.useremailmustexist"));
                  } else {
                    return Promise.resolve();
                  }
                }
              })
            ]}
          >
            <Input />
          </Form.Item>
          <Form.Item label={t("employees.fields.external_id")} name="external_id">
            <Input />
          </Form.Item>
        </LayoutFormRow>
        <Form.List name={["rates"]}>
          {(fields, { add, remove, move }) => {
            return (
              <div>
                {fields.map((field, index) => (
                  <Form.Item key={field.key} style={{ padding: 0, margin: 2 }}>
                    <LayoutFormRow grow>
                      <Form.Item
                        label={t("employees.fields.cost_center")}
                        key={`${index}`}
                        name={[field.name, "cost_center"]}
                        valuePropName="value"
                        rules={[
                          {
                            required: true
                            //message: t("general.validation.required"),
                          }
                        ]}
                      >
                        <Select>
                          <Select.Option key={"shift"} value="timetickets.labels.shift">
                            {t("timetickets.labels.shift")}
                          </Select.Option>

                          {bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber || Enhanced_Payroll.treatment === "on"
                            ? CiecaSelect(false, true)
                            : bodyshop.md_responsibility_centers.costs.map((c) => (
                                <Select.Option key={c.name} value={c.name}>
                                  {c.name}
                                </Select.Option>
                              ))}
                        </Select>
                      </Form.Item>
                      <Form.Item
                        label={t("employees.fields.rate")}
                        key={`${index}`}
                        name={[field.name, "rate"]}
                        rules={[
                          {
                            required: true
                            //message: t("general.validation.required"),
                          }
                        ]}
                      >
                        <InputNumber min={0} precision={2} />
                      </Form.Item>
                      <DeleteFilled
                        onClick={() => {
                          remove(field.name);
                        }}
                      />
                      <FormListMoveArrows move={move} index={index} total={fields.length} />
                    </LayoutFormRow>
                  </Form.Item>
                ))}
                <Form.Item>
                  <Button
                    type="dashed"
                    onClick={() => {
                      add();
                    }}
                    style={{ width: "100%" }}
                  >
                    {t("employees.actions.newrate")}
                  </Button>
                </Form.Item>
              </div>
            );
          }}
        </Form.List>
      </Form>

      <Table
        title={() => <ShopEmployeeAddVacation employee={data && data.employees_by_pk} />}
        columns={columns}
        rowKey={"id"}
        dataSource={data ? data.employees_by_pk.employee_vacations : []}
      />
    </Card>
  );
}

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