import { EditFilled, SyncOutlined } from "@ant-design/icons";
import { Button, Card, Checkbox, Input, Space, Table, Typography } from "antd";
import { useQuery } from "@apollo/client";
import axios from "axios";
import queryString from "query-string";
import { 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 { pageLimit } from "../../utils/config";
import { alphaSort, dateSort } from "../../utils/sorters";
import { QUERY_ALL_VENDORS } from "../../graphql/vendors.queries";
import { logImEXEvent } from "../../firebase/firebase.utils";

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

export function BillsListPage({ loading, data, refetch, total, setBillEnterContext, handleTableChange, sortedInfo }) {
  const search = queryString.parse(useLocation().search);
  const [openSearchResults, setOpenSearchResults] = useState([]);
  const [searchLoading, setSearchLoading] = useState(false);
  const { page } = search;
  const history = useNavigate();
  const Templates = TemplateList("bill");
  const { t } = useTranslation();

  const { data: vendorsData } = useQuery(QUERY_ALL_VENDORS);

  const columns = [
    {
      title: t("bills.fields.vendorname"),
      dataIndex: "vendorname",
      key: "vendorname",
      sorter: (a, b) => alphaSort(a.vendor.name, b.vendor.name),
      sortObject: (order) => ({
        vendor: { name: order === "descend" ? "desc" : "asc" }
      }),
      filters: (vendorsData?.vendors || []).map((v) => ({ text: v.name, value: v.id })),
      filteredValue: search.vendorIds ? search.vendorIds.split(",") : null,
      sortOrder: sortedInfo.columnKey === "vendorname" && 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: sortedInfo.columnKey === "invoice_number" && sortedInfo.order
    },
    {
      title: t("jobs.fields.ro_number"),
      dataIndex: "ro_number",
      key: "ro_number",
      sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number),
      sortObject: (order) => ({
        job: { ro_number: order === "descend" ? "desc" : "asc" }
      }),
      sortOrder: sortedInfo.columnKey === "ro_number" && 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: sortedInfo.columnKey === "date" && 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: sortedInfo.columnKey === "total" && 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: sortedInfo.columnKey === "is_credit_memo" && 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: sortedInfo.columnKey === "exported" && 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>
      )
    }
  ];

  // (State & URL handling moved to container - Option C)

  useEffect(() => {
    if (search.search && search.search.trim() !== "") {
      searchBills();
    }
  }, []);

  async function searchBills(value) {
    try {
      setSearchLoading(true);
      const searchData = await axios.post("/search", {
        search: value || search.search,
        index: "bills"
      });
      logImEXEvent("bills_search", { search: value || search.search, results: searchData?.data?.hits?.hits?.length });
      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);
