import { DeleteFilled, EyeFilled, SyncOutlined } from "@ant-design/icons";
import { useMutation } from "@apollo/client/react";
import { Button, Card, Checkbox, Input, Popconfirm, Space } from "antd";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { FaTasks } from "react-icons/fa";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { logImEXEvent } from "../../firebase/firebase.utils";
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 { DateFormatter } from "../../utils/DateFormatter";
import { TemplateList } from "../../utils/TemplateConstants";
import { alphaSort } from "../../utils/sorters";
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
import LockWrapperComponent from "../lock-wrapper/lock-wrapper.component";
import PartsReceiveModalContainer from "../parts-receive-modal/parts-receive-modal.container";
import PrintWrapper from "../print-wrapper/print-wrapper.component";
import PartsOrderDrawer from "./parts-order-list-table-drawer.component";
import ShareToTeamsButton from "../share-to-teams/share-to-teams.component.jsx";
import { bodyshopHasDmsKey } from "../../utils/dmsUtils.js";
import ResponsiveTable from "../responsive-table/responsive-table.component";

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 PartsOrderListTableComponent({
  setBillEnterContext,
  bodyshop,
  jobRO,
  job,
  billsQuery,
  handleOnRowClick,
  setPartsReceiveContext,
  setTaskUpsertContext,
  isPartsEntry
}) {
  const responsibilityCenters = bodyshop.md_responsibility_centers;
  const Templates = TemplateList("partsorder", { job });

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

  const [searchText, setSearchText] = useState("");
  const [deletePartsOrder] = useMutation(DELETE_PARTS_ORDER);

  const parts_orders = billsQuery.data ? billsQuery.data.parts_orders : [];

  const enrichedPartsOrders = parts_orders.map((order) => ({
    ...order,
    invoice_number: order.bill?.invoice_number
  }));

  const { refetch } = billsQuery;

  const recordActions = (record, showView = false) => (
    <Space orientation="horizontal" wrap>
      <ShareToTeamsButton
        linkText={""}
        urlOverride={`${window.location.origin}/manage/jobs/${job.id}?partsorderid=${record.id}&tab=partssublet `}
      />
      {showView && (
        <Button
          icon={<EyeFilled />}
          onClick={() => {
            handleOnRowClick(record);
          }}
        />
      )}
      <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) => {
                return {
                  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")}
          icon={<FaTasks />}
          onClick={() => {
            setTaskUpsertContext({
              context: {
                jobid: job.id,
                partsorderid: record.id
              }
            });
          }}
        />
      )}

      <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) => {
                    return {
                      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 columns = [
    {
      title: t("vendors.fields.name"),
      dataIndex: "vendorname",
      key: "vendorname",
      sorter: (a, b) => alphaSort(a.vendor.name, b.vendor.name),
      sortOrder: state.sortedInfo.columnKey === "vendorname" && state.sortedInfo.order,
      render: (text, record) => <span>{record.vendor.name}</span>
    },
    {
      title: t("parts_orders.fields.order_number"),
      dataIndex: "order_number",
      key: "order_number",
      sorter: (a, b) => alphaSort(a.invoice_number, b.invoice_number),
      sortOrder: state.sortedInfo.columnKey === "invoice_number" && state.sortedInfo.order,
      render: (text, record) => (
        <span>
          {record.order_number} {record.invoice_number && `(${record.invoice_number})`}
        </span>
      )
    },
    {
      title: t("parts_orders.fields.order_date"),
      dataIndex: "order_date",
      key: "order_date",
      sorter: (a, b) => a.order_date - b.order_date,
      sortOrder: state.sortedInfo.columnKey === "order_date" && state.sortedInfo.order,
      render: (text, record) => <DateFormatter>{record.order_date}</DateFormatter>
    }
  ];

  if (!isPartsEntry) {
    columns.push({
      title: t("parts_orders.fields.return"),
      dataIndex: "return",
      key: "return",
      sorter: (a, b) => a.return - b.return,
      sortOrder: state.sortedInfo.columnKey === "return" && state.sortedInfo.order,
      render: (text, record) => <Checkbox checked={record.return} />
    });
  }

  columns.push(
    {
      title: t("parts_orders.fields.deliver_by"),
      dataIndex: "deliver_by",
      key: "deliver_by",
      sorter: (a, b) => a.deliver_by - b.deliver_by,
      sortOrder: state.sortedInfo.columnKey === "deliver_by" && state.sortedInfo.order,
      render: (text, record) => <DateFormatter>{record.deliver_by}</DateFormatter>
    },
    {
      title: t("parts_orders.fields.orderedby"),
      dataIndex: "orderedby",
      key: "orderedby"
    },
    {
      title: t("general.labels.actions"),
      dataIndex: "actions",
      key: "actions",
      render: (text, record) => recordActions(record, true),
      id: "parts-order-list-table-actions"
    }
  );

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

  const filteredPartsOrders = enrichedPartsOrders
    ? searchText === ""
      ? enrichedPartsOrders
      : enrichedPartsOrders.filter(
          (b) =>
            (b.order_number || "").toString().toLowerCase().includes(searchText.toLowerCase()) ||
            (b.vendor.name || "").toLowerCase().includes(searchText.toLowerCase())
        )
    : [];

  return (
    <Card
      title={t("parts_orders.labels.parts_orders")}
      extra={
        <Space wrap>
          <Button onClick={() => refetch()}>
            <SyncOutlined />
          </Button>
          <Input.Search
            placeholder={t("general.labels.search")}
            value={searchText}
            onChange={(e) => {
              e.preventDefault();
              setSearchText(e.target.value);
            }}
            enterButton
          />
        </Space>
      }
    >
      <PartsReceiveModalContainer />
      <PartsOrderDrawer
        job={job}
        billsQuery={billsQuery}
        handleOnRowClick={handleOnRowClick}
        setPartsReceiveContext={setPartsReceiveContext}
        setTaskUpsertContext={setTaskUpsertContext}
      />
      <ResponsiveTable
        loading={billsQuery.loading}
        scroll={{
          x: true
          //y: "50rem"
        }}
        columns={columns}
        mobileColumnKeys={["vendorname", "order_number", "order_date", "actions"]}
        rowKey="id"
        dataSource={filteredPartsOrders}
        onChange={handleTableChange}
      />
    </Card>
  );
}

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