"use client";

import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { Box, Paper, Typography } from "@mui/material";
import type { Result } from "@zxing/library";
import ReactQrCodeScanner, {
  ScannerConfig,
  defaultScannerConfig,
} from "../ReactQrCodeScanner/ReactQrCodeScanner";
import { WarehouseResult } from "@/app/api/warehouse";
import { useTranslation } from "react-i18next";
import { QrCodeScanner as QrCodeIcon } from "@mui/icons-material";
import PutAwayModal from "./PutAwayModal";
import PutAwayReviewGrid from "./PutAwayReviewGrid";
import type { PutAwayRecord } from ".";
import type { QrCodeScanner as QrCodeScannerType } from "../QrCodeScannerProvider/QrCodeScannerProvider";

/** Find first number after a keyword in a string (e.g. "StockInLine" or "warehouseId"). */
function findIdByRoughMatch(inputString: string, keyword: string): number | null {
  const idx = inputString.indexOf(keyword);
  if (idx === -1) return null;
  const after = inputString.slice(idx + keyword.length);
  const match = after.match(/\d+/);
  return match ? parseInt(match[0], 10) : null;
}

type Props = {
  warehouse: WarehouseResult[];
};

type ScanStatusType = "pending" | "scanning";

const dummyScanner: QrCodeScannerType = {
  values: [],
  isScanning: false,
  startScan: () => {},
  stopScan: () => {},
  resetScan: () => {},
  result: undefined,
  state: "pending",
  error: undefined,
};

