import { DeleteFilled } from "@ant-design/icons";
import { PageHeader } from "@ant-design/pro-layout";
import { useLazyQuery, useMutation } from "@apollo/client/react";
import { Button, Drawer, Grid, Popconfirm, Space } from "antd";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import queryString from "query-string";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { FaTasks } from "react-icons/fa";
import { connect } from "react-redux";
import { useLocation } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import { logImEXEvent } from "../../firebase/firebase.utils";
import { QUERY_BILL_BY_PK } from "../../graphql/bills.queries";
import { DELETE_PARTS_ORDER } from "../../graphql/parts-orders.queries";
import { selectIsPartsEntry, selectJobReadOnly } from "../../redux/application/application.selectors";
import { setModalContext } from "../../redux/modals/modals.actions";
import { selectBodyshop } from "../../redux/user/user.selectors";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
import { DateFormatter } from "../../utils/DateFormatter";
import { TemplateList } from "../../utils/TemplateConstants";
import { alphaSort } from "../../utils/sorters";
import DataLabel from "../data-label/data-label.component";
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
import LockWrapperComponent from "../lock-wrapper/lock-wrapper.component";
import PartsOrderBackorderEta from "../parts-order-backorder-eta/parts-order-backorder-eta.component";
import PartsOrderCmReceived from "../parts-order-cm-received/parts-order-cm-received.component";
import PartsOrderDeleteLine from "../parts-order-delete-line/parts-order-delete-line.component";
import PartsOrderLineBackorderButton from "../parts-order-line-backorder-button/parts-order-line-backorder-button.component";
import PartsReceiveModalContainer from "../parts-receive-modal/parts-receive-modal.container";
import PrintWrapper from "../print-wrapper/print-wrapper.component";
import { bodyshopHasDmsKey } from "../../utils/dmsUtils.js";

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

const mapDispatchToProps = (dispatch) => ({
  setBillEnterContext: (context) =>
    dispatch(
      setModalContext({
        context: context,
        modal: "billEnter"
      })
    ),
  setPartsReceiveContext: (context) =>
    dispatch(
      setModalContext({
        context: context,
        modal: "partsReceive"
      })
    ),
  setTaskUpsertContext: (context) => dispatch(setModalContext({ context, modal: "taskUpsert" }))
});

