import { DeleteFilled, EyeFilled, SyncOutlined } from "@ant-design/icons";
import { useMutation } from "@apollo/client";
import {
  Button,
  Card,
  Checkbox,
  Drawer,
  Grid,
  Input,
  PageHeader,
  Popconfirm,
  Space,
  Table,
} from "antd";
import queryString from "query-string";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { useLocation } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import { logImEXEvent } from "../../firebase/firebase.utils";
import { DELETE_PARTS_ORDER } from "../../graphql/parts-orders.queries";
import { 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 { alphaSort } from "../../utils/sorters";
import { TemplateList } from "../../utils/TemplateConstants";
import DataLabel from "../data-label/data-label.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";

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

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

export function PartsOrderListTableComponent({
  setBillEnterContext,
  bodyshop,
  jobRO,
  job,
  billsQuery,
  handleOnRowClick,
  setPartsReceiveContext,
}) {
  const selectedBreakpoint = Object.entries(Grid.useBreakpoint())
    .filter((screen) => !!screen[1])
    .slice(-1)[0];

  const bpoints = {
    xs: "100%",
    sm: "100%",
    md: "100%",
    lg: "75%",
    xl: "75%",
    xxl: "65%",
  };
  const drawerPercentage = selectedBreakpoint
    ? bpoints[selectedBreakpoint[0]]
    : "100%";
  const responsibilityCenters = bodyshop.md_responsibility_centers;
  const Templates = TemplateList("partsorder", { job });

  const { t } = useTranslation();
  const [state, setState] = useState({
    sortedInfo: {},
  });
  const search = queryString.parse(useLocation().search);
  const selectedpartsorder = search.partsorderid;
  const [searchText, setSearchText] = useState("");

  const [deletePartsOrder] = useMutation(DELETE_PARTS_ORDER);

  const parts_orders = billsQuery.data ? billsQuery.data.parts_orders : [];
  const { refetch } = billsQuery;

  const recordActions = (record, showView = false) => (
    <Space wrap>
      {showView && (
        <Button onClick={() => handleOnRowClick(record)}>
          <EyeFilled />
        </Button>
      )}
      <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,
                };
              }),
            },
          });
        }}
      >
        {t("parts_orders.actions.receive")}
      </Button>
      <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}>
          <DeleteFilled />
        </Button>
      </Popconfirm>
      <Button
        disabled={
          (jobRO ? !record.return : jobRO) ||
          record.vendor.id === bodyshop.inhousevendorid
        }
        onClick={() => {
          logImEXEvent("parts_order_receive_bill");

          setBillEnterContext({
            actions: { refetch: refetch },
            context: {
              job: job,
              bill: {
                vendorid: record.vendor.id,
                is_credit_memo: record.return,
                billlines: record.parts_order_lines.map((pol) => {
                  return {
                    joblineid: pol.job_line_id,
                    line_desc: pol.line_desc,
                    quantity: pol.quantity,

                    actual_price: pol.act_price,

                    cost_center: pol.jobline?.part_type
                      ? bodyshop.pbs_serialnumber || bodyshop.cdk_dealerid
                        ? pol.jobline.part_type !== "PAE"
                          ? pol.jobline.part_type
                          : null
                        : responsibilityCenters.defaults &&
                          (responsibilityCenters.defaults.costs[
                            pol.jobline.part_type
                          ] ||
                            null)
                      : null,
                  };
                }),
              },
            },
          });
        }}
      >
        {t("parts_orders.actions.receivebill")}
      </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,
        }}
        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,
    },
    {
      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>
      ),
    },
    {
      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} />,
    },
    {
      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),
    },
  ];

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

  const selectedPartsOrderRecord = parts_orders.find(
    (r) => r.id === selectedpartsorder
  );

  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, record) => <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={record && `${record.vendor.name} - ${record.order_number}`}
          extra={recordActions(record)}
        />
        <Table
          scroll={{
            x: true, //y: "50rem"
          }}
          columns={columns}
          rowKey="id"
          dataSource={record.parts_order_lines}
        />
        <DataLabel label={t("parts_orders.fields.comments")}>
          <div style={{ whiteSpace: "pre" }}>{record.comments}</div>
        </DataLabel>
      </div>
    );
  };

  const filteredPartsOrders = parts_orders
    ? searchText === ""
      ? parts_orders
      : parts_orders.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);
            }}
          />
        </Space>
      }
    >
      <PartsReceiveModalContainer />
      <Drawer
        placement="right"
        onClose={() => handleOnRowClick(null)}
        visible={selectedpartsorder}
        closable
        width={drawerPercentage}
      >
        {selectedPartsOrderRecord && rowExpander(selectedPartsOrderRecord)}
      </Drawer>
      <Table
        loading={billsQuery.loading}
        scroll={{
          x: true,
          //y: "50rem"
        }}
        columns={columns}
        rowKey="id"
        dataSource={filteredPartsOrders}
        onChange={handleTableChange}
      />
    </Card>
  );
}
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(PartsOrderListTableComponent);
