"use client";
import {
  Autocomplete,
  Box,
  Button,
  CircularProgress,
  FormControl,
  Grid,
  Modal,
  TextField,
  Typography,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Paper,
  Checkbox,
  TablePagination,
} from "@mui/material";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import {
  newassignPickOrder,
  AssignPickOrderInputs,
  releaseAssignedPickOrders,
  fetchPickOrderWithStockClient, // Add this import
} from "@/app/api/pickOrder/actions";
import { fetchNameList, NameList } from "@/app/api/user/actions";
import {
  FormProvider,
  useForm,
} from "react-hook-form";
import { isEmpty, upperFirst, groupBy } from "lodash";
import { OUTPUT_DATE_FORMAT, arrayToDayjs } from "@/app/utils/formatUtil";
import useUploadContext from "../UploadProvider/useUploadContext";
import dayjs from "dayjs";
import arraySupport from "dayjs/plugin/arraySupport";
import SearchBox, { Criterion } from "../SearchBox";
import { sortBy, uniqBy } from "lodash";
import { createStockOutLine, CreateStockOutLine, fetchPickOrderDetails } from "@/app/api/pickOrder/actions";
dayjs.extend(arraySupport);

interface Props {
  filterArgs: Record<string, any>;
}

// Update the interface to match the new API response structure
interface PickOrderRow {
  id: string;
  code: string;
  targetDate: string;
  type: string;
  status: string;
  assignTo: number;
  groupName: string;
  consoCode?: string;
  pickOrderLines: PickOrderLineRow[];
}

interface PickOrderLineRow {
  id: number;
  itemId: number;
  itemCode: string;
  itemName: string;
  availableQty: number | null;
  requiredQty: number;
  uomCode: string;
  uomDesc: string;
  suggestedList: any[];
}

const style = {
  position: "absolute",
  top: "50%",
  left: "50%",
  transform: "translate(-50%, -50%)",
  bgcolor: "background.paper",
  pt: 5,
  px: 5,
  pb: 10,
  width: { xs: "100%", sm: "100%", md: "100%" },
};

