import { SyncOutlined } from "@ant-design/icons";
import { useQuery } from "@apollo/client/react";
import { Button, Card, Checkbox, Input, Space } from "antd";
import _ from "lodash";
import queryString from "query-string";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { Link, useLocation, useNavigate } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import { QUERY_PARTS_QUEUE } from "../../graphql/jobs.queries";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { DateTimeFormatter, TimeAgoFormatter } from "../../utils/DateFormatter";
import { onlyUnique } from "../../utils/arrayHelper";
import { pageLimit } from "../../utils/config";
import { alphaSort, dateSort } from "../../utils/sorters";
import useLocalStorage from "../../utils/useLocalStorage";
import AlertComponent from "../alert/alert.component";
import JobRemoveFromPartsQueue from "../job-remove-from-parst-queue/job-remove-from-parts-queue.component";
import OwnerNameDisplay, { OwnerNameDisplayFunction } from "../owner-name-display/owner-name-display.component";
import ProductionListColumnComment from "../production-list-columns/production-list-columns.comment.component";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import { logImEXEvent } from "../../firebase/firebase.utils";
import JobPartsReceived from "../job-parts-received/job-parts-received.component";

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

export function PartsQueueListComponent({ bodyshop }) {
  const searchParams = queryString.parse(useLocation().search);
  const { selected, sortcolumn, sortorder, statusFilters, page, pageSize } = searchParams;
  const currentPage = Number.parseInt(page || "1", 10);
  const parsedPageSize = Number.parseInt(pageSize || String(pageLimit), 10);
  const currentPageSize = Number.isNaN(parsedPageSize) ? pageLimit : parsedPageSize;
  const history = useNavigate();
  const [filter, setFilter] = useLocalStorage("filter_parts_queue", null);
  const [viewTimeStamp, setViewTimeStamp] = useLocalStorage("parts_queue_timestamps", false);
  const [countsOnly, setCountsOnly] = useLocalStorage("parts_queue_counts_only", false);

  const { loading, error, data, refetch } = useQuery(QUERY_PARTS_QUEUE, {
    fetchPolicy: "network-only",
    nextFetchPolicy: "network-only",
    variables: {
      statuses: (statusFilters && JSON.parse(statusFilters)) ||
        bodyshop.md_ro_statuses.active_statuses || ["Open", "Open*"]
    }
  });

  const { t } = useTranslation();
  const [searchText, setSearchText] = useState("");

  if (error) return <AlertComponent title={error.message} type="error" />;

  const jobs = data
    ? searchText === ""
      ? data.jobs
      : data.jobs.filter(
          (j) =>
            (j.ro_number || "").toString().toLowerCase().includes(searchText.toLowerCase()) ||
            (j.ownr_co_nm || "").toLowerCase().includes(searchText.toLowerCase()) ||
            (j.ownr_fn || "").toLowerCase().includes(searchText.toLowerCase()) ||
            (j.ownr_ln || "").toLowerCase().includes(searchText.toLowerCase()) ||
            (j.clm_no || "").toLowerCase().includes(searchText.toLowerCase()) ||
            (j.plate_no || "").toLowerCase().includes(searchText.toLowerCase()) ||
            (j.v_model_desc || "").toLowerCase().includes(searchText.toLowerCase()) ||
            (j.v_make_desc || "").toLowerCase().includes(searchText.toLowerCase())
        )
    : [];

  const handleTableChange = (pagination, filters, sorter) => {
    const nextPageSize = pagination?.pageSize || currentPageSize;
    const pageSizeChanged = nextPageSize !== currentPageSize;

    searchParams.pageSize = nextPageSize;
    searchParams.page = pageSizeChanged ? 1 : pagination.current;
    searchParams.sortcolumn = sorter.columnKey;
    searchParams.sortorder = sorter.order;

    if (filters.status) {
      searchParams.statusFilters = JSON.stringify(_.flattenDeep(filters.status));
    } else {
      delete searchParams.statusFilters;
    }
    setFilter(filters);
    history({ search: queryString.stringify(searchParams) });
    logImEXEvent("parts_queue_sort_filter", { pagination, filters, sorter });
  };

  const handleOnRowClick = (record) => {
    if (record?.id) {
      history({
        search: queryString.stringify({
          ...searchParams,
          selected: record.id
        })
      });
    }
  };
  const columns = [
    {
      title: t("jobs.fields.ro_number"),
      dataIndex: "ro_number",
      key: "ro_number",
      width: "110px",
      sorter: (a, b) => alphaSort(a.ro_number, b.ro_number),
      sortOrder: sortcolumn === "ro_number" && sortorder,

      render: (text, record) => (
        <Link to={"/manage/jobs/" + record.id}>{record.ro_number || t("general.labels.na")}</Link>
      )
    },
    {
      title: t("jobs.fields.owner"),
      dataIndex: "ownr_ln",
      key: "ownr_ln",
      width: "8%",
      ellipsis: {
        showTitle: true
      },
      sorter: (a, b) => alphaSort(OwnerNameDisplayFunction(a), OwnerNameDisplayFunction(b)),
      sortOrder: sortcolumn === "ownr_ln" && sortorder,
      render: (text, record) => {
        return record.ownerid ? (
          <Link to={"/manage/owners/" + record.ownerid}>
            <OwnerNameDisplay ownerObject={record} withToolTip />
          </Link>
        ) : (
          <span>
            <OwnerNameDisplay ownerObject={record} withToolTip />
          </span>
        );
      }
    },
    {
      title: t("jobs.fields.vehicle"),
      dataIndex: "vehicle",
      key: "vehicle",
      ellipsis: true,
      sorter: (a, b) =>
        alphaSort(
          `${a.v_model_yr || ""} ${a.v_make_desc || ""} ${a.v_model_desc || ""}`,
          `${b.v_model_yr || ""} ${b.v_make_desc || ""} ${b.v_model_desc || ""}`
        ),
      sortOrder: sortcolumn === "vehicle" && sortorder,
      render: (text, record) => {
        return record.vehicleid ? (
          <Link to={"/manage/vehicles/" + record.vehicleid}>
            {`${record.v_model_yr || ""} ${record.v_make_desc || ""} ${record.v_model_desc || ""}`}
          </Link>
        ) : (
          <span>{`${record.v_model_yr || ""} ${record.v_make_desc || ""} ${record.v_model_desc || ""}`}</span>
        );
      }
    },
    {
      title: t("jobs.fields.ins_co_nm_short"),
      dataIndex: "ins_co_nm",
      key: "ins_co_nm",
      ellipsis: true,
      sorter: (a, b) => alphaSort(a.ins_co_nm, b.ins_co_nm),
      sortOrder: sortcolumn === "ins_co_nm" && sortorder,
      filteredValue: filter?.ins_co_nm || null,
      filters:
        (jobs &&
          jobs
            .map((j) => j.ins_co_nm)
            .filter(onlyUnique)
            .map((s) => {
              return {
                text: s || "No Ins. Co.*",
                value: [s]
              };
            })
            .sort((a, b) => alphaSort(a.text, b.text))) ||
        [],
      onFilter: (value, record) => value.includes(record.ins_co_nm)
    },
    {
      title: t("jobs.fields.status"),
      dataIndex: "status",
      key: "status",
      sorter: (a, b) => alphaSort(a.status, b.status),
      sortOrder: sortcolumn === "status" && sortorder,
      filteredValue: statusFilters ? JSON.parse(statusFilters) : null,
      filters:
        bodyshop.md_ro_statuses.active_statuses.map((s) => {
          return {
            text: s || t("dashboard.errors.status"),
            value: [s]
          };
        }) || [],
      render: (text, record) => {
        return record.status || t("general.labels.na");
      }
    },

    {
      title: t("jobs.fields.scheduled_in"),
      dataIndex: "scheduled_in",
      key: "scheduled_in",
      ellipsis: true,
      sorter: (a, b) => dateSort(a.scheduled_in, b.scheduled_in),
      sortOrder: sortcolumn === "scheduled_in" && sortorder,
      render: (text, record) => <DateTimeFormatter hideTime={!viewTimeStamp}>{record.scheduled_in}</DateTimeFormatter>
    },
    {
      title: t("jobs.fields.scheduled_completion"),
      dataIndex: "scheduled_completion",
      key: "scheduled_completion",
      ellipsis: true,
      sorter: (a, b) => dateSort(a.scheduled_completion, b.scheduled_completion),
      sortOrder: sortcolumn === "scheduled_completion" && sortorder,
      render: (text, record) => (
        <DateTimeFormatter hideTime={!viewTimeStamp}>{record.scheduled_completion}</DateTimeFormatter>
      )
    },
    // {
    //   title: t("vehicles.fields.plate_no"),
    //   dataIndex: "plate_no",
    //   key: "plate_no",
    //   sorter: (a, b) => alphaSort(a.plate_no, b.plate_no),
    //   sortOrder: sortcolumn === "plate_no" && sortorder,
    //   render: (text, record) => {
    //     return record.plate_no ? record.plate_no : "";
    //   },

    //},
    // {
    //   title: t("jobs.fields.clm_total"),
    //   dataIndex: "clm_total",
    //   key: "clm_total",
    //   sorter: (a, b) => a.clm_total - b.clm_total,
    //   sortOrder: sortcolumn === "clm_total" && sortorder,
    //   render: (text, record) => {
    //     return record.clm_total ? (
    //       <CurrencyFormatter>{record.clm_total}</CurrencyFormatter>
    //     ) : (
    //       t("general.labels.unknown")
    //     );
    //   },
    // },
    {
      title: t("jobs.fields.updated_at"),
      dataIndex: "updated_at",
      key: "updated_at",
      width: "110px",
      sorter: (a, b) => dateSort(a.updated_at, b.updated_at),
      sortOrder: sortcolumn === "updated_at" && sortorder,
      render: (text, record) => <TimeAgoFormatter removeAgoString>{record.updated_at}</TimeAgoFormatter>
    },
    {
      title: t("jobs.fields.partsstatus"),
      dataIndex: "partsstatus",
      key: "partsstatus",
      width: countsOnly ? "180px" : "110px",
      render: (text, record) => (
        <JobPartsReceived
          parts={record.joblines_status}
          displayMode="full"
          popoverPlacement="middle"
          countsOnly={countsOnly}
        />
      )
    },
    {
      title: t("jobs.fields.comment"),
      dataIndex: "comment",
      key: "comment",
      render: (text, record) => <ProductionListColumnComment record={record} />
    },
    {
      title: t("jobs.fields.queued_for_parts"),
      dataIndex: "queued_for_parts",
      key: "queued_for_parts",
      width: "120px",
      sorter: (a, b) => a.queued_for_parts - b.queued_for_parts,
      sortOrder: sortcolumn === "queued_for_parts" && sortorder,
      filteredValue: filter?.queued_for_parts || null,
      filters: [
        {
          text: "Queued",
          value: true
        },
        {
          text: "Unqueued",
          value: false
        }
      ],
      onFilter: (value, record) => record.queued_for_parts === value,
      render: (text, record) => <JobRemoveFromPartsQueue checked={record.queued_for_parts} jobId={record.id} />
    }
  ];

  return (
    <Card
      title={t("titles.bc.parts-queue")}
      extra={
        <Space wrap>
          <Button onClick={() => refetch()}>
            <SyncOutlined />
          </Button>
          <Checkbox checked={countsOnly} onChange={(e) => setCountsOnly(e.target.checked)}>
            {t("parts.labels.view_counts_only")}
          </Checkbox>
          <Checkbox checked={viewTimeStamp} onChange={(e) => setViewTimeStamp(e.target.checked)}>
            {t("parts.labels.view_timestamps")}
          </Checkbox>
          <Input.Search
            className="imex-table-header__search"
            placeholder={t("general.labels.search")}
            onChange={(e) => {
              setSearchText(e.target.value);
            }}
            value={searchText}
            enterButton
          />
        </Space>
      }
    >
      <ResponsiveTable
        loading={loading}
        pagination={{
          placement: "top",
          pageSize: currentPageSize,
          current: currentPage,
          showSizeChanger: true,
          total: jobs.length
        }}
        columns={columns}
        mobileColumnKeys={["ro_number", "ownr_ln", "status", "vehicle", "partsstatus"]}
        rowKey="id"
        dataSource={jobs}
        style={{ height: "100%" }}
        //scroll={{ x: true }}
        onChange={handleTableChange}
        rowSelection={{
          onSelect: (record) => {
            handleOnRowClick(record);
          },
          selectedRowKeys: [selected],
          type: "radio"
        }}
        onRow={() => {
          return {
            onClick: () => {
              //  NO OP
            }
          };
        }}
      />
    </Card>
  );
}

export default connect(mapStateToProps, null)(PartsQueueListComponent);
