"use client";

import {
  Box,
  Button,
  Chip,
  CircularProgress,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  Paper,
  Stack,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TablePagination,
  TableRow,
  TextField,
  Typography,
} from "@mui/material";
import { useCallback, useEffect, useState, useMemo } from "react";
import { useTranslation } from "react-i18next";
import SearchBox, { Criterion } from "../SearchBox";
import SearchResults, { Column } from "../SearchResults";
import { defaultPagingController } from "../SearchResults/SearchResults";
import {
  fetchAllPickExecutionIssues,
  PickExecutionIssue,
  updatePickExecutionIssueStatus,
  FetchPickExecutionIssuesParams,
} from "@/app/api/pickOrder/actions";
import dayjs from "dayjs";
import { OUTPUT_DATE_FORMAT } from "@/app/utils/formatUtil";

type SearchQuery = {
  issueNo: string;
  pickOrderCode: string;
  itemCode: string;
  lotNo: string;
  type: string;
  status: string;
};

type SearchParamNames = keyof SearchQuery;

const PickExecutionIssuesTab: React.FC = () => {
  const { t } = useTranslation(["stockTake", "pickOrder"]);

  // States
  const [issues, setIssues] = useState<PickExecutionIssue[]>([]);
  const [loading, setLoading] = useState(false);
  const [pagingController, setPagingController] = useState(defaultPagingController);
  const [totalCount, setTotalCount] = useState(0);

  // Search inputs
  const defaultInputs = useMemo(() => ({
    issueNo: "",
    pickOrderCode: "",
    itemCode: "",
    lotNo: "",
    type: "",
    status: "",
  }), []);
  const [inputs, setInputs] = useState<Record<SearchParamNames, string>>(defaultInputs);

  // Handle dialog
  const [selectedIssue, setSelectedIssue] = useState<PickExecutionIssue | null>(null);
  const [handleDialogOpen, setHandleDialogOpen] = useState(false);
  const [handleRemark, setHandleRemark] = useState("");

  // Search criteria
  const searchCriteria: Criterion<SearchParamNames>[] = useMemo(
    () => [
      { label: t("Issue No"), paramName: "issueNo", type: "text" },
      { label: t("Pick Order Code"), paramName: "pickOrderCode", type: "text" },
      { label: t("Item Code"), paramName: "itemCode", type: "text" },
      { label: t("Lot No"), paramName: "lotNo", type: "text" },
      {
        label: t("Type"),
        paramName: "type",
        type: "select-labelled",
        options: [
          { value: "jo", label: t("jo") },
          { value: "do", label: t("do") },
          { value: "material", label: t("material") },
        ],
      },
      {
        label: t("Status"),
        paramName: "status",
        type: "select-labelled",
        options: [
          { value: "pending", label: t("pending") },
          { value: "resolved", label: t("resolved") },
        ],
      },
    ],
    [t],
  );

  // Fetch issues
  const refetchIssuesData = useCallback(async (
    query: Record<SearchParamNames, string>,
    actionType: "reset" | "search" | "paging" | "init",
    pagingController: typeof defaultPagingController,
  ) => {
    console.log("%c Action Type.", "color:red", actionType);
    
    setLoading(true);
    try {
      // Build API parameters with proper type casting
      let apiParams: FetchPickExecutionIssuesParams | undefined = undefined;
      
      if (query.type && query.type !== "All") {
        // Type assertion to ensure the string is one of the valid types
        const validType = query.type as "jo" | "do" | "material";
        apiParams = { type: validType };
      }
      
      // Call API with type parameter if specified
      const result = await fetchAllPickExecutionIssues(apiParams);

      // Apply client-side filtering for other parameters
      let filteredResult = result;

      if (query.issueNo) {
        filteredResult = filteredResult.filter(issue => 
          issue.issueNo.toLowerCase().includes(query.issueNo.toLowerCase())
        );
      }

      if (query.pickOrderCode) {
        filteredResult = filteredResult.filter(issue => 
          issue.pickOrderCode.toLowerCase().includes(query.pickOrderCode.toLowerCase())
        );
      }

      if (query.itemCode) {
        filteredResult = filteredResult.filter(issue => 
          issue.itemCode.toLowerCase().includes(query.itemCode.toLowerCase())
        );
      }

      if (query.lotNo) {
        filteredResult = filteredResult.filter(issue => 
          issue.lotNo && issue.lotNo.toLowerCase().includes(query.lotNo.toLowerCase())
        );
      }

      if (query.status && query.status !== "All") {
        filteredResult = filteredResult.filter(issue => {
          if (query.status === "pending") {
            return issue.handleStatus.toLowerCase() === "pending";
          }
          if (query.status === "resolved") {
            return issue.handleStatus.toLowerCase() !== "pending";
          }
          return true;
        });
      }

      setIssues(filteredResult);
      setTotalCount(filteredResult.length);

    } catch (error) {
      console.error("Error fetching pick execution issues:", error);
      setIssues([]);
      setTotalCount(0);
    } finally {
      setLoading(false);
    }
  }, []);

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

  useEffect(() => {
    refetchIssuesData(inputs, "paging", pagingController);
  }, [pagingController, refetchIssuesData, inputs]);

  // Handlers
  const onReset = useCallback(() => {
    refetchIssuesData(defaultInputs, "reset", defaultPagingController);
    setInputs(() => defaultInputs);
    setPagingController(() => defaultPagingController);
  }, [refetchIssuesData, defaultInputs]);

  const onSearch = useCallback((query: Record<SearchParamNames, string>) => {
    refetchIssuesData(query, "search", defaultPagingController);
    setInputs(() => query);
    setPagingController(() => defaultPagingController);
  }, [refetchIssuesData]);

  const handleViewDetail = (issue: PickExecutionIssue) => {
    setSelectedIssue(issue);
    setHandleDialogOpen(true);
    setHandleRemark("");
  };

  const handleCloseDialog = () => {
    setHandleDialogOpen(false);
    setSelectedIssue(null);
    setHandleRemark("");
  };

  const handleMarkAsResolved = async () => {
    if (!selectedIssue) return;

    try {
      await updatePickExecutionIssueStatus({
        issueId: selectedIssue.id,
        handleStatus: "resolved",
        handleDate: new Date().toISOString(),
        handleRemark: handleRemark,
      });

      // Refresh data
      await refetchIssuesData(inputs, "search", pagingController);
      handleCloseDialog();
    } catch (error) {
      console.error("Error updating issue status:", error);
    }
  };

  const getIssueCategoryColor = (category: string) => {
    switch (category.toLowerCase()) {
      case "lot_issue":
        return "error";
      case "quality_issue":
        return "warning";
      case "quantity_mismatch":
        return "info";
      default:
        return "default";
    }
  };

  // Table columns
  const columns: Column<PickExecutionIssue>[] = useMemo(
    () => [
      { name: "issueNo", label: t("Issue No") },
      { name: "pickOrderCode", label: t("Pick Order") },
      {
        name: "itemCode",
        label: t("Item"),
        renderCell: (params) => (
          <Box>
            <Typography variant="body2">{params.itemCode}</Typography>
            <Typography variant="caption" color="text.secondary">
              {params.itemDescription}
            </Typography>
          </Box>
        ),
      },
      { 
        name: "lotNo", 
        label: t("Lot No"),
        renderCell: (params) => params.lotNo || "-"
      },
      { name: "requiredQty", label: t("Required Qty"), align: "right", type: "integer" },
      { 
        name: "actualPickQty", 
        label: t("Actual Qty"), 
        align: "right", 
        type: "integer",
        renderCell: (params) => params.actualPickQty || 0
      },
      { 
        name: "missQty", 
        label: t("Miss Qty"), 
        align: "right", 
        type: "integer",
        renderCell: (params) => params.missQty || 0
      },
      {
        name: "issueCategory",
        label: t("Category"),
        renderCell: (params) => (
          <Chip
            label={t(params.issueCategory)}
            size="small"
            color={getIssueCategoryColor(params.issueCategory)}
          />
        ),
      },
      {
        name: "handleStatus",
        label: t("Status"),
        renderCell: (params) => (
          <Chip
            label={t(params.handleStatus)}
            size="small"
            color={
              params.handleStatus.toLowerCase() === "pending"
                ? "warning"
                : "success"
            }
          />
        ),
      },
      {
        name: "pickExecutionDate",
        label: t("Date"),
        renderCell: (params) => dayjs(params.pickExecutionDate).format(OUTPUT_DATE_FORMAT),
      },
      {
        name: "id",
        label: t("Action"),
        renderCell: (params) => (
          <Button size="small" onClick={() => handleViewDetail(params)}>
            {t("Detail")}
          </Button>
        ),
      },
    ],
    [t, handleViewDetail],
  );

  return (
    <Box>
      <SearchBox
        criteria={searchCriteria}
        onSearch={onSearch}
        onReset={onReset}
      />

      <SearchResults<PickExecutionIssue>
        items={issues}
        columns={columns}
        pagingController={pagingController}
        setPagingController={setPagingController}
        totalCount={totalCount}
      />

      {/* Handle Issue Dialog */}
      <Dialog open={handleDialogOpen} onClose={handleCloseDialog} maxWidth="md" fullWidth>
        <DialogTitle>{t("Issue Detail")}</DialogTitle>
        <DialogContent>
          {selectedIssue && (
            <Stack spacing={2} sx={{ mt: 2 }}>
              <Box>
                <Typography variant="subtitle2" color="text.secondary">
                  {t("Issue No")}
                </Typography>
                <Typography variant="body1">{selectedIssue.issueNo}</Typography>
              </Box>

              <Box>
                <Typography variant="subtitle2" color="text.secondary">
                  {t("Pick Order")}
                </Typography>
                <Typography variant="body1">{selectedIssue.pickOrderCode}</Typography>
              </Box>

              <Box>
                <Typography variant="subtitle2" color="text.secondary">
                  {t("Item")}
                </Typography>
                <Typography variant="body1">
                  {selectedIssue.itemCode} - {selectedIssue.itemDescription}
                </Typography>
              </Box>

              {selectedIssue.lotNo && (
                <Box>
                  <Typography variant="subtitle2" color="text.secondary">
                    {t("Lot No")}
                  </Typography>
                  <Typography variant="body1">{selectedIssue.lotNo}</Typography>
                </Box>
              )}

              <Box>
                <Typography variant="subtitle2" color="text.secondary">
                  {t("Location")}
                </Typography>
                <Typography variant="body1">{selectedIssue.storeLocation || "-"}</Typography>
              </Box>

              <Stack direction="row" spacing={3}>
                <Box>
                  <Typography variant="subtitle2" color="text.secondary">
                    {t("Required Qty")}
                  </Typography>
                  <Typography variant="body1">{selectedIssue.requiredQty}</Typography>
                </Box>
                <Box>
                  <Typography variant="subtitle2" color="text.secondary">
                    {t("Actual Qty")}
                  </Typography>
                  <Typography variant="body1">{selectedIssue.actualPickQty || 0}</Typography>
                </Box>
                <Box>
                  <Typography variant="subtitle2" color="text.secondary">
                    {t("Miss Qty")}
                  </Typography>
                  <Typography variant="body1" color="error">
                    {selectedIssue.missQty || 0}
                  </Typography>
                </Box>
              </Stack>

              {selectedIssue.issueRemark && (
                <Box>
                  <Typography variant="subtitle2" color="text.secondary">
                    {t("Issue Remark")}
                  </Typography>
                  <Typography variant="body1">{selectedIssue.issueRemark}</Typography>
                </Box>
              )}

              <Box>
                <Typography variant="subtitle2" color="text.secondary">
                  {t("Picker")}
                </Typography>
                <Typography variant="body1">{selectedIssue.pickerName || "-"}</Typography>
              </Box>

              <Box>
                <Typography variant="subtitle2" color="text.secondary">
                  {t("Status")}
                </Typography>
                <Chip
                  label={t(selectedIssue.handleStatus)}
                  size="small"
                  color={
                    selectedIssue.handleStatus.toLowerCase() === "pending"
                      ? "warning"
                      : "success"
                  }
                />
              </Box>

              {selectedIssue.handleStatus.toLowerCase() === "pending" && (
                <TextField
                  label={t("Handle Remark")}
                  multiline
                  rows={3}
                  value={handleRemark}
                  onChange={(e) => setHandleRemark(e.target.value)}
                  fullWidth
                />
              )}
            </Stack>
          )}
        </DialogContent>
        <DialogActions>
          <Button onClick={handleCloseDialog}>{t("Close")}</Button>
          {selectedIssue && selectedIssue.handleStatus.toLowerCase() === "pending" && (
            <Button onClick={handleMarkAsResolved} variant="contained" color="primary">
              {t("Mark as Resolved")}
            </Button>
          )}
        </DialogActions>
      </Dialog>
    </Box>
  );
};

export default PickExecutionIssuesTab;