import { DeleteFilled, DollarCircleFilled } from "@ant-design/icons";
import { useTreatments } from "@splitsoftware/splitio-react";
import {
  Button, Form,
  Input,
  InputNumber,
  Select,
  Space,
  Switch,
  Table,
  Tooltip
} from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import CiecaSelect from "../../utils/Ciecaselect";
import BillLineSearchSelect from "../bill-line-search-select/bill-line-search-select.component";
import BilllineAddInventory from "../billline-add-inventory/billline-add-inventory.component";
import CurrencyInput from "../form-items-formatted/currency-form-item.component";

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

export function BillEnterModalLinesComponent({
  bodyshop,
  disabled,
  lineData,
  discount,
  form,
  responsibilityCenters,
  billEdit,
  billid,
}) {
  const { t } = useTranslation();
  const { setFieldsValue, getFieldsValue, getFieldValue } = form;
  const { Simple_Inventory } = useTreatments(
    ["Simple_Inventory"],
    {},
    bodyshop && bodyshop.imexshopid
  );
  const columns = (remove) => {
    return [
      {
        title: t("billlines.fields.jobline"),
        dataIndex: "joblineid",
        editable: true,
        width: "20rem",
        formItemProps: (field) => {
          return {
            key: `${field.index}joblinename`,
            name: [field.name, "joblineid"],
            label: t("billlines.fields.jobline"),
            rules: [
              {
                required: true,
                //message: t("general.validation.required"),
              },
            ],
          };
        },
        wrapper: (props) => (
          <Form.Item
            noStyle
            shouldUpdate={(prev, cur) =>
              prev.is_credit_memo !== cur.is_credit_memo
            }
          >
            {() => {
              return props.children;
            }}
          </Form.Item>
        ),
        formInput: (record, index) => (
          <BillLineSearchSelect
            disabled={disabled}
            options={lineData}
            style={{ width: "100%", minWidth: "10rem" }}
            allowRemoved={form.getFieldValue("is_credit_memo") || false}
            onSelect={(value, opt) => {
              setFieldsValue({
                billlines: getFieldsValue(["billlines"]).billlines.map(
                  (item, idx) => {
                    if (idx === index) {
                      return {
                        ...item,
                        line_desc: opt.line_desc,
                        quantity: opt.part_qty || 1,
                        actual_price: opt.cost,
                        cost_center: opt.part_type
                          ? bodyshop.pbs_serialnumber || bodyshop.cdk_dealerid
                            ? opt.part_type !== "PAE"
                              ? opt.part_type
                              : null
                            : responsibilityCenters.defaults &&
                              (responsibilityCenters.defaults.costs[
                                opt.part_type
                              ] ||
                                null)
                          : null,
                      };
                    }
                    return item;
                  }
                ),
              });
            }}
          />
        ),
      },
      {
        title: t("billlines.fields.line_desc"),
        dataIndex: "line_desc",
        editable: true,

        formItemProps: (field) => {
          return {
            key: `${field.index}line_desc`,
            name: [field.name, "line_desc"],
            label: t("billlines.fields.line_desc"),
            rules: [
              {
                required: true,
                //message: t("general.validation.required"),
              },
            ],
          };
        },
        formInput: (record, index) => <Input disabled={disabled} />,
      },
      {
        title: t("billlines.fields.quantity"),
        dataIndex: "quantity",
        editable: true,
        width: "4rem",
        formItemProps: (field) => {
          return {
            key: `${field.index}quantity`,
            name: [field.name, "quantity"],
            label: t("billlines.fields.quantity"),
            rules: [
              {
                required: true,
                //message: t("general.validation.required"),
              },
              ({ getFieldValue }) => ({
                validator(rule, value) {
                  if (
                    value &&
                    getFieldValue("billlines")[field.fieldKey]?.inventories
                      ?.length > value
                  ) {
                    return Promise.reject(
                      t("bills.validation.inventoryquantity", {
                        number:
                          getFieldValue("billlines")[field.fieldKey]
                            ?.inventories?.length,
                      })
                    );
                  }
                  return Promise.resolve();
                },
              }),
            ],
          };
        },
        formInput: (record, index) => (
          <InputNumber precision={0} min={1} disabled={disabled} />
        ),
      },
      {
        title: t("billlines.fields.actual_price"),
        dataIndex: "actual_price",
        width: "8rem",
        editable: true,
        formItemProps: (field) => {
          return {
            key: `${field.index}actual_price`,
            name: [field.name, "actual_price"],
            label: t("billlines.fields.actual_price"),
            rules: [
              {
                required: true,
                //message: t("general.validation.required"),
              },
            ],
          };
        },
        formInput: (record, index) => (
          <CurrencyInput
            min={0}
            disabled={disabled}
            onBlur={(e) => {
              setFieldsValue({
                billlines: getFieldsValue("billlines").billlines.map(
                  (item, idx) => {
                    if (idx === index) {
                      return {
                        ...item,
                        actual_cost: !!item.actual_cost
                          ? item.actual_cost
                          : Math.round(
                              (parseFloat(e.target.value) * (1 - discount) +
                                Number.EPSILON) *
                                100
                            ) / 100,
                      };
                    }
                    return item;
                  }
                ),
              });
            }}
          />
        ),
      },
      {
        title: t("billlines.fields.actual_cost"),
        dataIndex: "actual_cost",
        editable: true,
        width: "8rem",

        formItemProps: (field) => {
          return {
            key: `${field.index}actual_cost`,
            name: [field.name, "actual_cost"],
            label: t("billlines.fields.actual_cost"),
            rules: [
              {
                required: true,
                //message: t("general.validation.required"),
              },
            ],
          };
        },
        formInput: (record, index) => (
          <CurrencyInput
            min={0}
            disabled={disabled}
            controls={false}
            addonAfter={
              <Form.Item shouldUpdate noStyle>
                {() => {
                  const line = getFieldsValue(["billlines"]).billlines[index];
                  if (!!!line) return null;
                  let lineDiscount = 1 - line.actual_cost / line.actual_price;
                  if (isNaN(lineDiscount)) lineDiscount = 0;
                  return (
                    <Tooltip title={`${(lineDiscount * 100).toFixed(2) || 0}%`}>
                      <DollarCircleFilled
                        style={{
                          color:
                            Math.abs(lineDiscount - discount) > 0.005
                              ? lineDiscount > discount
                                ? "orange"
                                : "red"
                              : "green",
                        }}
                      />
                    </Tooltip>
                  );
                }}
              </Form.Item>
            }
          />
        ),
        // additional: (record, index) => (
        //   <Form.Item shouldUpdate>
        //     {() => {
        //       const line = getFieldsValue(["billlines"]).billlines[index];
        //       if (!!!line) return null;
        //       const lineDiscount = (
        //         1 -
        //         Math.round((line.actual_cost / line.actual_price) * 100) / 100
        //       ).toPrecision(2);

        //       return (
        //         <Tooltip title={`${(lineDiscount * 100).toFixed(0) || 0}%`}>
        //           <DollarCircleFilled
        //             style={{
        //               color: lineDiscount - discount !== 0 ? "red" : "green",
        //             }}
        //           />
        //         </Tooltip>
        //       );
        //     }}
        //   </Form.Item>
        // ),
      },
      {
        title: t("billlines.fields.cost_center"),
        dataIndex: "cost_center",
        editable: true,

        formItemProps: (field) => {
          return {
            key: `${field.index}cost_center`,
            name: [field.name, "cost_center"],
            label: t("billlines.fields.cost_center"),
            valuePropName: "value",
            rules: [
              {
                required: true,
                //message: t("general.validation.required"),
              },
            ],
          };
        },
        formInput: (record, index) => (
          <Select showSearch style={{ minWidth: "3rem" }} disabled={disabled}>
            {bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber
              ? CiecaSelect(true, false)
              : responsibilityCenters.costs.map((item) => (
                  <Select.Option key={item.name}>{item.name}</Select.Option>
                ))}
          </Select>
        ),
      },
      ...(billEdit
        ? []
        : [
            {
              title: t("billlines.fields.location"),
              dataIndex: "location",
              editable: true,
              label: t("billlines.fields.location"),
              formItemProps: (field) => {
                return {
                  key: `${field.index}location`,
                  name: [field.name, "location"],
                };
              },
              formInput: (record, index) => (
                <Select disabled={disabled}>
                  {bodyshop.md_parts_locations.map((loc, idx) => (
                    <Select.Option key={idx} value={loc}>
                      {loc}
                    </Select.Option>
                  ))}
                </Select>
              ),
            },
          ]),
      {
        title: t("billlines.labels.deductedfromlbr"),
        dataIndex: "deductedfromlbr",
        editable: true,
        formItemProps: (field) => {
          return {
            valuePropName: "checked",
            key: `${field.index}deductedfromlbr`,
            name: [field.name, "deductedfromlbr"],
          };
        },
        formInput: (record, index) => <Switch disabled={disabled} />,
        additional: (record, index) => (
          <Form.Item shouldUpdate style={{ display: "inline-block" }}>
            {() => {
              const price = getFieldValue([
                "billlines",
                record.name,
                "actual_price",
              ]);

              const adjustmentRate = getFieldValue([
                "billlines",
                record.name,
                "lbr_adjustment",
                "rate",
              ]);

              if (getFieldValue(["billlines", record.name, "deductedfromlbr"]))
                return (
                  <div>
                    <Form.Item
                      label={t("joblines.fields.mod_lbr_ty")}
                      key={`${index}modlbrty`}
                      rules={[
                        {
                          required: true,
                          //message: t("general.validation.required"),
                        },
                      ]}
                      name={[record.name, "lbr_adjustment", "mod_lbr_ty"]}
                    >
                      <Select allowClear>
                        <Select.Option value="LAA">
                          {t("joblines.fields.lbr_types.LAA")}
                        </Select.Option>
                        <Select.Option value="LAB">
                          {t("joblines.fields.lbr_types.LAB")}
                        </Select.Option>
                        <Select.Option value="LAD">
                          {t("joblines.fields.lbr_types.LAD")}
                        </Select.Option>
                        <Select.Option value="LAE">
                          {t("joblines.fields.lbr_types.LAE")}
                        </Select.Option>
                        <Select.Option value="LAF">
                          {t("joblines.fields.lbr_types.LAF")}
                        </Select.Option>
                        <Select.Option value="LAG">
                          {t("joblines.fields.lbr_types.LAG")}
                        </Select.Option>
                        <Select.Option value="LAM">
                          {t("joblines.fields.lbr_types.LAM")}
                        </Select.Option>
                        <Select.Option value="LAR">
                          {t("joblines.fields.lbr_types.LAR")}
                        </Select.Option>
                        <Select.Option value="LAS">
                          {t("joblines.fields.lbr_types.LAS")}
                        </Select.Option>
                        <Select.Option value="LAU">
                          {t("joblines.fields.lbr_types.LAU")}
                        </Select.Option>
                        <Select.Option value="LA1">
                          {t("joblines.fields.lbr_types.LA1")}
                        </Select.Option>
                        <Select.Option value="LA2">
                          {t("joblines.fields.lbr_types.LA2")}
                        </Select.Option>
                        <Select.Option value="LA3">
                          {t("joblines.fields.lbr_types.LA3")}
                        </Select.Option>
                        <Select.Option value="LA4">
                          {t("joblines.fields.lbr_types.LA4")}
                        </Select.Option>
                      </Select>
                    </Form.Item>
                    <Form.Item
                      label={t("jobs.labels.adjustmentrate")}
                      name={[record.name, "lbr_adjustment", "rate"]}
                      initialValue={bodyshop.default_adjustment_rate}
                      rules={[
                        {
                          required: true,
                          //message: t("general.validation.required"),
                        },
                      ]}
                    >
                      <InputNumber precision={2} min={0.01} />
                    </Form.Item>
                    {price &&
                      adjustmentRate &&
                      `${(price / adjustmentRate).toFixed(1)} hrs`}
                  </div>
                );
              return <></>;
            }}
          </Form.Item>
        ),
      },
      {
        title: t("billlines.fields.federal_tax_applicable"),
        dataIndex: "applicable_taxes.federal",
        editable: true,

        formItemProps: (field) => {
          return {
            key: `${field.index}fedtax`,
            valuePropName: "checked",
            initialValue: true,
            name: [field.name, "applicable_taxes", "federal"],
          };
        },
        formInput: (record, index) => <Switch disabled={disabled} />,
      },
      {
        title: t("billlines.fields.state_tax_applicable"),
        dataIndex: "applicable_taxes.state",
        editable: true,

        formItemProps: (field) => {
          return {
            key: `${field.index}statetax`,
            valuePropName: "checked",
            name: [field.name, "applicable_taxes", "state"],
          };
        },
        formInput: (record, index) => <Switch disabled={disabled} />,
      },
      {
        title: t("billlines.fields.local_tax_applicable"),
        dataIndex: "applicable_taxes.local",
        editable: true,

        formItemProps: (field) => {
          return {
            key: `${field.index}localtax`,
            valuePropName: "checked",
            name: [field.name, "applicable_taxes", "local"],
          };
        },
        formInput: (record, index) => <Switch disabled={disabled} />,
      },
      {
        title: t("general.labels.actions"),

        dataIndex: "actions",
        render: (text, record) => (
          <Form.Item shouldUpdate noStyle>
            {() => (
              <Space wrap>
                <Button
                  disabled={
                    disabled ||
                    getFieldValue("billlines")[record.fieldKey]?.inventories
                      ?.length > 0
                  }
                  onClick={() => remove(record.name)}
                >
                  <DeleteFilled />
                </Button>
                {Simple_Inventory.treatment === "on" && (
                  <BilllineAddInventory
                    disabled={
                      !billEdit ||
                      form.isFieldsTouched() ||
                      form.getFieldValue("is_credit_memo")
                    }
                    billline={getFieldValue("billlines")[record.fieldKey]}
                    jobid={getFieldValue("jobid")}
                  />
                )}
              </Space>
            )}
          </Form.Item>
        ),
      },
    ];
  };

  const mergedColumns = (remove) =>
    columns(remove).map((col) => {
      if (!col.editable) return col;
      return {
        ...col,
        onCell: (record) => ({
          record,
          formItemProps: col.formItemProps,
          formInput: col.formInput,
          additional: col.additional,
          dataIndex: col.dataIndex,
          title: col.title,
        }),
      };
    });

  return (
    <Form.List
      name="billlines"
      rules={[
        {
          validator: async (_, billlines) => {
            if (!billlines || billlines.length < 1) {
              return Promise.reject(
                new Error(t("billlines.validation.atleastone"))
              );
            }
          },
        },
      ]}
    >
      {(fields, { add, remove, move }) => {
        return (
          <>
            <Table
              components={{
                body: {
                  cell: EditableCell,
                },
              }}
              size="small"
              bordered
              dataSource={fields}
              columns={mergedColumns(remove)}
              scroll={{ x: true }}
              pagination={false}
              rowClassName="editable-row"
            />
            <Form.Item>
              <Button
                disabled={disabled}
                onClick={() => {
                  add();
                }}
                style={{ width: "100%" }}
              >
                {t("billlines.actions.newline")}
              </Button>
            </Form.Item>
          </>
        );
      }}
    </Form.List>
  );
}

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

const EditableCell = ({
  dataIndex,
  title,
  inputType,
  record,
  index,
  children,
  formInput,
  formItemProps,
  additional,
  wrapper,
  ...restProps
}) => {
  if (additional)
    return (
      <td {...restProps}>
        <Space size="small">
          <Form.Item
            name={dataIndex}
            labelCol={{ span: 0 }}
            {...(formItemProps && formItemProps(record))}
          >
            {(formInput && formInput(record, record.name)) || children}
          </Form.Item>
          {additional && additional(record, record.name)}
        </Space>
      </td>
    );
  if (wrapper)
    return (
      <wrapper>
        <td {...restProps}>
          <Form.Item
            labelCol={{ span: 0 }}
            name={dataIndex}
            {...(formItemProps && formItemProps(record))}
          >
            {(formInput && formInput(record, record.name)) || children}
          </Form.Item>
        </td>
      </wrapper>
    );
  return (
    <td {...restProps}>
      <Form.Item
        labelCol={{ span: 0 }}
        name={dataIndex}
        {...(formItemProps && formItemProps(record))}
      >
        {(formInput && formInput(record, record.name)) || children}
      </Form.Item>
    </td>
  );
};
