import { EditFilled, SyncOutlined } from "@ant-design/icons";
import { Button, Card, Checkbox, Input, Space, Table, Typography } from "antd";
import axios from "axios";
import queryString from "query-string";
import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { Link, useLocation, useNavigate } from "react-router-dom";
import BillDeleteButton from "../../components/bill-delete-button/bill-delete-button.component";
import PartsOrderModalContainer from "../../components/parts-order-modal/parts-order-modal.container";
import PrintWrapperComponent from "../../components/print-wrapper/print-wrapper.component";
import { setModalContext } from "../../redux/modals/modals.actions";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
import { DateFormatter } from "../../utils/DateFormatter";
import { TemplateList } from "../../utils/TemplateConstants";
import { alphaSort, dateSort } from "../../utils/sorters";
import { pageLimit } from "../../utils/config";

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

export function BillsListPage({ loading, data, refetch, total, setPartsOrderContext, setBillEnterContext }) {
  const search = queryString.parse(useLocation().search);
  const [openSearchResults, setOpenSearchResults] = useState([]);
  const [searchLoading, setSearchLoading] = useState(false);
  const { page } = search;
  const history = useNavigate();
  const [state, setState] = useState({
    sortedInfo: {},
    filteredInfo: { text: "" }
  });
  const Templates = TemplateList("bill");
  const { t } = useTranslation();
  const columns = [
    {
      title: t("bills.fields.vendorname"),
      dataIndex: "vendorname",
      key: "vendorname",
      // sortObject: (direction) => {
      //   return {
      //     vendor: {
      //       name: direction
      //         ? direction === "descend"
      //           ? "desc"
      //           : "asc"
      //         : "desc",
      //     },
      //   };
      // },
      // 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("bills.fields.invoice_number"),
      dataIndex: "invoice_number",
      key: "invoice_number",
      sorter: (a, b) => alphaSort(a.invoice_number, b.invoice_number),
      sortOrder: state.sortedInfo.columnKey === "invoice_number" && state.sortedInfo.order
    },
    {
      title: t("jobs.fields.ro_number"),
      dataIndex: "ro_number",
      key: "ro_number",
      // sortObject: (direction) => {
      //   return {
      //     job: {
      //       ro_number: direction
      //         ? direction === "descend"
      //           ? "desc"
      //           : "asc"
      //         : "desc",
      //     },
      //   };
      // },
      // sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number),
      // sortOrder:
      //   state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order,
      render: (text, record) => record.job && <Link to={`/manage/jobs/${record.job.id}`}>{record.job.ro_number}</Link>
    },
    {
      title: t("bills.fields.date"),
      dataIndex: "date",
      key: "date",
      sorter: (a, b) => dateSort(a.date, b.date),
      sortOrder: state.sortedInfo.columnKey === "date" && state.sortedInfo.order,
      render: (text, record) => <DateFormatter>{record.date}</DateFormatter>
    },
    {
      title: t("bills.fields.total"),
      dataIndex: "total",
      key: "total",
      sorter: (a, b) => a.total - b.total,
      sortOrder: state.sortedInfo.columnKey === "total" && state.sortedInfo.order,
      render: (text, record) => <CurrencyFormatter>{record.total}</CurrencyFormatter>
    },
    {
      title: t("bills.fields.is_credit_memo"),
      dataIndex: "is_credit_memo",
      key: "is_credit_memo",
      sorter: (a, b) => a.is_credit_memo - b.is_credit_memo,
      sortOrder: state.sortedInfo.columnKey === "is_credit_memo" && state.sortedInfo.order,
      render: (text, record) => <Checkbox checked={record.is_credit_memo} />
    },
    {
      title: t("bills.fields.exported"),
      dataIndex: "exported",
      key: "exported",
      sorter: (a, b) => a.exported - b.exported,
      sortOrder: state.sortedInfo.columnKey === "exported" && state.sortedInfo.order,
      render: (text, record) => <Checkbox checked={record.exported} />
    },
    {
      title: t("general.labels.actions"),
      dataIndex: "actions",
      key: "actions",
      render: (text, record) => (
        <Space wrap>
          <Link to={`/manage/bills?billid=${record.id}`}>
            <Button>
              <EditFilled />
            </Button>
          </Link>
          {
            //  <Button
            //         disabled={record.is_credit_memo}
            //         onClick={() =>
            //           setPartsOrderContext({
            //             actions: {},
            //             context: {
            //               jobId: record.jobid,
            //               vendorId: record.vendorid,
            //               returnFromBill: record.id,
            //               invoiceNumber: record.invoice_number,
            //               linesToOrder: record.billlines.map((i) => {
            //                 return {
            //                   line_desc: i.line_desc,
            //                   //  db_price: i.actual_price,
            //                   act_price: i.actual_price,
            //                   cost: i.actual_cost,
            //                   quantity: i.quantity,
            //                   joblineid: i.joblineid,
            //                 };
            //               }),
            //               isReturn: true,
            //             },
            //           })
            //         }
            //       >
            //         {t("bills.actions.return")}
            //       </Button>
          }
          <BillDeleteButton
            bill={record}
            callback={(deletedBillid) => {
              //Filter out the state and set it again.
              setOpenSearchResults((currentResults) => currentResults.filter((bill) => bill.id !== deletedBillid));
            }}
          />
          {record.isinhouse && (
            <PrintWrapperComponent
              templateObject={{
                name: Templates.inhouse_invoice.key,
                variables: { id: record.id }
              }}
              messageObject={{ subject: Templates.inhouse_invoice.subject }}
            />
          )}
        </Space>
      )
    }
  ];

  const handleTableChange = (pagination, filters, sorter) => {
    setState({ ...state, filteredInfo: filters, sortedInfo: sorter });
    search.page = pagination.current;
    if (sorter && sorter.column && sorter.column.sortObject) {
      search.searchObj = JSON.stringify(sorter.column.sortObject(sorter.order));
    } else {
      delete search.searchObj;
      search.sortcolumn = sorter.order ? sorter.columnKey : null;
      search.sortorder = sorter.order;
    }
    search.sort = JSON.stringify({ [sorter.columnKey]: sorter.order });
    history({ search: queryString.stringify(search) });
  };

  useEffect(() => {
    if (search.search && search.search.trim() !== "") {
      searchBills();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  async function searchBills(value) {
    try {
      setSearchLoading(true);
      const searchData = await axios.post("/search", {
        search: value || search.search,
        index: "bills"
      });
      setOpenSearchResults(searchData.data.hits.hits.map((s) => s._source));
    } catch (error) {
      console.log("Error while fetching search results", error);
    } finally {
      setSearchLoading(false);
    }
  }

  return (
    <Card
      title={t("bills.labels.bills")}
      extra={
        <Space wrap>
          {search.search && (
            <Space align="center">
              <Typography.Title level={4}>
                {t("general.labels.searchresults", { search: search.search })}
              </Typography.Title>
              <Button
                onClick={() => {
                  delete search.search;
                  delete search.page;
                  history({ search: queryString.stringify(search) });
                }}
              >
                {t("general.actions.clear")}
              </Button>
            </Space>
          )}
          <Button onClick={() => refetch()}>
            <SyncOutlined />
          </Button>
          <Button
            onClick={() => {
              setBillEnterContext({
                actions: { refetch: refetch },
                context: {}
              });
            }}
          >
            {t("jobs.actions.postbills")}
          </Button>

          <Input.Search
            placeholder={search.search || t("general.labels.search")}
            onSearch={(value) => {
              search.search = value;
              history({ search: queryString.stringify(search) });
              searchBills(value);
            }}
            loading={loading || searchLoading}
            enterButton
          />
        </Space>
      }
    >
      <PartsOrderModalContainer />

      <Table
        loading={loading || searchLoading}
        // scroll={{
        //   x: "50%", // y: "40rem"
        // }}
        scroll={{ x: true }}
        pagination={
          search?.search
            ? {
                pageSize: pageLimit,
                showSizeChanger: false
              }
            : {
                pageSize: pageLimit,
                current: parseInt(page || 1),
                total: total,
                showSizeChanger: false
              }
        }
        columns={columns}
        rowKey="id"
        dataSource={search?.search ? openSearchResults : data}
        onChange={handleTableChange}
      />
    </Card>
  );
}

export default connect(null, mapDispatchToProps)(BillsListPage);
