"use client";

import { Alert, Box, CircularProgress, Stack, Typography } from "@mui/material";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useSearchParams } from "next/navigation";
import { useTranslation } from "react-i18next";
import { fetchItemLotTrace } from "@/app/api/itemTracing/actions";
import { ItemLotTraceResponse } from "@/app/api/itemTracing";
import { isNotFoundServerFetchError } from "@/app/utils/serverFetchError";
import ItemTracingScanBar from "./ItemTracingScanBar";
import ItemTracingSummary from "./ItemTracingSummary";
import ItemTracingFlowGraph from "./ItemTracingFlowGraph";
import ItemTracingSections from "./ItemTracingSections";
import {
  compileTraceGraph,
  type CompiledTraceGraph,
} from "./compileTraceGraph";
import { buildTraceGraphLabels } from "./traceGraphLabels";
import { exportItemLotTraceXlsx } from "./exportItemLotTraceXlsx";

export type WarehouseFocusRequest = {
  inventoryLotId: number;
  warehouseCode: string;
};

const ItemTracing: React.FC = () => {
  const { t } = useTranslation("itemTracing");
  const searchParams = useSearchParams();
  const initialTraceRan = useRef(false);
  const [data, setData] = useState<ItemLotTraceResponse | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [focusWarehouse, setFocusWarehouse] =
    useState<WarehouseFocusRequest | null>(null);

  const runTrace = useCallback(
    async (params: {
      stockInLineId?: number;
      inventoryLotLineId?: number;
      lotNo?: string;
      itemCode?: string;
    }) => {
      setLoading(true);
      setError(null);
      try {
        const res = await fetchItemLotTrace(params);
        setData(res);
        setFocusWarehouse(null);
      } catch (e) {
        console.error(e);
        if (isNotFoundServerFetchError(e)) {
          setError(t("notFound"));
        } else {
          setError(t("traceError"));
        }
        setData(null);
      } finally {
        setLoading(false);
      }
    },
    [t],
  );

  useEffect(() => {
    if (initialTraceRan.current) return;
    const stockInLineIdRaw = searchParams.get("stockInLineId");
    const lotNo = searchParams.get("lotNo")?.trim();
    const itemCode = searchParams.get("itemCode")?.trim();
    const stockInLineId = stockInLineIdRaw
      ? Number(stockInLineIdRaw)
      : undefined;
    const hasTraceParams =
      (stockInLineId != null && !Number.isNaN(stockInLineId)) ||
      Boolean(lotNo) ||
      Boolean(itemCode);
    if (!hasTraceParams) return;
    initialTraceRan.current = true;
    void runTrace({
      stockInLineId:
        stockInLineId != null && !Number.isNaN(stockInLineId)
          ? stockInLineId
          : undefined,
      lotNo: lotNo || undefined,
      itemCode: itemCode || undefined,
    });
  }, [runTrace, searchParams]);

  const compiledGraph = useMemo((): CompiledTraceGraph | null => {
    if (!data) return null;
    const labels = buildTraceGraphLabels(t, data.lot.uom);
    return compileTraceGraph(data, labels);
  }, [data, t]);

  const handleExportExcel = useCallback(() => {
    if (!data || !compiledGraph) return;
    exportItemLotTraceXlsx(data, compiledGraph, t);
  }, [data, compiledGraph, t]);

  return (
    <Stack spacing={3} sx={{ mt: 2 }}>
      <Typography variant="body1" color="text.secondary">
        {t("subtitle")}
      </Typography>

      <ItemTracingScanBar
        onTrace={runTrace}
        loading={loading}
        lastLotNo={data?.lot.lotNo}
      />

      {loading && (
        <Box sx={{ display: "flex", justifyContent: "center", py: 4 }}>
          <CircularProgress />
        </Box>
      )}

      {error && !loading && <Alert severity="error">{error}</Alert>}

      {!loading && !data && !error && (
        <Alert severity="info">{t("noResult")}</Alert>
      )}

      {data && !loading && (
        <>
          <ItemTracingSummary
            data={data}
            onFocusWarehouse={(request) => setFocusWarehouse(request)}
            onExportExcel={compiledGraph ? handleExportExcel : undefined}
          />
          {compiledGraph && (
            <>
              <ItemTracingFlowGraph
                data={data}
                compiledGraph={compiledGraph}
                onTrace={runTrace}
                focusWarehouse={focusWarehouse}
              />
              <ItemTracingSections
                data={data}
                compiledGraph={compiledGraph}
                onTrace={runTrace}
              />
            </>
          )}
        </>
      )}
    </Stack>
  );
};

export default ItemTracing;