const AssignTo: React.FC<Props> = ({ filterArgs }) => {
  const { t } = useTranslation("pickOrder");
  const { setIsUploading } = useUploadContext();
  const [isUploading, setIsUploadingLocal] = useState(false);
  // Update state to use pick order data directly
  const [selectedPickOrderIds, setSelectedPickOrderIds] = useState<string[]>([]);
  const [filteredPickOrders, setFilteredPickOrders] = useState<PickOrderRow[]>([]);
  const [isLoadingItems, setIsLoadingItems] = useState(false);
  const [pagingController, setPagingController] = useState({
    pageNum: 1,
    pageSize: 10,
  });
  const [totalCountItems, setTotalCountItems] = useState<number>();
  const [modalOpen, setModalOpen] = useState(false);
  const [usernameList, setUsernameList] = useState<NameList[]>([]);
  const [searchQuery, setSearchQuery] = useState<Record<string, any>>({});
  const [originalPickOrderData, setOriginalPickOrderData] = useState<PickOrderRow[]>([]);

  const formProps = useForm<AssignPickOrderInputs>();
  const errors = formProps.formState.errors;

  // Update the handler functions to work with string IDs
  const handlePickOrderSelect = useCallback((pickOrderId: string, checked: boolean) => {
    if (checked) {
      setSelectedPickOrderIds(prev => [...prev, pickOrderId]);
    } else {
      setSelectedPickOrderIds(prev => prev.filter(id => id !== pickOrderId));
    }
  }, []);

  const isPickOrderSelected = useCallback((pickOrderId: string) => {
    return selectedPickOrderIds.includes(pickOrderId);
  }, [selectedPickOrderIds]);

  // Update the fetch function to use the correct endpoint
  const fetchNewPageItems = useCallback(
    async (pagingController: Record<string, number>, filterArgs: Record<string, any>) => {
      setIsLoadingItems(true);
      try {
        const params = {
          ...pagingController,
          ...filterArgs,
          pageNum: (pagingController.pageNum || 1) - 1,
          pageSize: pagingController.pageSize || 10,
          // Filter for assigned status only
          status: "assigned"
        };

        const res = await fetchPickOrderWithStockClient(params);

        if (res && res.records) {
          // Convert pick order data to the expected format
          const pickOrderRows: PickOrderRow[] = res.records.map((pickOrder: any) => ({
            id: pickOrder.id,
            code: pickOrder.code,
            targetDate: pickOrder.targetDate,
            type: pickOrder.type,
            status: pickOrder.status,
            assignTo: pickOrder.assignTo,
            groupName: pickOrder.groupName || "No Group",
            consoCode: pickOrder.consoCode,
            pickOrderLines: pickOrder.pickOrderLines || []
          }));
          
          setOriginalPickOrderData(pickOrderRows);
          setFilteredPickOrders(pickOrderRows);
          setTotalCountItems(res.total);
        } else {
          setFilteredPickOrders([]);
          setTotalCountItems(0);
        }
      } catch (error) {
        console.error("Error fetching pick orders:", error);
        setFilteredPickOrders([]);
        setTotalCountItems(0);
      } finally {
        setIsLoadingItems(false);
      }
    },
    [],
  );

  // Handle Release operation
// Handle Release operation
const handleRelease = useCallback(async () => {
  if (selectedPickOrderIds.length === 0) return;
  
  setIsUploading(true);
  try {
    // Get the assigned user from the selected pick orders
    const selectedPickOrders = filteredPickOrders.filter(pickOrder => 
      selectedPickOrderIds.includes(pickOrder.id)
    );
    
    // Check if all selected pick orders have the same assigned user
    const assignedUsers = selectedPickOrders.map(po => po.assignTo).filter(Boolean);
    if (assignedUsers.length === 0) {
      alert("Selected pick orders are not assigned to any user.");
      return;
    }
    
    const assignToValue = assignedUsers[0];
    
    // Validate that all pick orders are assigned to the same user
    const allSameUser = assignedUsers.every(userId => userId === assignToValue);
    if (!allSameUser) {
      alert("All selected pick orders must be assigned to the same user.");
      return;
    }
    
    console.log("Using assigned user:", assignToValue);
    console.log("selectedPickOrderIds:", selectedPickOrderIds);
    
    const releaseRes = await releaseAssignedPickOrders({
      pickOrderIds: selectedPickOrderIds.map(id => parseInt(id)),
      assignTo: assignToValue
    });
    
    if (releaseRes.code === "SUCCESS") {
      console.log("Pick orders released successfully");
      
      // Get the consoCode from the response
      const consoCode = (releaseRes.entity as any)?.consoCode;
      
      if (consoCode) {
        // Create StockOutLine records for each pick order line
        for (const pickOrder of selectedPickOrders) {
          for (const line of pickOrder.pickOrderLines) {
            try {
              const stockOutLineData = {
                consoCode: consoCode,
                pickOrderLineId: line.id,
                inventoryLotLineId: 0, // This will be set when user scans QR code
                qty: line.requiredQty,
              };
              
              console.log("Creating stock out line:", stockOutLineData);
              await createStockOutLine(stockOutLineData);
            } catch (error) {
              console.error("Error creating stock out line for line", line.id, error);
            }
          }
        }
      }
      
      fetchNewPageItems(pagingController, filterArgs);
    } else {
      console.error("Release failed:", releaseRes.message);
    }
  } catch (error) {
    console.error("Error releasing pick orders:", error);
  } finally {
    setIsUploading(false);
  }
}, [selectedPickOrderIds, filteredPickOrders, setIsUploading, fetchNewPageItems, pagingController, filterArgs]);

  // Update search criteria to match the new data structure
  const searchCriteria: Criterion<any>[] = useMemo(
    () => [
      {
        label: t("Pick Order Code"),
        paramName: "code",
        type: "text",
      },
      {
        label: t("Group Code"),
        paramName: "groupName",
        type: "text",
      },
      {
        label: t("Target Date From"),
        label2: t("Target Date To"),
        paramName: "targetDate",
        type: "dateRange",
      },
    ],
    [t],
  );

  // Update search function to work with pick order data
  const handleSearch = useCallback((query: Record<string, any>) => {
    setSearchQuery({ ...query });

    const filtered = originalPickOrderData.filter((pickOrder) => {
      const pickOrderTargetDateStr = arrayToDayjs(pickOrder.targetDate);

      const codeMatch = !query.code || 
        pickOrder.code?.toLowerCase().includes((query.code || "").toLowerCase());
      
      const groupNameMatch = !query.groupName || 
        pickOrder.groupName?.toLowerCase().includes((query.groupName || "").toLowerCase());
      
      // Date range search
      let dateMatch = true;
      if (query.targetDate || query.targetDateTo) {
        try {
          if (query.targetDate && !query.targetDateTo) {
            const fromDate = dayjs(query.targetDate);
            dateMatch = pickOrderTargetDateStr.isSame(fromDate, 'day') || 
                       pickOrderTargetDateStr.isAfter(fromDate, 'day');
          } else if (!query.targetDate && query.targetDateTo) {
            const toDate = dayjs(query.targetDateTo);
            dateMatch = pickOrderTargetDateStr.isSame(toDate, 'day') || 
                       pickOrderTargetDateStr.isBefore(toDate, 'day');
          } else if (query.targetDate && query.targetDateTo) {
            const fromDate = dayjs(query.targetDate);
            const toDate = dayjs(query.targetDateTo);
            dateMatch = (pickOrderTargetDateStr.isSame(fromDate, 'day') || 
                        pickOrderTargetDateStr.isAfter(fromDate, 'day')) &&
                       (pickOrderTargetDateStr.isSame(toDate, 'day') || 
                        pickOrderTargetDateStr.isBefore(toDate, 'day'));
          }
        } catch (error) {
          console.error("Date parsing error:", error);
          dateMatch = true;
        }
      }

      return codeMatch && groupNameMatch && dateMatch;
    });
    
    setFilteredPickOrders(filtered);
  }, [originalPickOrderData]);

  const handleReset = useCallback(() => {
    setSearchQuery({});
    setFilteredPickOrders(originalPickOrderData);
    setTimeout(() => {
      setSearchQuery({});
    }, 0);
  }, [originalPickOrderData]);

  // Pagination handlers
  const handlePageChange = useCallback((event: unknown, newPage: number) => {
    const newPagingController = {
      ...pagingController,
      pageNum: newPage + 1,
    };
    setPagingController(newPagingController);
  }, [pagingController]);

  const handlePageSizeChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
    const newPageSize = parseInt(event.target.value, 10);
    const newPagingController = {
      pageNum: 1,
      pageSize: newPageSize,
    };
    setPagingController(newPagingController);
  }, []);

  // Component mount effect
  useEffect(() => {
    fetchNewPageItems(pagingController, filterArgs || {});
  }, []);

  // Dependencies change effect
  useEffect(() => {
    if (pagingController && (filterArgs || {})) {
      fetchNewPageItems(pagingController, filterArgs || {});
    }
  }, [pagingController, filterArgs, fetchNewPageItems]);

  useEffect(() => {
    const loadUsernameList = async () => {
      try {
        const res = await fetchNameList();
        if (res) {
          setUsernameList(res);
        }
      } catch (error) {
        console.error("Error loading username list:", error);
      }
    };
    loadUsernameList();
  }, []);

  // Update the table component to work with pick order data directly
  const CustomPickOrderTable = () => {
    // Helper function to get user name
    const getUserName = useCallback((assignToId: number | null | undefined) => {
      if (!assignToId) return '-';
      const user = usernameList.find(u => u.id === assignToId);
      return user ? user.name : `User ${assignToId}`;
    }, [usernameList]);

    return (
      <>
        <TableContainer component={Paper}>
          <Table>
            <TableHead>
              <TableRow>
                <TableCell>{t("Selected")}</TableCell>
                <TableCell>{t("Pick Order Code")}</TableCell>
                <TableCell>{t("Group Code")}</TableCell>
                <TableCell>{t("Item Code")}</TableCell>
                <TableCell>{t("Item Name")}</TableCell>
                <TableCell align="right">{t("Order Quantity")}</TableCell>
                <TableCell align="right">{t("Current Stock")}</TableCell>
                <TableCell align="right">{t("Stock Unit")}</TableCell>
                <TableCell>{t("Target Date")}</TableCell>
                <TableCell>{t("Assigned To")}</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {filteredPickOrders.length === 0 ? (
                <TableRow>
                  <TableCell colSpan={10} align="center">
                    <Typography variant="body2" color="text.secondary">
                      {t("No data available")}
                    </Typography>
                  </TableCell>
                </TableRow>
              ) : (
                filteredPickOrders.map((pickOrder) => (
                  pickOrder.pickOrderLines.map((line: PickOrderLineRow, index: number) => (
                    <TableRow key={`${pickOrder.id}-${line.id}`}>
                      {/* Checkbox - only show for first line of each pick order */}
                      <TableCell>
                        {index === 0 ? (
                          <Checkbox
                            checked={isPickOrderSelected(pickOrder.id)}
                            onChange={(e) => handlePickOrderSelect(pickOrder.id, e.target.checked)}
                            disabled={!isEmpty(pickOrder.consoCode)}
                          />
                        ) : null}
                      </TableCell>
                      {/* Pick Order Code - only show for first line */}
                      <TableCell>
                        {index === 0 ? pickOrder.code : null}
                      </TableCell>
                      {/* Group Name - only show for first line */}
                      <TableCell>
                        {index === 0 ? pickOrder.groupName : null}
                      </TableCell>
                      {/* Item Code */}
                      <TableCell>{line.itemCode}</TableCell>
                      {/* Item Name */}
                      <TableCell>{line.itemName}</TableCell>
                      
                      {/* Order Quantity */}
                      <TableCell align="right">{line.requiredQty}</TableCell>
                      
                      {/* Current Stock */}
                      <TableCell align="right">
                        <Typography 
                          variant="body2" 
                          color={line.availableQty && line.availableQty > 0 ? "success.main" : "error.main"}
                          sx={{ fontWeight: line.availableQty && line.availableQty > 0 ? 'bold' : 'normal' }}
                        >
                          {(line.availableQty || 0).toLocaleString()}
                        </Typography>
                      </TableCell>
                      
                      {/* Unit */}
                      <TableCell align="right">{line.uomDesc}</TableCell>
                      
                      {/* Target Date - only show for first line */}
                      <TableCell>
                        {index === 0 ? (
                          arrayToDayjs(pickOrder.targetDate)
                            .add(-1, "month")
                            .format(OUTPUT_DATE_FORMAT)
                        ) : null}
                      </TableCell>
                      
                      {/* Assigned To - only show for first line */}
                      <TableCell>
                        {index === 0 ? (
                          <Typography variant="body2">
                            {getUserName(pickOrder.assignTo)}
                          </Typography>
                        ) : null}
                      </TableCell>
                    </TableRow>
                  ))
                ))
              )}
            </TableBody>
          </Table>
        </TableContainer>
        
        <TablePagination
          component="div"
          count={totalCountItems || 0}
          page={(pagingController.pageNum - 1)}
          rowsPerPage={pagingController.pageSize}
          onPageChange={handlePageChange}
          onRowsPerPageChange={handlePageSizeChange}
          rowsPerPageOptions={[10, 25, 50, 100]}
          labelRowsPerPage={t("Rows per page")}
          labelDisplayedRows={({ from, to, count }) => 
            `${from}-${to} of ${count !== -1 ? count : `more than ${to}`}`
          }
        />
      </>
    );
  };

  return (
    <>
      <SearchBox criteria={searchCriteria} onSearch={handleSearch} onReset={handleReset} />
      <Grid container rowGap={1}>
        <Grid item xs={12}>
          {isLoadingItems ? (
            <CircularProgress size={40} />
          ) : (
            <CustomPickOrderTable />
          )}
        </Grid>
        <Grid item xs={12}>
          <Box sx={{ display: "flex", justifyContent: "flex-start", mt: 2 }}>
            <Button
              disabled={selectedPickOrderIds.length < 1}
              variant="outlined"
              onClick={handleRelease}
            >
              {t("Release")}
            </Button>
          </Box>
        </Grid>
      </Grid>
    </>
  );
};

export default AssignTo;