"use client";

import { DoResult } from "@/app/api/do";
import { DoSearchAll, DoSearchLiteResponse, fetchDoSearch, fetchAllDoSearch, fetchDoSearchList, releaseDo } from "@/app/api/do/actions";
import {
  startWorkbenchBatchReleaseAsyncV2,
  getWorkbenchBatchReleaseProgress,
} from "@/app/api/doworkbench/actions";

import { useRouter } from "next/navigation";
import React, { ForwardedRef, useCallback, useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { Criterion } from "../SearchBox";
import { isEmpty, sortBy, uniqBy } from "lodash";
import { arrayToDateString, arrayToDayjs } from "@/app/utils/formatUtil";
import SearchBox from "../SearchBox/SearchBox";
import { EditNote } from "@mui/icons-material";
import InputDataGrid from "../InputDataGrid";
import { CreateConsoDoInput } from "@/app/api/do/actions";
import { TableRow } from "../InputDataGrid/InputDataGrid";
import {
  FooterPropsOverrides,
  GridColDef,
  GridRowModel,
  GridToolbarContainer,
  useGridApiRef,
} from "@mui/x-data-grid";
import {
  FormProvider,
  SubmitErrorHandler,
  SubmitHandler,
  useForm,
} from "react-hook-form"; 
import { Box, Button, Paper, Stack, Typography, TablePagination } from "@mui/material";
import StyledDataGrid from "../StyledDataGrid";
import Swal from "sweetalert2";
import { useSession } from "next-auth/react";
import { SessionWithTokens } from "@/config/authConfig";
import { useDoSearchRowSelection } from "../DoSearch/useDoSearchRowSelection";

type Props = {
  filterArgs?: Record<string, any>;
  searchQuery?: Record<string, any>;
  onDeliveryOrderSearch?: () => void;
  /** 明細頁路由前綴，預設 `/doworkbench`；在 `/do copy 2` 等別名頁面請傳對應 base */
  workbenchHrefBase?: string;
};
type SearchBoxInputs = Record<"code" | "status" | "estimatedArrivalDate" | "orderDate" | "supplierName" | "shopName" | "deliveryOrderLines" | "truckLanceCode" | "floor" | "codeTo" | "statusTo" | "estimatedArrivalDateTo" | "orderDateTo" | "supplierNameTo" | "shopNameTo" | "deliveryOrderLinesTo" | "truckLanceCodeTo" | "floorTo", string>;
type SearchParamNames = keyof SearchBoxInputs;

// put all this into a new component
// ConsoDoForm
type EntryError =
  | {
      [field in keyof DoResult]?: string;
    }
  | undefined;
type DoRow = TableRow<Partial<DoResult>, EntryError>;

function isTruckLaneSearchMissingEta(truckLanceCode: string, estimatedArrivalDate: string): boolean {
  return truckLanceCode.trim() !== "" && estimatedArrivalDate.trim() === "";
}

const DoSearchWorkbench: React.FC<Props> = ({
  filterArgs,
  searchQuery,
  onDeliveryOrderSearch,
  workbenchHrefBase = "/doworkbench",
}) => {
  const apiRef = useGridApiRef();

  const formProps = useForm<CreateConsoDoInput>({
    defaultValues: {},
  });
  const { setValue } = formProps;
  const errors = formProps.formState.errors;

  
  const { t } = useTranslation("do");
  const router = useRouter();
  const { data: session } = useSession() as { data: SessionWithTokens | null };
  const currentUserId = session?.id ? parseInt(session.id) : undefined;
  //console.log("🔍 DoSearch - session:", session);
  //console.log("🔍 DoSearch - currentUserId:", currentUserId);
  const [searchTimeout, setSearchTimeout] = useState<NodeJS.Timeout | null>(null);

  const [searchAllDos, setSearchAllDos] = useState<DoSearchAll[]>([]);
  const [totalCount, setTotalCount] = useState(0);

  const [pagingController, setPagingController] = useState({
    pageNum: 1,
    pageSize: 10,
  });

  const [currentSearchParams, setCurrentSearchParams] = useState<SearchBoxInputs>({
    code: "",
    status: "",
    estimatedArrivalDate: "",
    orderDate: "",
    supplierName: "",
    shopName: "",
    deliveryOrderLines: "",
    truckLanceCode: "",  // 添加这个字段
    floor: "All",
    codeTo: "",
    statusTo: "",
    estimatedArrivalDateTo: "",
    orderDateTo: "",
    supplierNameTo: "",
    shopNameTo: "",
    deliveryOrderLinesTo: "",
    truckLanceCodeTo: "",
    floorTo: "",
  });

  const [hasSearched, setHasSearched] = useState(false);
  const [hasResults, setHasResults] = useState(false);

  const {
    rowSelectionModel,
    applyRowSelectionChange,
    resetSelection,
    resolveIdsForBatchRelease,
  } = useDoSearchRowSelection(searchAllDos, setValue);

  // 当搜索条件变化时，重置到第一页
  useEffect(() => {
    setPagingController(p => ({
      ...p,
      pageNum: 1,
    }));
  }, [
    currentSearchParams.code,
    currentSearchParams.shopName,
    currentSearchParams.status,
    currentSearchParams.estimatedArrivalDate,
    currentSearchParams.truckLanceCode,
    currentSearchParams.floor,
  ]);


  const searchCriteria: Criterion<SearchParamNames>[] = useMemo(
    () => [
      { label: t("Code"), paramName: "code", type: "text" },
      { label: t("Shop Name"), paramName: "shopName", type: "text" },
      { label: t("Truck Lance Code"), paramName: "truckLanceCode", type: "text" },
      {
        label: t("Floor"),
        paramName: "floor",
        type: "select-labelled",
        options: [
          { label: "2F", value: "2F" },
          { label: "4F", value: "4F" },
        ],
      },
      {
        label: t("Estimated Arrival"),
        paramName: "estimatedArrivalDate",
        type: "date",
      },
      {
        label: t("Status"),
        paramName: "status",
        type: "autocomplete",
        options:[
          {label: t('Pending'), value: 'pending'},
          {label: t('Receiving'), value: 'receiving'},
          {label: t('Completed'), value: 'completed'}
        ]
      }
    ],
    [t],
  );

  const onReset = useCallback(async () => {
    try {
      setSearchAllDos([]);
      setTotalCount(0);
      setHasSearched(false);
      setHasResults(false);
      resetSelection();
      setPagingController({ pageNum: 1, pageSize: 10 });
    } 
    catch (error) {
      console.error("Error: ", error);
      setSearchAllDos([]);
      setTotalCount(0);
  }
  }, [resetSelection]);

  const onDetailClick = useCallback(
    (doResult: DoResult) => {
      if (typeof window !== 'undefined') {
        sessionStorage.setItem('doSearchParams', JSON.stringify(currentSearchParams));
      }
      const base = workbenchHrefBase.replace(/\/$/, "");
      router.push(`${base}/edit?id=${doResult.id}`);
    },
    [router, currentSearchParams, workbenchHrefBase],
  );

  const validationTest = useCallback(
    (
      newRow: GridRowModel<DoRow>,
    ): EntryError => {
      const error: EntryError = {};
      console.log(newRow);
      return Object.keys(error).length > 0 ? error : undefined;
    },
    [],
  );

  const columns = useMemo<GridColDef[]>(
    () => [
      {
        field: "id",
        headerName: t("Details"),
        width: 100,
        renderCell: (params) => (
          <Button
            variant="outlined"
            size="small"
            startIcon={<EditNote />}
            onClick={() => onDetailClick(params.row)}
          >
            {t("Details")}
          </Button>
        ),
      },
      {
        field: "code",
        headerName: t("code"),
        flex: 1.5,
      },
      {
        field: "shopName",
        headerName: t("Shop Name"),
        flex: 1,
      },
      {
        field: "supplierName",
        headerName: t("Supplier Name"),
        flex: 1,
      },
      {
        field: "truckLanceCode",
        headerName: t("Truck Lance Code"),
        flex: 1,
      },
      {
        field: "orderDate",
        headerName: t("Order Date"),
        flex: 1,
        renderCell: (params) => {
          return params.row.orderDate
            ? arrayToDateString(params.row.orderDate)
            : "N/A";
        },
      },
      {
        field: "estimatedArrivalDate",
        headerName: t("Estimated Arrival"),
        flex: 1,
        renderCell: (params) => {
          return params.row.estimatedArrivalDate
            ? arrayToDateString(params.row.estimatedArrivalDate)
            : "N/A";
        },
      },
      {
        field: "status",
        headerName: t("Status"),
        flex: 1,
        renderCell: (params) => {
          return t(params.row.status);
        },
      },
    ],
    [t, arrayToDateString, onDetailClick],
  );

  const onSubmit = useCallback<SubmitHandler<CreateConsoDoInput>>(
    async (data, event) => {
      const hasErrors = false;
      console.log(errors);
    },
    [errors],
  );
  const onSubmitError = useCallback<SubmitErrorHandler<CreateConsoDoInput>>(
    (errors) => {},
    [],
  );

  //SEARCH FUNCTION
const handleSearch = useCallback(async (query: SearchBoxInputs) => {
  try {
    if (isTruckLaneSearchMissingEta(query.truckLanceCode ?? "", query.estimatedArrivalDate ?? "")) {
      await Swal.fire({
        icon: "warning",
        title: t("Truck lane search requires date title"),
        text: t("Truck lane search requires date message"),
        confirmButtonText: t("Confirm"),
      });
      return;
    }

    setCurrentSearchParams(query);

    let estArrStartDate = query.estimatedArrivalDate;
    const time = "T00:00:00";
  
    if(estArrStartDate != ""){
      estArrStartDate = query.estimatedArrivalDate + time;
    }
    
    let status = "";
    if(query.status == "All"){
      status = "";
    }
    else{
      status = query.status;
    }

    const floorParam = query.floor === "All" || !query.floor ? null : query.floor;
    
    // 调用新的 API，传入分页参数和 truckLanceCode
    const response = await fetchDoSearch(
      query.code || "",
      query.shopName || "",
      status,
      "", // orderStartDate - 不再使用
      "", // orderEndDate - 不再使用
      estArrStartDate,
      "", // estArrEndDate - 不再使用
      pagingController.pageNum, // 传入当前页码
      pagingController.pageSize, // 传入每页大小
      query.truckLanceCode || "",
    );

    setSearchAllDos(response.records);
    setTotalCount(response.total); // 设置总记录数
    setHasSearched(true);
    setHasResults(response.records.length > 0);
    resetSelection();

  } catch (error) {
    console.error("Error: ", error);
    setSearchAllDos([]);
    setTotalCount(0);
    setHasSearched(true);
    setHasResults(false);
    resetSelection();
  }
}, [pagingController, t, resetSelection]);

  useEffect(() => {
    if (typeof window !== 'undefined') {
      const savedSearchParams = sessionStorage.getItem('doSearchParams');
      
      if (savedSearchParams) {
        try {
          const params = JSON.parse(savedSearchParams);
          setCurrentSearchParams(params);
          
          // 自动使用保存的搜索条件重新搜索，获取最新数据
          const timer = setTimeout(async () => {
            await handleSearch(params);
            // 搜索完成后，清除 sessionStorage
            if (typeof window !== 'undefined') {
              sessionStorage.removeItem('doSearchParams');
              sessionStorage.removeItem('doSearchResults');
              sessionStorage.removeItem('doSearchHasSearched');
            }
          }, 100);
          
          return () => clearTimeout(timer);
        } catch (e) {
          console.error('Error restoring search state:', e);
          // 如果出错，也清除 sessionStorage
          if (typeof window !== 'undefined') {
            sessionStorage.removeItem('doSearchParams');
            sessionStorage.removeItem('doSearchResults');
            sessionStorage.removeItem('doSearchHasSearched');
          }
        }
      }
    }
  }, [handleSearch]);

  const debouncedSearch = useCallback((query: SearchBoxInputs) => {
    if (searchTimeout) {
      clearTimeout(searchTimeout);
    }
    
    const timeout = setTimeout(() => {
      handleSearch(query);
    }, 300);
    
    setSearchTimeout(timeout);
  }, [handleSearch, searchTimeout]);

  // 分页变化时重新搜索
  const handlePageChange = useCallback((event: unknown, newPage: number) => {
    const newPagingController = {
      ...pagingController,
      pageNum: newPage + 1,
    };
    setPagingController(newPagingController);
    // 如果已经搜索过，重新搜索
    if (hasSearched && currentSearchParams) {
      // 使用新的分页参数重新搜索
      const searchWithNewPage = async () => {
        try {
          if (
            isTruckLaneSearchMissingEta(
              currentSearchParams.truckLanceCode ?? "",
              currentSearchParams.estimatedArrivalDate ?? "",
            )
          ) {
            await Swal.fire({
              icon: "warning",
              title: t("Truck lane search requires date title"),
              text: t("Truck lane search requires date message"),
              confirmButtonText: t("Confirm"),
            });
            return;
          }
          let estArrStartDate = currentSearchParams.estimatedArrivalDate;
          const time = "T00:00:00";
      
          if(estArrStartDate != ""){
            estArrStartDate = currentSearchParams.estimatedArrivalDate + time;
          }
          
          let status = "";
          if(currentSearchParams.status == "All"){
            status = "";
          }
          else{
            status = currentSearchParams.status;
          }

          const floorParam =
            currentSearchParams.floor === "All" || !currentSearchParams.floor
              ? null
              : currentSearchParams.floor;
          
          const response = await fetchDoSearch(
            currentSearchParams.code || "",
            currentSearchParams.shopName || "",
            status,
            "",
            "",
            estArrStartDate,
            "",
            newPagingController.pageNum,
            newPagingController.pageSize,
            currentSearchParams.truckLanceCode || "",
          );
      
          setSearchAllDos(response.records);
          setTotalCount(response.total);
        } catch (error) {
          console.error("Error: ", error);
        }
      };
      searchWithNewPage();
    }
  }, [pagingController, hasSearched, currentSearchParams, t]);

  const handlePageSizeChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
    const newPageSize = parseInt(event.target.value, 10);
    const newPagingController = {
      pageNum: 1, // 改变每页大小时重置到第一页
      pageSize: newPageSize,
    };
    setPagingController(newPagingController);
    // 如果已经搜索过，重新搜索
    if (hasSearched && currentSearchParams) {
      const searchWithNewPageSize = async () => {
        try {
          if (
            isTruckLaneSearchMissingEta(
              currentSearchParams.truckLanceCode ?? "",
              currentSearchParams.estimatedArrivalDate ?? "",
            )
          ) {
            await Swal.fire({
              icon: "warning",
              title: t("Truck lane search requires date title"),
              text: t("Truck lane search requires date message"),
              confirmButtonText: t("Confirm"),
            });
            return;
          }
          let estArrStartDate = currentSearchParams.estimatedArrivalDate;
          const time = "T00:00:00";
      
          if(estArrStartDate != ""){
            estArrStartDate = currentSearchParams.estimatedArrivalDate + time;
          }
          
          let status = "";
          if(currentSearchParams.status == "All"){
            status = "";
          }
          else{
            status = currentSearchParams.status;
          }

          const floorParam =
            currentSearchParams.floor === "All" || !currentSearchParams.floor
              ? null
              : currentSearchParams.floor;
          
          const response = await fetchDoSearch(
            currentSearchParams.code || "",
            currentSearchParams.shopName || "",
            status,
            "",
            "",
            estArrStartDate,
            "",
            1, // 重置到第一页
            newPageSize,
            currentSearchParams.truckLanceCode || "",
          );
      
          setSearchAllDos(response.records);
          setTotalCount(response.total);
        } catch (error) {
          console.error("Error: ", error);
        }
      };
      searchWithNewPageSize();
    }
  }, [hasSearched, currentSearchParams, t]);

  const handleBatchRelease = useCallback(async () => {
    try {
      if (
        isTruckLaneSearchMissingEta(
          currentSearchParams.truckLanceCode ?? "",
          currentSearchParams.estimatedArrivalDate ?? "",
        )
      ) {
        await Swal.fire({
          icon: "warning",
          title: t("Truck lane search requires date title"),
          text: t("Truck lane search requires date message"),
          confirmButtonText: t("Confirm"),
        });
        return;
      }
      // 根据当前搜索条件获取所有匹配的记录（不分页）
      let estArrStartDate = currentSearchParams.estimatedArrivalDate;
      const time = "T00:00:00";
    
      if(estArrStartDate != ""){
        estArrStartDate = currentSearchParams.estimatedArrivalDate + time;
      }
      
      let status = "";
      if(currentSearchParams.status == "All"){
        status = "";
      }
      else{
        status = currentSearchParams.status;
      }

      const floorParam =
        currentSearchParams.floor === "All" || !currentSearchParams.floor
          ? null
          : currentSearchParams.floor;
  
      // 显示加载提示
      const loadingSwal = Swal.fire({
        title: t("Loading"),
        text: t("Fetching all matching records..."),
        allowOutsideClick: false,
        allowEscapeKey: false,
        showConfirmButton: false,
        didOpen: () => {
          Swal.showLoading();
        }
      });
  
      // 获取所有匹配的记录
      const allMatchingDos = await fetchAllDoSearch(
        currentSearchParams.code || "",
        currentSearchParams.shopName || "",
        status,
        estArrStartDate,
        currentSearchParams.truckLanceCode || "",
      );
  
      Swal.close();
  
      if (allMatchingDos.length === 0) {
        await Swal.fire({
          icon: "warning",
          title: t("No Records"),
          text: t("No matching records found for batch release."),
          confirmButtonText: t("OK")
        });
        return;
      }

      const idsToRelease = resolveIdsForBatchRelease(
        allMatchingDos.map((d) => d.id),
      );

      if (idsToRelease.length === 0) {
        await Swal.fire({
          icon: "warning",
          title: t("No Records"),
          text: t("No delivery orders selected for batch release. Uncheck orders you want to exclude, or search again to reset selection."),
          confirmButtonText: t("OK"),
        });
        return;
      }
  
      // 显示确认对话框
      const result = await Swal.fire({
        icon: "question",
        title: t("Batch Release"),
        html: `
          <div style="text-align: left;">
            <p>${t("Selected Shop(s): ")}${idsToRelease.length}</p>
            <p style="font-size: 0.9em; color: #666; margin-top: 8px;">
             
              ${currentSearchParams.code ? `${t("Code")}: ${currentSearchParams.code} ` : ""}
              ${currentSearchParams.shopName ? `${t("Shop Name")}: ${currentSearchParams.shopName} ` : ""}
              ${currentSearchParams.estimatedArrivalDate ? `${t("Estimated Arrival")}: ${currentSearchParams.estimatedArrivalDate} ` : ""}
              ${status ? `${t("Status")}: ${t(status)} ` : ""}
            </p>
            <label style="display:flex;align-items:flex-start;gap:8px;margin-top:16px;font-size:0.95em;cursor:pointer;">
              <input type="checkbox" id="mergeExtraIntoLaneTicket" style="margin-top:3px;" />
              <span>${t("Merge extra orders into lane batch ticket")}</span>
            </label>
          </div>
        `,
        showCancelButton: true,
        confirmButtonText: t("Confirm"),
        cancelButtonText: t("Cancel"),
        confirmButtonColor: "#8dba00",
        cancelButtonColor: "#F04438",
        preConfirm: () => {
          const el = document.getElementById("mergeExtraIntoLaneTicket") as HTMLInputElement | null;
          return { mergeExtraIntoLaneTicket: el?.checked ?? false };
        },
      });
    
      if (result.isConfirmed) {
        try {
          const mergeExtraIntoLaneTicket =
            (result.value as { mergeExtraIntoLaneTicket?: boolean } | undefined)?.mergeExtraIntoLaneTicket ?? false;
          const startRes = await startWorkbenchBatchReleaseAsyncV2({
            ids: idsToRelease,
            userId: currentUserId ?? 1,
            mergeExtraIntoLaneTicket,
          });
          const startEntity = startRes?.entity as { jobId?: string } | undefined;
          const jobId = startEntity?.jobId;
      
          if (!jobId) {
            await Swal.fire({ icon: "error", title: t("Error"), text: t("Failed to start batch release") });
            return;
          }
  
          const progressSwal = Swal.fire({
              title: t("Releasing"),
              text: "0% (0 / 0)",
              allowOutsideClick: false,
              allowEscapeKey: false,
              showConfirmButton: false,
              didOpen: () => {
                Swal.showLoading();
              }
            });
            
          const timer = setInterval(async () => {
            try {
              const p = await getWorkbenchBatchReleaseProgress(jobId);

              const e = (p?.entity || {}) as {
                total?: number;
                finished?: number;
                running?: boolean;
              };
              const total = e.total ?? 0;
              const finished = e.finished ?? 0;
              const percentage = total > 0 ? Math.round((finished / total) * 100) : 0;
            
            const textContent = document.querySelector('.swal2-html-container');
            if (textContent) {
              textContent.textContent = `${percentage}% (${finished} / ${total})`;
            }
  
            if (p.code === "FINISHED" || e.running === false) {
              clearInterval(timer);
              await new Promise(resolve => setTimeout(resolve, 500));
              Swal.close();
            
              await Swal.fire({
                icon: "success",
                title: t("Completed"),
                text: t("Batch release completed successfully."),
                confirmButtonText: t("Confirm"),
                confirmButtonColor: "#8dba00"
              });
            
              if (currentSearchParams && Object.keys(currentSearchParams).length > 0) {
                await handleSearch(currentSearchParams);
              }
            }
          } catch (err) {
            console.error("progress poll error:", err);
          }
        }, 800);
      } catch (error) {
        console.error("Batch release error:", error);
        await Swal.fire({
          icon: "error",
          title: t("Error"),
          text: t("An error occurred during batch release"),
          confirmButtonText: t("OK")
        });
      }
    }
    } catch (error) {
      console.error("Error fetching all matching records:", error);
      await Swal.fire({
        icon: "error",
        title: t("Error"),
        text: t("Failed to fetch matching records"),
        confirmButtonText: t("OK")
      });
    }
  }, [t, currentUserId, currentSearchParams, handleSearch, resolveIdsForBatchRelease]);

  return (
    <>
      <FormProvider {...formProps}>
        <Stack
          spacing={2}
          component="form"
          onSubmit={formProps.handleSubmit(onSubmit, onSubmitError)}
        >
          {hasSearched && hasResults && (
            <Stack direction="row" justifyContent="flex-end" sx={{ mb: 1 }}>
              <Button
                name="batch_release"
                variant="contained"
                onClick={handleBatchRelease}
              >
                {t("Workbench batch release", { defaultValue: "Workbench batch release" })}
              </Button>
            </Stack>
          )}

          <SearchBox
            criteria={searchCriteria}
            onSearch={handleSearch}
            onReset={onReset}
          />

          <Paper variant="outlined" sx={{ overflow: "hidden" }}>
            <StyledDataGrid
              rows={searchAllDos}
              columns={columns}
              checkboxSelection
              rowSelectionModel={rowSelectionModel}
              onRowSelectionModelChange={applyRowSelectionChange}
              slots={{
                footer: FooterToolbar,
                noRowsOverlay: NoRowsOverlay,
              }}
            />
            <TablePagination
              component="div"
              count={totalCount}
              page={(pagingController.pageNum - 1)}
              rowsPerPage={pagingController.pageSize}
              onPageChange={handlePageChange}
              onRowsPerPageChange={handlePageSizeChange}
              rowsPerPageOptions={[10, 25, 50]}
            />
          </Paper>

        </Stack>
      </FormProvider>
    </>
  );
};


const FooterToolbar: React.FC<FooterPropsOverrides> = ({ child }) => {
  return <GridToolbarContainer sx={{ p: 2 }}>{child}</GridToolbarContainer>;
};
const NoRowsOverlay: React.FC = () => {
  const { t } = useTranslation("home");
  return (
    <Box
      display="flex"
      justifyContent="center"
      alignItems="center"
      height="100%"
    >
      <Typography variant="caption">{t("Add some entries!")}</Typography>
    </Box>
  );
};

export default DoSearchWorkbench;