"use client";

import {
  fetchBadItemRecords,
  fetchExpiryItemRecords,
  StockIssueHandleRecord,
} from "@/app/api/stockIssue/actions";
import StockIssueSearchPanel, {
  StockIssueSearchField,
} from "./StockIssueSearchPanel";
import SearchResults, { Column } from "@/components/SearchResults";
import { OUTPUT_DATE_FORMAT } from "@/app/utils/formatUtil";
import dayjs from "dayjs";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useTranslation } from "react-i18next";

type RecordKind = "bad" | "expiry";

type SearchQuery = {
  itemCode: string;
  itemName: string;
  lotNo: string;
  startDate: string;
  endDate: string;
};
type SearchParamNames = keyof SearchQuery;

interface Props {
  kind: RecordKind;
}

const StockIssueRecordTab: React.FC<Props> = ({ kind }) => {
  const { t } = useTranslation("stockIssue");
  const [items, setItems] = useState<StockIssueHandleRecord[]>([]);
  const [totalCount, setTotalCount] = useState(0);
  const [paging, setPaging] = useState({ pageNum: 1, pageSize: 10 });
  const [filterArgs, setFilterArgs] = useState<SearchQuery>({
    itemCode: "",
    itemName: "",
    lotNo: "",
    startDate: "",
    endDate: "",
  });
  const hasSearchedRef = useRef(false);
  const prevPagingRef = useRef(paging);

  const searchFields: StockIssueSearchField<SearchParamNames>[] = useMemo(
    () => [
      { name: "itemCode", label: t("Item Code"), type: "text" },
      { name: "itemName", label: t("Item"), type: "text" },
      { name: "lotNo", label: t("Lot No."), type: "text" },
      {
        name: "startDate",
        label: kind === "expiry" ? t("Expiry Start Date") : t("Start Date"),
        type: "date",
        mirrorTo: "endDate",
      },
      {
        name: "endDate",
        label: kind === "expiry" ? t("Expiry End Date") : t("End Date"),
        type: "date",
      },
    ],
    [t, kind],
  );

  const fetchRecords = useCallback(
    async (query: SearchQuery, page: { pageNum: number; pageSize: number }) => {
      try {
        const params = {
          itemCode: query.itemCode?.trim() || undefined,
          itemName: query.itemName?.trim() || undefined,
          lotNo: query.lotNo?.trim() || undefined,
          startDate: query.startDate || undefined,
          endDate: query.endDate || undefined,
          pageNum: page.pageNum - 1,
          pageSize: page.pageSize,
        };
        const res =
          kind === "bad"
            ? await fetchBadItemRecords(params)
            : await fetchExpiryItemRecords(params);
        setItems(res?.records ?? []);
        setTotalCount(res?.total ?? 0);
      } catch (e) {
        console.error(e);
        setItems([]);
        setTotalCount(0);
      }
    },
    [kind],
  );

  const handleSearch = useCallback(
    async (query: Record<SearchParamNames, string>) => {
      const q = query as SearchQuery;
      setFilterArgs(q);
      const page = { pageNum: 1, pageSize: paging.pageSize };
      setPaging(page);
      hasSearchedRef.current = true;
      await fetchRecords(q, page);
      prevPagingRef.current = page;
    },
    [fetchRecords, paging.pageSize],
  );

  useEffect(() => {
    if (!hasSearchedRef.current) return;
    const pagingChanged =
      prevPagingRef.current.pageNum !== paging.pageNum ||
      prevPagingRef.current.pageSize !== paging.pageSize;
    if (pagingChanged) {
      fetchRecords(filterArgs, paging);
      prevPagingRef.current = paging;
    }
  }, [paging, filterArgs, fetchRecords]);

  const formatDateValue = (raw: string | null | undefined) => {
    if (raw == null || raw === "") return "—";
    const trimmed = String(raw).trim();
    if (trimmed.includes(",")) {
      const parts = trimmed.split(",").map((s) => parseInt(s.trim(), 10));
      const [y, m, d_] = parts;
      if (
        parts.length >= 3 &&
        !Number.isNaN(y) &&
        !Number.isNaN(m) &&
        !Number.isNaN(d_)
      ) {
        const d = dayjs(new Date(y, m - 1, d_));
        return d.isValid() ? d.format(OUTPUT_DATE_FORMAT) : trimmed;
      }
    }
    const d = dayjs(trimmed);
    return d.isValid() ? d.format(OUTPUT_DATE_FORMAT) : trimmed;
  };

  const columns = useMemo<Column<StockIssueHandleRecord>[]>(() => {
    const base: Column<StockIssueHandleRecord>[] = [
      {
        name: "handledAt",
        label: t("Handled Date"),
        renderCell: (row) => formatDateValue(row.handledAt),
      },
      { name: "itemCode", label: t("Item Code") },
      { name: "itemName", label: t("Item") },
      { name: "lotNo", label: t("Lot No.") },
      { name: "storeLocation", label: t("Location") },
    ];
    if (kind === "expiry") {
      base.push({
        name: "expiryDate",
        label: t("Expiry Date"),
        renderCell: (row) => formatDateValue(row.expiryDate),
      });
    }
    base.push(
      {
        name: "qty",
        label: kind === "expiry" ? t("Expiry Item Qty") : t("Bad Item Qty"),
        renderCell: (row) => (
          <>
            {Number(row.qty).toFixed(2)}
          </>
        ),
      },
      {
        name: "uomDesc",
        label: t("UOM"),
        renderCell: (row) => (
          <>
            {row.uomDesc ?? ""}
          </>
        ),
      },
      {
        name: "handlerName",
        label: t("Handler"),
        renderCell: (row) =>
          row.handlerName ?? (row.handlerId != null ? String(row.handlerId) : "—"),
      },
      { name: "remarks", label: t("Remarks") },
    );
    return base;
  }, [t, kind]);

  return (
    <>
      <StockIssueSearchPanel fields={searchFields} onSearch={handleSearch} />
      <SearchResults<StockIssueHandleRecord>
        items={items}
        columns={columns}
        pagingController={paging}
        setPagingController={setPaging}
        totalCount={totalCount}
        isAutoPaging={false}
      />
    </>
  );
};

export default StockIssueRecordTab;