const PutAwayCamScan: React.FC<Props> = ({ warehouse }) => {
  const { t } = useTranslation("putAway");

  const [scanStatus, setScanStatus] = useState<ScanStatusType>("pending");
  const [openPutAwayModal, setOpenPutAwayModal] = useState(false);
  const [scannedSilId, setScannedSilId] = useState<number>(0);
  const [scannedWareHouseId, setScannedWareHouseId] = useState<number>(0);
  const [putAwayHistory, setPutAwayHistory] = useState<PutAwayRecord[]>([]);

  const addPutAwayHistory = (putAwayData: PutAwayRecord) => {
    const newPutaway = { ...putAwayData, id: putAwayHistory.length + 1 };
    setPutAwayHistory((prev) => [...prev, newPutaway]);
  };

  const handleSetDefaultWarehouseId = useCallback((warehouseId: number) => {
    if (scannedWareHouseId === 0) {
      setScannedWareHouseId(warehouseId);
    }
  }, [scannedWareHouseId]);

  // Refs so the scanner (which only gets config on mount) always calls the latest handler and we throttle duplicates
  const handleScanRef = useRef<(rawText: string) => void>(() => {});
  const lastScannedRef = useRef({ text: "", at: 0 });
  const THROTTLE_MS = 2000;

  const handleScan = useCallback(
    (rawText: string) => {
      const trimmed = (rawText || "").trim();
      if (!trimmed) return;
      const now = Date.now();
      if (
        lastScannedRef.current.text === trimmed &&
        now - lastScannedRef.current.at < THROTTLE_MS
      ) {
        return;
      }

      setScanStatus("scanning");

      const done = () => {
        lastScannedRef.current = { text: trimmed, at: now };
      };

      const trySetSilId = (num: number): boolean => {
        if (!Number.isFinite(num) || num <= 0) return false;
        setScannedSilId(num);
        done();
        return true;
      };
      const trySetWarehouseId = (num: number): boolean => {
        if (!Number.isFinite(num) || num <= 0) return false;
        setScannedWareHouseId(num);
        done();
        return true;
      };

      const isFirstScan = scannedSilId === 0;
      const isSecondScan = scannedSilId > 0 && scannedWareHouseId === 0;

      // 1) Try JSON
      try {
        const data = JSON.parse(trimmed) as Record<string, unknown>;
        if (data && typeof data === "object") {
          if (isFirstScan) {
            if (data.stockInLineId != null && trySetSilId(Number(data.stockInLineId))) return;
            if (data.value != null && trySetSilId(Number(data.value))) return;
          }
          if (isSecondScan) {
            if (data.warehouseId != null && trySetWarehouseId(Number(data.warehouseId))) return;
            if (data.value != null && trySetWarehouseId(Number(data.value))) return;
          }
        }
      } catch {
        // not JSON
      }

      // 2) Rough match: "StockInLine" or "warehouseId" + number (same as barcode scanner)
      if (isFirstScan) {
        const sil =
          findIdByRoughMatch(trimmed, "StockInLine") ??
          findIdByRoughMatch(trimmed, "stockInLineId");
        if (sil != null && trySetSilId(sil)) return;
      }
      if (isSecondScan) {
        const wh =
          findIdByRoughMatch(trimmed, "warehouseId") ??
          findIdByRoughMatch(trimmed, "WarehouseId");
        if (wh != null && trySetWarehouseId(wh)) return;
      }

      // 3) Plain number
      const num = Number(trimmed);
      if (isFirstScan && trySetSilId(num)) return;
      if (isSecondScan && trySetWarehouseId(num)) return;
    },
    [scannedSilId, scannedWareHouseId],
  );

  handleScanRef.current = handleScan;

  // Open modal only after both stock-in-line and location (warehouse) are scanned
  useEffect(() => {
    if (scannedSilId > 0 && scannedWareHouseId > 0) {
      setOpenPutAwayModal(true);
      setScanStatus("pending");
    }
  }, [scannedSilId, scannedWareHouseId]);

  const closeModal = () => {
    setScannedSilId(0);
    setScannedWareHouseId(0);
    setOpenPutAwayModal(false);
    setScanStatus("pending");
  };

  const displayText = useMemo(() => {
    if (scanStatus === "scanning") {
      return t("Scanning");
    }
    if (scannedSilId > 0 && scannedWareHouseId > 0) {
      return t("Scanned, opening detail");
    }
    if (scannedSilId > 0) {
      return t("Please scan warehouse qr code");
    }
    return t("Pending scan");
  }, [scanStatus, scannedSilId, scannedWareHouseId, t]);

  const scannerConfig: ScannerConfig = useMemo(
    () => ({
      ...defaultScannerConfig,
      onUpdate: (_err: unknown, result?: Result): void => {
        if (result) {
          handleScanRef.current(result.getText());
        }
      },
    }),
    [],
  );

  return (
    <>
      <Paper
        sx={{
          display: "flex",
          flexDirection: "column",
          justifyContent: "center",
          alignItems: "center",
          textAlign: "center",
          gap: 2,
          p: 2,
        }}
      >
        <Typography variant="h4" sx={{ mb: 1 }}>
          {displayText}
        </Typography>
        <QrCodeIcon sx={{ fontSize: 80, mb: 1 }} color="primary" />
        <Box
          sx={{
            width: "100%",
            maxWidth: 480,
            aspectRatio: "4 / 3",
            overflow: "hidden",
          }}
        >
          <ReactQrCodeScanner scannerConfig={scannerConfig} />
        </Box>
      </Paper>

      {putAwayHistory.length > 0 && (
        <>
          <Typography variant="h5" sx={{ mt: 3, mb: 1 }}>
            {t("putAwayHistory")}
          </Typography>
          <PutAwayReviewGrid putAwayHistory={putAwayHistory} />
        </>
      )}

      <PutAwayModal
        open={openPutAwayModal}
        onClose={closeModal}
        warehouse={warehouse}
        stockInLineId={scannedSilId}
        warehouseId={scannedWareHouseId}
        scanner={dummyScanner}
        addPutAwayHistory={addPutAwayHistory}
        onSetDefaultWarehouseId={handleSetDefaultWarehouseId}
      />
    </>
  );
};

export default PutAwayCamScan;