export function PartsOrderListTableDrawerComponent({
  setBillEnterContext,
  bodyshop,
  jobRO,
  job,
  billsQuery,
  handleOnRowClick,
  setPartsReceiveContext,
  setTaskUpsertContext,
  isPartsEntry
}) {
  const screens = Grid.useBreakpoint();

  const bpoints = {
    xs: "100%",
    sm: "100%",
    md: "100%",
    lg: "75%",
    xl: "75%",
    xxl: "65%"
  };

  let drawerPercentage = "100%";
  if (screens.xxl) drawerPercentage = bpoints.xxl;
  else if (screens.xl) drawerPercentage = bpoints.xl;
  else if (screens.lg) drawerPercentage = bpoints.lg;
  else if (screens.md) drawerPercentage = bpoints.md;
  else if (screens.sm) drawerPercentage = bpoints.sm;
  else if (screens.xs) drawerPercentage = bpoints.xs;
  const responsibilityCenters = bodyshop.md_responsibility_centers;
  const Templates = TemplateList("partsorder", { job });

  const { t } = useTranslation();
  const [state, setState] = useState({
    sortedInfo: {}
  });

  const [billData, setBillData] = useState(null);
  const search = queryString.parse(useLocation().search);
  const selectedpartsorder = search.partsorderid;

  const [deletePartsOrder] = useMutation(DELETE_PARTS_ORDER);
  const parts_orders = billsQuery.data ? billsQuery.data.parts_orders : [];
  const { refetch } = billsQuery;
  const [billQuery] = useLazyQuery(QUERY_BILL_BY_PK);
  const selectedPartsOrderRecord = parts_orders.find((r) => r.id === selectedpartsorder);

  useEffect(() => {
    const fetchData = async () => {
      if (selectedPartsOrderRecord?.returnfrombill) {
        try {
          const { data } = await billQuery({
            variables: {
              billid: selectedPartsOrderRecord.returnfrombill
            }
          });
          setBillData(data);
        } catch (error) {
          console.error("Error fetching bill data:", error);
        }
      } else setBillData(null);
    };
    fetchData();
  }, [selectedPartsOrderRecord, billQuery]);

  const recordActions = (record) => (
    <Space orientation="horizontal" wrap>
      <Button
        disabled={jobRO || record.return || record.vendor.id === bodyshop.inhousevendorid}
        onClick={() => {
          logImEXEvent("parts_order_receive_bill");
          setPartsReceiveContext({
            actions: { refetch: refetch },
            context: {
              jobId: job.id,
              job: job,
              partsorderlines: record.parts_order_lines.map((pol) => ({
                joblineid: pol.job_line_id,
                id: pol.id,
                line_desc: pol.line_desc,
                quantity: pol.quantity,
                act_price: pol.act_price,
                oem_partno: pol.oem_partno
              }))
            }
          });
        }}
      >
        {t("parts_orders.actions.receive")}
      </Button>
      {!isPartsEntry && (
        <Button
          title={t("tasks.buttons.create")}
          onClick={() => {
            setTaskUpsertContext({
              context: {
                jobid: job.id,
                partsorderid: record.id
              }
            });
          }}
          icon={<FaTasks />}
        />
      )}
      <Popconfirm
        title={t("parts_orders.labels.confirmdelete")}
        disabled={jobRO}
        onConfirm={async () => {
          //Delete the parts return.!
          await deletePartsOrder({
            variables: { partsOrderId: record.id },
            update(cache) {
              cache.modify({
                fields: {
                  parts_orders(existingPartsOrders, { readField }) {
                    return existingPartsOrders.filter((billref) => record.id !== readField("id", billref));
                  }
                }
              });
            }
          });
        }}
      >
        <Button disabled={jobRO} icon={<DeleteFilled />} />
      </Popconfirm>
      {!isPartsEntry && (
        <Button
          disabled={
            (jobRO ? !record.return : jobRO) ||
            record.vendor.id === bodyshop.inhousevendorid ||
            !HasFeatureAccess({ bodyshop, featureName: "bills" })
          }
          onClick={() => {
            logImEXEvent("parts_order_receive_bill");
            setBillEnterContext({
              actions: { refetch: refetch },
              context: {
                job: job,
                parts_order: { id: record.id },
                bill: {
                  vendorid: record.vendor.id,
                  is_credit_memo: record.return,
                  billlines: record.parts_order_lines.map((pol) => ({
                    joblineid: pol.job_line_id || "noline",
                    line_desc: pol.line_desc,
                    quantity: pol.quantity,
                    actual_price: pol.act_price,
                    cost_center: pol.jobline?.part_type
                      ? bodyshopHasDmsKey(bodyshop)
                        ? pol.jobline.part_type !== "PAE"
                          ? pol.jobline.part_type
                          : null
                        : responsibilityCenters.defaults &&
                          (responsibilityCenters.defaults.costs[pol.jobline.part_type] || null)
                      : null
                  }))
                }
              }
            });
          }}
        >
          <LockWrapperComponent featureName="bills">{t("parts_orders.actions.receivebill")}</LockWrapperComponent>
        </Button>
      )}

      <PrintWrapper
        templateObject={{
          name: record.return ? Templates.parts_return_slip.key : Templates.parts_order.key,
          variables: { id: record.id }
        }}
        messageObject={{
          subject: record.return ? Templates.parts_return_slip.subject : Templates.parts_order.subject,
          to: record.vendor.email
        }}
        id={job.id}
      />
    </Space>
  );

  const handleTableChange = (pagination, filters, sorter) => {
    setState({ ...state, filteredInfo: filters, sortedInfo: sorter });
  };

  const rowExpander = (record) => {
    const columns = [
      {
        title: t("parts_orders.fields.line_desc"),
        dataIndex: "line_desc",
        key: "line_desc",
        sorter: (a, b) => alphaSort(a.line_desc, b.line_desc),
        sortOrder: state.sortedInfo.columnKey === "line_desc" && state.sortedInfo.order
      },
      {
        title: t("parts_orders.fields.quantity"),
        dataIndex: "quantity",
        key: "quantity",
        sorter: (a, b) => a.quantity - b.quantity,
        sortOrder: state.sortedInfo.columnKey === "quantity" && state.sortedInfo.order
      },
      {
        title: t("parts_orders.fields.act_price"),
        dataIndex: "act_price",
        key: "act_price",
        sorter: (a, b) => a.act_price - b.act_price,
        sortOrder: state.sortedInfo.columnKey === "act_price" && state.sortedInfo.order,
        render: (text, record) => <CurrencyFormatter>{record.act_price}</CurrencyFormatter>
      },
      ...(selectedPartsOrderRecord && selectedPartsOrderRecord.return
        ? [
            {
              title: t("parts_orders.fields.cost"),
              dataIndex: "cost",
              key: "cost",
              sorter: (a, b) => a.cost - b.cost,
              sortOrder: state.sortedInfo.columnKey === "cost" && state.sortedInfo.order,
              render: (text, record) => <CurrencyFormatter>{record.cost}</CurrencyFormatter>
            }
          ]
        : []),
      {
        title: t("parts_orders.fields.part_type"),
        dataIndex: "part_type",
        key: "part_type",
        render: (text, record) => (record.part_type ? t(`joblines.fields.part_types.${record.part_type}`) : null)
      },
      {
        title: t("parts_orders.fields.oem_partno"),
        dataIndex: "oem_partno",
        key: "oem_partno",
        sorter: (a, b) => alphaSort(a.oem_partno, b.oem_partno),
        sortOrder: state.sortedInfo.columnKey === "oem_partno" && state.sortedInfo.order
      },
      {
        title: t("parts_orders.fields.line_remarks"),
        dataIndex: "line_remarks",
        key: "line_remarks"
      },
      {
        title: t("parts_orders.fields.status"),
        dataIndex: "status",
        key: "status"
      },

      ...(selectedPartsOrderRecord && selectedPartsOrderRecord.return
        ? [
            {
              title: t("parts_orders.fields.cm_received"),
              dataIndex: "cm_received",
              key: "cm_received",
              render: (text, record) => (
                <PartsOrderCmReceived
                  orderLineId={record.id}
                  checked={record.cm_received}
                  partsorderid={selectedPartsOrderRecord.id}
                />
              )
            }
          ]
        : []),
      {
        title: t("parts_orders.fields.backordered_on"),
        dataIndex: "backordered_on",
        key: "backordered_on",
        render: (text) => <DateFormatter>{text}</DateFormatter>
      },
      {
        title: t("parts_orders.fields.backordered_eta"),
        dataIndex: "backordered_eta",
        key: "backordered_eta",
        render: (text, record) => (
          <PartsOrderBackorderEta
            backordered_eta={record.backordered_eta}
            disabled={jobRO}
            partsOrderStatus={record.status}
            partsLineId={record.id}
            jobLineId={record.job_line_id}
          />
        )
      },

      {
        title: t("general.labels.actions"),
        dataIndex: "actions",
        key: "actions",
        render: (text, record) => (
          <Space wrap>
            <PartsOrderDeleteLine
              disabled={jobRO}
              partsOrderStatus={record.status}
              partsLineId={record.id}
              partsOrderId={selectedpartsorder}
              jobLineId={record.job_line_id}
            />
            <PartsOrderLineBackorderButton
              disabled={jobRO}
              partsOrderStatus={record.status}
              partsLineId={record.id}
              jobLineId={record.job_line_id}
            />
          </Space>
        )
      }
    ];

    return (
      <div>
        <PageHeader
          title={
            billData
              ? `${record.vendor.name} - ${record.order_number} - ${t("bills.labels.returnfrombill")}: ${billData.bills_by_pk.invoice_number}`
              : `${record.vendor.name} - ${record.order_number}`
          }
          extra={recordActions(record)}
        />
        <ResponsiveTable
          scroll={{
            x: true //y: "50rem"
          }}
          columns={columns}
          mobileColumnKeys={["status", "line_desc", "actions", "quantity"]}
          rowKey="id"
          dataSource={record.parts_order_lines}
          onChange={handleTableChange}
        />
        <DataLabel label={t("parts_orders.fields.comments")}>
          <div style={{ whiteSpace: "pre" }}>{record.comments}</div>
        </DataLabel>
      </div>
    );
  };

  return (
    <div>
      <PartsReceiveModalContainer />
      <Drawer
        placement="right"
        onClose={() => handleOnRowClick(null)}
        open={selectedpartsorder}
        closable
        size={drawerPercentage}
      >
        {selectedPartsOrderRecord && rowExpander(selectedPartsOrderRecord)}
      </Drawer>
    </div>
  );
}

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