"use client";
import { InventoryLotLineResult, InventoryResult } from "@/app/api/inventory";
import { useTranslation } from "react-i18next";
import SearchBox, { Criterion } from "../SearchBox";
import { useCallback, useEffect, useMemo, useState } from "react";
import { isEqual, orderBy, uniq, uniqBy } from "lodash";
import SearchResults, { Column } from "../SearchResults";
import { CheckCircleOutline, DoDisturb } from "@mui/icons-material";
import InventoryTable from "./InventoryTable";
import { defaultPagingController } from "../SearchResults/SearchResults";
import InventoryLotLineTable from "./InventoryLotLineTable";
import { SearchInventory, SearchInventoryLotLine, fetchInventories, fetchInventoryLotLines } from "@/app/api/inventory/actions";

interface Props {
  inventories: InventoryResult[];
}

type SearchQuery = Partial<
  Omit<
    InventoryResult,
    | "id"
    | "qty"
    | "uomCode"
    | "uomUdfudesc"
    | "germPerSmallestUnit"
    | "qtyPerSmallestUnit"
    | "itemSmallestUnit"
    | "price"
    | "description"
    | "category"
  >
>;
type SearchParamNames = keyof SearchQuery;

const InventorySearch: React.FC<Props> = ({ inventories }) => {
  const { t } = useTranslation(["inventory", "common"]);

  // Inventory
  const [filteredInventories, setFilteredInventories] = useState<InventoryResult[]>([]);
  const [inventoriesPagingController, setInventoriesPagingController] = useState(defaultPagingController)
  const [inventoriesTotalCount, setInventoriesTotalCount] = useState(0)
  const [selectedInventory, setSelectedInventory] = useState<InventoryResult | null>(null)

  // Inventory Lot Line
  const [filteredInventoryLotLines, setFilteredInventoryLotLines] = useState<InventoryLotLineResult[]>([]);
  const [inventoryLotLinesPagingController, setInventoryLotLinesPagingController] = useState(defaultPagingController)
  const [inventoryLotLinesTotalCount, setInventoryLotLinesTotalCount] = useState(0)

  const defaultInputs = useMemo(() => ({
    itemId: "",
    itemCode: "",
    itemName: "",
    itemType: "",
    onHandQty: "",
    onHoldQty: "",
    unavailableQty: "",
    availableQty: "",
    currencyName: "",
    status: "",
    baseUom: "",
  }), [])
  const [inputs, setInputs] = useState<Record<SearchParamNames, string>>(defaultInputs);

  const searchCriteria: Criterion<SearchParamNames>[] = useMemo(
    () => [
      { label: t("Code"), paramName: "itemCode", type: "text" },
      { label: t("Name"), paramName: "itemName", type: "text" },
      {
        label: t("Type"),
        paramName: "itemType",
        type: "select",
        options: uniq(inventories.map((i) => i.itemType)),
      },
      // {
      //   label: t("Status"),
      //   paramName: "status",
      //   type: "select",
      //   options: uniq(inventories.map((i) => i.status)),
      // },
    ],
    [t],
  );

  // Inventory
  const refetchInventoryData = useCallback(async (
    query: Record<SearchParamNames, string>,
    actionType: "reset" | "search" | "paging" | "init",
    pagingController: typeof defaultPagingController,
  ) => {
    console.log("%c Action Type 1.", "color:red", actionType)
    // Avoid loading data again
    if (actionType === "paging" && pagingController === defaultPagingController) {
      return
    }
    console.log("%c Action Type 2.", "color:blue", actionType)

    const params: SearchInventory = {
      code: query?.itemCode ?? '',
      name: query?.itemName ?? '',
      type: query?.itemType.toLowerCase() === "all" ? '' : query?.itemType ?? '',
      pageNum: pagingController.pageNum - 1,
      pageSize: pagingController.pageSize
    }

    const response = await fetchInventories(params)

    if (response) {
      setInventoriesTotalCount(response.total);
      switch (actionType) {
        case "init":
        case "reset":
        case "search":
          setFilteredInventories(() => response.records);
          break;
        case "paging":
          setFilteredInventories((fi) =>
            // orderBy(
              uniqBy([...fi, ...response.records], "id")
              // , ["id"], ["desc"])
              );
      }
    }
  }, [])

  useEffect(() => {
    refetchInventoryData(defaultInputs, "init", defaultPagingController)
  }, [])

  useEffect(() => {
    // if (!isEqual(inventoriesPagingController, defaultPagingController)) {
      refetchInventoryData(inputs, "paging", inventoriesPagingController)
    // }
  }, [inventoriesPagingController])

  // Inventory Lot Line
  const refetchInventoryLotLineData = useCallback(async (
    itemId: number | null,
    actionType: "reset" | "search" | "paging",
    pagingController: typeof defaultPagingController,
  ) => {
    if (!itemId) {
      setSelectedInventory(null)
      setInventoryLotLinesTotalCount(0);
      setFilteredInventoryLotLines([])
      return
    }

    // Avoid loading data again
    if (actionType === "paging" && pagingController === defaultPagingController) {
      return
    }

    const params: SearchInventoryLotLine = {
      itemId: itemId,
      pageNum: pagingController.pageNum - 1,
      pageSize: pagingController.pageSize
    }

    const response = await fetchInventoryLotLines(params)
    if (response) {
      setInventoryLotLinesTotalCount(response.total);
      switch (actionType) {
        case "reset":
        case "search":
          setFilteredInventoryLotLines(() => response.records);
          break;
        case "paging":
          setFilteredInventoryLotLines((fi) =>
            // orderBy(
              uniqBy([...fi, ...response.records], "id"),
              // ["id"], ["desc"])
              );
      }
    }
  }, [])

  useEffect(() => {
    // if (!isEqual(inventoryLotLinesPagingController, defaultPagingController)) {
      refetchInventoryLotLineData(selectedInventory?.itemId ?? null, "paging", inventoryLotLinesPagingController)
    // }
  }, [inventoryLotLinesPagingController])

  // Reset
  const onReset = useCallback(() => {
    refetchInventoryData(defaultInputs, "reset", defaultPagingController);
    refetchInventoryLotLineData(null, "reset", defaultPagingController);
    // setFilteredInventories(inventories);

    setInputs(() => defaultInputs)
    setInventoriesPagingController(() => defaultPagingController)
    setInventoryLotLinesPagingController(() => defaultPagingController)
  }, []);

  // Click Row
  const onInventoryRowClick = useCallback((item: InventoryResult) => {
    refetchInventoryLotLineData(item.itemId, "search", defaultPagingController)

    setSelectedInventory(item)
    setInventoryLotLinesPagingController(() => defaultPagingController)
  }, [])

  // On Search
  const onSearch = useCallback((query: Record<SearchParamNames, string>) => {
    refetchInventoryData(query, "search", defaultPagingController)
    refetchInventoryLotLineData(null, "search", defaultPagingController);

    setInputs(() => query)
    setInventoriesPagingController(() => defaultPagingController)
    setInventoryLotLinesPagingController(() => defaultPagingController)
  }, [refetchInventoryData])

  console.log("", "color: #666", inventoriesPagingController)

  return (
    <>
      <SearchBox
        criteria={searchCriteria}
        onSearch={(query) => {
          onSearch(query)
          // console.log(query)
          // console.log(inventories)
          // setInputs(() => query)
          // refetchInventoryData(query, "search", defaultPagingController)
          // setFilteredInventories(
          //   inventories.filter(
          //     (i) =>
          //       i.itemCode.toLowerCase().includes(query.itemCode.toLowerCase()) &&
          //       i.itemName.toLowerCase().includes(query.itemName.toLowerCase()) &&
          //       (query.itemType == "All" ||
          //         i.itemType.toLowerCase().includes(query.itemType.toLowerCase())) &&
          //       (query.status == "All" ||
          //         i.status.toLowerCase().includes(query.status.toLowerCase())),
          //   ),
          // );
        }}
        onReset={onReset}
      />
      <InventoryTable
        inventories={filteredInventories}
        pagingController={inventoriesPagingController}
        setPagingController={setInventoriesPagingController}
        totalCount={inventoriesTotalCount}
        onRowClick={onInventoryRowClick}
      />
      <InventoryLotLineTable
        inventoryLotLines={filteredInventoryLotLines}
        pagingController={inventoryLotLinesPagingController}
        setPagingController={setInventoryLotLinesPagingController}
        totalCount={inventoryLotLinesTotalCount}
        inventory={selectedInventory}
      />
    </>
  );
};

export default InventorySearch;
