import { DeleteFilled, DollarCircleFilled } from "@ant-design/icons";
import { useTreatmentsWithConfig } from "@splitsoftware/splitio-react";
import { Button, Checkbox, Form, Input, InputNumber, Select, Space, Switch, Table, Tooltip } from "antd";
import { useRef } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectDarkMode } from "../../redux/application/application.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors";
import CiecaSelect from "../../utils/Ciecaselect";
import { bodyshopHasDmsKey } from "../../utils/dmsUtils.js";
import InstanceRenderManager from "../../utils/instanceRenderMgr";
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";
import ConfidenceDisplay from "./bill-form.lines.confidence.component.jsx";

const mapStateToProps = createStructuredSelector({
  bodyshop: selectBodyshop,
  isDarkMode: selectDarkMode
});

const mapDispatchToProps = () => ({});

export function BillEnterModalLinesComponent({
  bodyshop,
  isDarkMode,
  disabled,
  lineData,
  discount,
  form,
  responsibilityCenters,
  billEdit,
  isAiScan
}) {
  const { t } = useTranslation();
  const { setFieldsValue, getFieldsValue, getFieldValue } = form;
  const firstFieldRefs = useRef({});

  const CONTROL_HEIGHT = 32;

  const normalizeDiscount = (d) => {
    const n = Number(d);
    if (!Number.isFinite(n) || n <= 0) return 0;
    return n > 1 ? n / 100 : n;
  };

  const round2 = (v) => Math.round((v + Number.EPSILON) * 100) / 100;

  const isBlank = (v) => v === null || v === undefined || v === "" || Number.isNaN(v);

  const toNumber = (raw) => {
    if (raw === null || raw === undefined) return NaN;
    if (typeof raw === "number") return raw;

    if (typeof raw === "string") {
      const cleaned = raw
        .trim()
        .replace(/[^\d.,-]/g, "")
        .replace(/,/g, "");
      return Number.parseFloat(cleaned);
    }

    if (typeof raw === "object") {
      try {
        if (typeof raw.toNumber === "function") return raw.toNumber();

        const v = raw.valueOf?.();
        if (typeof v === "number") return v;
        if (typeof v === "string") {
          const cleaned = v
            .trim()
            .replace(/[^\d.,-]/g, "")
            .replace(/,/g, "");
          return Number.parseFloat(cleaned);
        }
      } catch {
        // ignore
      }
    }

    return NaN;
  };

  const setLineField = (index, field, value) => {
    if (typeof form.setFieldValue === "function") {
      form.setFieldValue(["billlines", index, field], value);
      return;
    }

    const lines = form.getFieldValue("billlines") || [];
    form.setFieldsValue({
      billlines: lines.map((l, i) => (i === index ? { ...l, [field]: value } : l))
    });
  };

  // Only fill actual_cost when the user forward-tabs out of Retail (actual_price)
  const autofillActualCost = (index) => {
    if (bodyshop.accountingconfig?.disableBillCostCalculation) return;
    Promise.resolve().then(() => {
      const retailRaw = form.getFieldValue(["billlines", index, "actual_price"]);
      const actualRaw = form.getFieldValue(["billlines", index, "actual_cost"]);
      const d = normalizeDiscount(discount);

      if (!isBlank(actualRaw)) return;

      const retail = toNumber(retailRaw);
      if (!Number.isFinite(retail)) return;

      const next = round2(retail * (1 - d));
      setLineField(index, "actual_cost", next);
    });
  };

  const getIndicatorColor = (lineDiscount) => {
    const d = normalizeDiscount(discount);
    if (Math.abs(lineDiscount - d) > 0.005) return lineDiscount > d ? "orange" : "red";
    return "green";
  };

  const getIndicatorShellStyles = (statusColor) => {
    if (isDarkMode) {
      if (statusColor === "green")
        return { borderColor: "rgba(82, 196, 26, 0.75)", background: "rgba(82, 196, 26, 0.10)" };
      if (statusColor === "orange")
        return { borderColor: "rgba(250, 173, 20, 0.75)", background: "rgba(250, 173, 20, 0.10)" };
      return { borderColor: "rgba(255, 77, 79, 0.75)", background: "rgba(255, 77, 79, 0.10)" };
    }

    if (statusColor === "green") return { borderColor: "#b7eb8f", background: "#f6ffed" };
    if (statusColor === "orange") return { borderColor: "#ffe58f", background: "#fffbe6" };
    return { borderColor: "#ffccc7", background: "#fff2f0" };
  };

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

  const columns = (remove) => {
    return [
      ...(isAiScan
        ? [
            {
              title: t("billlines.fields.confidence"),
              dataIndex: "confidence",
              editable: true,
              width: "5rem",
              formItemProps: (field) => ({
                key: `${field.index}confidence`,
                name: [field.name, "confidence"],
                label: t("billlines.fields.confidence")
              }),
              formInput: (record) => {
                const rowValue = getFieldValue(["billlines", record.name]);
                return (
                  <div style={{ display: "flex", alignItems: "center", justifyContent: "center" }}>
                    <ConfidenceDisplay rowValue={rowValue} />
                  </div>
                );
              }
            }
          ]
        : []),
      {
        title: t("billlines.fields.jobline"),
        dataIndex: "joblineid",
        editable: true,
        minWidth: "10rem",
        formItemProps: (field) => ({
          key: `${field.name}joblinename`,
          name: [field.name, "joblineid"],
          label: t("billlines.fields.jobline"),
          rules: [{ required: true }]
        }),
        wrapper: (props) => (
          <Form.Item noStyle shouldUpdate={(prev, cur) => prev.is_credit_memo !== cur.is_credit_memo}>
            {() => props.children}
          </Form.Item>
        ),
        formInput: (record, index) => (
          <BillLineSearchSelect
            ref={(el) => {
              firstFieldRefs.current[index] = el;
            }}
            disabled={disabled}
            options={lineData}
            style={{
              minWidth: "20rem",
              whiteSpace: "normal",
              height: "auto",
              minHeight: `${CONTROL_HEIGHT}px`
            }}
            allowRemoved={form.getFieldValue("is_credit_memo") || false}
            onSelect={(value, opt) => {
              // IMPORTANT:
              // Do NOT autofill actual_cost here. It should only fill when the user forward-tabs
              // from Retail (actual_price) -> Actual Cost (actual_cost).
              setFieldsValue({
                billlines: (getFieldValue("billlines") || []).map((item, idx) => {
                  if (idx !== index) return item;

                  return {
                    ...item,
                    line_desc: opt.line_desc,
                    quantity: opt.part_qty || 1,
                    actual_price: opt.cost,
                    original_actual_price: opt.cost,
                    // actual_cost intentionally untouched here
                    cost_center: opt.part_type
                      ? bodyshopHasDmsKey(bodyshop)
                        ? opt.part_type !== "PAE"
                          ? opt.part_type
                          : null
                        : responsibilityCenters.defaults &&
                          (responsibilityCenters.defaults.costs[opt.part_type] || null)
                      : null
                  };
                })
              });
            }}
          />
        )
      },
      {
        title: t("billlines.fields.line_desc"),
        dataIndex: "line_desc",
        editable: true,
        minWidth: "10rem",
        formItemProps: (field) => ({
          key: `${field.name}line_desc`,
          name: [field.name, "line_desc"],
          label: t("billlines.fields.line_desc"),
          rules: [{ required: true }]
        }),
        formInput: () => <Input.TextArea disabled={disabled} autoSize tabIndex={0} />
      },

      {
        title: t("billlines.fields.quantity"),
        dataIndex: "quantity",
        editable: true,
        width: "4rem",
        formItemProps: (field) => ({
          key: `${field.name}quantity`,
          name: [field.name, "quantity"],
          label: t("billlines.fields.quantity"),
          rules: [
            { required: true },
            ({ getFieldValue: gf }) => ({
              validator(_, value) {
                const invLen = gf(["billlines", field.name, "inventories"])?.length ?? 0;

                if (value && invLen > value) {
                  return Promise.reject(
                    t("bills.validation.inventoryquantity", {
                      number: invLen
                    })
                  );
                }
                return Promise.resolve();
              }
            })
          ]
        }),
        formInput: () => <InputNumber precision={0} min={1} disabled={disabled} tabIndex={0} />
      },
      {
        title: t("billlines.fields.actual_price"),
        dataIndex: "actual_price",
        width: "8rem",
        editable: true,
        formItemProps: (field) => ({
          key: `${field.name}actual_price`,
          name: [field.name, "actual_price"],
          label: t("billlines.fields.actual_price"),
          rules: [
            { required: true },
            {
              validator: (_, value) => {
                return Math.abs(parseFloat(value)) < 0.01 ? Promise.reject() : Promise.resolve();
              },
              warningOnly: true
            }
          ],
          hasFeedback: true
        }),
        formInput: (record, index) => (
          <CurrencyInput
            min={0}
            disabled={disabled}
            tabIndex={0}
            // NOTE: Autofill should only happen on forward Tab out of Retail
            onKeyDown={(e) => {
              if (e.key === "Tab" && !e.shiftKey) autofillActualCost(index);
            }}
          />
        ),
        additional: (record, index) =>
          InstanceRenderManager({
            rome: (
              <Form.Item dependencies={["billlines", record.name, "actual_price"]} noStyle>
                {() => {
                  const billLine = getFieldValue(["billlines", record.name]);
                  const jobLine = lineData.find((line) => line.id === billLine?.joblineid);

                  if (!billEdit && billLine && jobLine && billLine?.actual_price !== jobLine?.act_price) {
                    return (
                      <Space size="small">
                        <Form.Item
                          noStyle
                          label={t("joblines.fields.create_ppc")}
                          key={`${index}ppc`}
                          valuePropName="checked"
                          name={[record.name, "create_ppc"]}
                        >
                          <Checkbox />
                        </Form.Item>
                        {t("joblines.fields.create_ppc")}
                      </Space>
                    );
                  }
                  return null;
                }}
              </Form.Item>
            )
          })
      },
      {
        title: t("billlines.fields.actual_cost"),
        dataIndex: "actual_cost",
        editable: true,
        width: "10rem",
        skipFormItem: true,
        formItemProps: (field) => ({
          key: `${field.name}actual_cost`,
          name: [field.name, "actual_cost"],
          label: t("billlines.fields.actual_cost"),
          rules: [{ required: true }]
        }),
        formInput: (record, index, fieldProps) => {
          const { name, rules, valuePropName, getValueFromEvent, normalize, validateTrigger, initialValue } =
            fieldProps || {};

          const bindProps = {
            name,
            rules,
            valuePropName,
            getValueFromEvent,
            normalize,
            validateTrigger,
            initialValue
          };

          return (
            <div
              style={{
                display: "flex",
                width: "100%",
                alignItems: "center",
                height: CONTROL_HEIGHT
              }}
            >
              <div style={{ flex: "1 1 auto", minWidth: 0 }}>
                <Form.Item noStyle {...bindProps}>
                  <CurrencyInput
                    min={0}
                    disabled={disabled}
                    controls={false}
                    tabIndex={0}
                    style={{ width: "100%", height: CONTROL_HEIGHT }}
                    onFocus={() => autofillActualCost(index)}
                  />
                </Form.Item>
              </div>

              <Form.Item shouldUpdate noStyle>
                {() => {
                  const all = getFieldsValue(["billlines"]);
                  const line = all?.billlines?.[index];
                  if (!line) return null;

                  const ap = toNumber(line.actual_price);
                  const ac = toNumber(line.actual_cost);

                  let lineDiscount = 0;
                  if (Number.isFinite(ap) && ap !== 0 && Number.isFinite(ac)) {
                    lineDiscount = 1 - ac / ap;
                  }

                  const statusColor = getIndicatorColor(lineDiscount);
                  const shell = getIndicatorShellStyles(statusColor);

                  return (
                    <Tooltip title={`${(lineDiscount * 100).toFixed(2) || 0}%`}>
                      <div
                        style={{
                          height: CONTROL_HEIGHT,
                          minWidth: CONTROL_HEIGHT,
                          padding: "0 10px",
                          display: "flex",
                          alignItems: "center",
                          justifyContent: "center",
                          boxSizing: "border-box",
                          borderStyle: "solid",
                          borderWidth: 1,
                          borderLeftWidth: 0,
                          ...shell,
                          borderTopRightRadius: 6,
                          borderBottomRightRadius: 6
                        }}
                      >
                        <DollarCircleFilled style={{ color: statusColor, lineHeight: 1 }} />
                      </div>
                    </Tooltip>
                  );
                }}
              </Form.Item>
            </div>
          );
        }
      },
      {
        title: t("billlines.fields.cost_center"),
        dataIndex: "cost_center",
        editable: true,
        formItemProps: (field) => ({
          key: `${field.name}cost_center`,
          name: [field.name, "cost_center"],
          label: t("billlines.fields.cost_center"),
          valuePropName: "value",
          rules: [{ required: true }]
        }),
        formInput: () => (
          <Select
            showSearch
            style={{ minWidth: "3rem" }}
            disabled={disabled}
            tabIndex={0}
            options={
              bodyshopHasDmsKey(bodyshop)
                ? CiecaSelect(true, false)
                : responsibilityCenters.costs.map((item) => ({ value: item.name, label: item.name }))
            }
          />
        )
      },
      ...(billEdit
        ? []
        : [
            {
              title: t("billlines.fields.location"),
              dataIndex: "location",
              editable: true,
              label: t("billlines.fields.location"),
              formItemProps: (field) => ({
                key: `${field.name}location`,
                name: [field.name, "location"]
              }),
              formInput: () => (
                <Select
                  disabled={disabled}
                  tabIndex={0}
                  options={bodyshop.md_parts_locations.map((loc) => ({ value: loc, label: loc }))}
                />
              )
            }
          ]),
      {
        title: t("billlines.labels.deductedfromlbr"),
        dataIndex: "deductedfromlbr",
        editable: true,
        width: "40px",
        formItemProps: (field) => ({
          valuePropName: "checked",
          key: `${field.name}deductedfromlbr`,
          name: [field.name, "deductedfromlbr"]
        }),
        formInput: () => <Switch disabled={disabled} tabIndex={0} />,
        additional: (record, index) => (
          <Form.Item shouldUpdate noStyle style={{ display: "inline-block" }}>
            {() => {
              const price = getFieldValue(["billlines", record.name, "actual_price"]);
              const adjustmentRate = getFieldValue(["billlines", record.name, "lbr_adjustment", "rate"]);
              const billline = getFieldValue(["billlines", record.name]);
              const jobline = lineData.find((line) => line.id === billline?.joblineid);
              const employeeTeamName = bodyshop.employee_teams.find((team) => team.id === jobline?.assigned_team);

              if (getFieldValue(["billlines", record.name, "deductedfromlbr"]))
                return (
                  <div>
                    {Enhanced_Payroll.treatment === "on" ? (
                      <Space>
                        {t("joblines.fields.assigned_team", { name: employeeTeamName?.name })}
                        {jobline
                          ? `${jobline.mod_lb_hrs} units/${t(`joblines.fields.lbr_types.${jobline.mod_lbr_ty}`)}`
                          : null}
                      </Space>
                    ) : null}

                    <Form.Item
                      label={t("joblines.fields.mod_lbr_ty")}
                      key={`${index}modlbrty`}
                      initialValue={jobline ? jobline.mod_lbr_ty : null}
                      rules={[{ required: true }]}
                      name={[record.name, "lbr_adjustment", "mod_lbr_ty"]}
                    >
                      <Select allowClear options={CiecaSelect(false, true)} />
                    </Form.Item>

                    {Enhanced_Payroll.treatment === "on" ? (
                      <Form.Item
                        label={t("billlines.labels.mod_lbr_adjustment")}
                        name={[record.name, "lbr_adjustment", "mod_lb_hrs"]}
                        rules={[{ required: true }]}
                      >
                        <InputNumber precision={5} min={0.01} max={jobline ? jobline.mod_lb_hrs : 0} />
                      </Form.Item>
                    ) : (
                      <Form.Item
                        label={t("jobs.labels.adjustmentrate")}
                        name={[record.name, "lbr_adjustment", "rate"]}
                        initialValue={bodyshop.default_adjustment_rate}
                        rules={[{ required: true }]}
                      >
                        <InputNumber precision={2} min={0.01} />
                      </Form.Item>
                    )}

                    <Space>{price && adjustmentRate && `${(price / adjustmentRate).toFixed(1)} hrs`}</Space>
                  </div>
                );

              return <></>;
            }}
          </Form.Item>
        )
      },

      ...InstanceRenderManager({
        rome: [],
        imex: [
          {
            title: t("billlines.fields.federal_tax_applicable"),
            dataIndex: "applicable_taxes.federal",
            editable: true,
            width: "40px",
            formItemProps: (field) => ({
              key: `${field.name}fedtax`,
              valuePropName: "checked",
              name: [field.name, "applicable_taxes", "federal"],
              initialValue: InstanceRenderManager({
                imex: true,
                rome: false
              })
            }),
            formInput: () => <Switch disabled={disabled} tabIndex={0} />
          }
        ]
      }),

      {
        title: t("billlines.fields.state_tax_applicable"),
        dataIndex: "applicable_taxes.state",
        editable: true,
        width: "40px",
        formItemProps: (field) => ({
          key: `${field.name}statetax`,
          valuePropName: "checked",
          name: [field.name, "applicable_taxes", "state"]
        }),
        formInput: () => <Switch disabled={disabled} tabIndex={0} />
      },

      ...InstanceRenderManager({
        rome: [],
        imex: [
          {
            title: t("billlines.fields.local_tax_applicable"),
            dataIndex: "applicable_taxes.local",
            editable: true,
            width: "40px",
            formItemProps: (field) => ({
              key: `${field.name}localtax`,
              valuePropName: "checked",
              name: [field.name, "applicable_taxes", "local"]
            }),
            formInput: () => <Switch disabled={disabled} tabIndex={0} />
          }
        ]
      }),

      {
        title: t("general.labels.actions"),
        dataIndex: "actions",
        render: (text, record) => (
          <Form.Item shouldUpdate noStyle>
            {() => {
              const currentLine = getFieldValue(["billlines", record.name]);
              const invLen = currentLine?.inventories?.length ?? 0;

              return (
                <Space wrap>
                  <Button
                    icon={<DeleteFilled />}
                    disabled={disabled || invLen > 0}
                    onClick={() => remove(record.name)}
                    tabIndex={0}
                  />

                  {Simple_Inventory.treatment === "on" && (
                    <BilllineAddInventory
                      disabled={!billEdit || form.isFieldsTouched() || form.getFieldValue("is_credit_memo")}
                      billline={currentLine}
                      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,
          wrapper: col.wrapper,
          skipFormItem: col.skipFormItem
        })
      };
    });

  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 }) => {
        const hasRows = fields.length > 0;

        return (
          <>
            <Table
              className="bill-lines-table"
              components={{ body: { cell: EditableCell } }}
              size="small"
              bordered
              dataSource={fields}
              rowKey="key"
              columns={mergedColumns(remove)}
              scroll={hasRows ? { x: "max-content" } : undefined}
              pagination={false}
              rowClassName="editable-row"
            />

            <div style={{ marginTop: 12 }}>
              <Form.Item style={{ marginBottom: 0 }}>
                <Button
                  disabled={disabled}
                  onClick={() => {
                    const newIndex = fields.length;
                    add(
                      InstanceRenderManager({
                        imex: { applicable_taxes: { federal: true } },
                        rome: { applicable_taxes: { federal: false } }
                      })
                    );
                    setTimeout(() => {
                      const firstField = firstFieldRefs.current[newIndex];
                      if (firstField?.focus) {
                        firstField.focus();
                      }
                    }, 100);
                  }}
                  style={{ width: "100%" }}
                >
                  {t("billlines.actions.newline")}
                </Button>
              </Form.Item>
            </div>
          </>
        );
      }}
    </Form.List>
  );
}

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

const EditableCell = ({
  record,
  children,
  formInput,
  formItemProps,
  additional,
  wrapper: Wrapper,
  skipFormItem,
  ...restProps
}) => {
  const rawProps = formItemProps?.(record);

  const propsFinal = rawProps
    ? (() => {
        // eslint-disable-next-line no-unused-vars
        const { key, ...rest } = rawProps;
        return rest;
      })()
    : undefined;

  const control = skipFormItem ? (
    (formInput && formInput(record, record.name, propsFinal)) || children
  ) : (
    <Form.Item labelCol={{ span: 0 }} {...propsFinal} style={{ marginBottom: 0 }}>
      {(formInput && formInput(record, record.name, propsFinal)) || children}
    </Form.Item>
  );

  const cellInner = additional ? (
    <div>
      {control}
      {additional(record, record.name)}
    </div>
  ) : (
    control
  );

  const { style: tdStyle, ...tdRest } = restProps;

  const td = (
    <td {...tdRest} style={{ ...tdStyle, verticalAlign: "middle" }}>
      {cellInner}
    </td>
  );

  if (Wrapper) return <Wrapper>{td}</Wrapper>;
  return td;
};
