"use client";

import {
  ModalFormInput,
  PurchaseQCInput,
  PurchaseQcResult,
  StockInInput,
  StockInLineEntry,
  updateStockInLine,
} from "@/app/api/po/actions";
import { Box, Button, Modal, ModalProps, Stack } from "@mui/material";
import {
  Dispatch,
  SetStateAction,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
} from "react";
import { FormProvider, SubmitHandler, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import QcForm from "./QcForm";
import { QcItemWithChecks } from "@/app/api/qc";
import { Check, CurrencyYuanRounded, TtyTwoTone } from "@mui/icons-material";
import { PurchaseOrderLine, StockInLine } from "@/app/api/po";
import { useSearchParams } from "next/navigation";
import { StockInLineRow } from "./PoInputGrid";
import EscalationForm from "./EscalationForm";
import StockInFormOld from "./StockInFormOld";
import PutAwayForm from "./PutAwayForm"; 
import {
  INPUT_DATE_FORMAT,
  stockInLineStatusMap,
} from "@/app/utils/formatUtil";
import dayjs from "dayjs";
import arraySupport from "dayjs/plugin/arraySupport";
import { downloadFile } from "@/app/utils/commonUtil";
import { fetchPoQrcode } from "@/app/api/pdf/actions";
import UploadContext from "../UploadProvider/UploadProvider";
import useUploadContext from "../UploadProvider/useUploadContext";
import RejectForm from "./RejectForm";
import { isNullOrUndefined } from "html5-qrcode/esm/core";
import { isEmpty, isFinite } from "lodash";

dayjs.extend(arraySupport);
interface CommonProps extends Omit<ModalProps, "children"> {
  // setRows: Dispatch<SetStateAction<PurchaseOrderLine[]>>;
  setEntries?: Dispatch<SetStateAction<StockInLineRow[]>>;
  setStockInLine?: Dispatch<SetStateAction<StockInLine[]>>;
  itemDetail: StockInLine & { qcResult?: PurchaseQcResult[] };
  setItemDetail: Dispatch<
    SetStateAction<
      | (StockInLine & {
          warehouseId?: number;
        })
      | undefined
    >
  >;
  qc?: QcItemWithChecks[];
  warehouse?: any[];
  type: "qc" | "stockIn" | "escalation" | "putaway" | "reject";
}
interface QcProps extends CommonProps {
  qc: QcItemWithChecks[];
  type: "qc";
}
interface StockInProps extends CommonProps {
  // naming
  type: "stockIn";
}
interface PutawayProps extends CommonProps {
  warehouse: any[];
  type: "putaway";
}
interface EscalationProps extends CommonProps {
  // naming
  type: "escalation";
}
interface RejectProps extends CommonProps {
  // naming
  type: "reject";
}

type Props =
  | QcProps
  | StockInProps
  | PutawayProps
  | EscalationProps
  | RejectProps;
const style = {
  position: "absolute",
  top: "50%",
  left: "50%",
  transform: "translate(-50%, -50%)",
  overflow: "scroll",
  bgcolor: "background.paper",
  pt: 5,
  px: 5,
  pb: 10,
  display: "block",
  width: { xs: "60%", sm: "60%", md: "60%" },
};

const PoQcStockInModal: React.FC<Props> = ({
  type,
  // setRows,
  setEntries,
  setStockInLine,
  open,
  onClose,
  itemDetail,
  setItemDetail,
  qc,
  warehouse,
}) => {
  const { setIsUploading } = useUploadContext();

  const [serverError, setServerError] = useState("");
  const { t } = useTranslation("purchaseOrder");
  const params = useSearchParams();
  const [btnIsLoading, setBtnIsLoading] = useState(false);

  // console.log(params.get("id"));
  // console.log(itemDetail);
  // console.log(itemDetail.qcResult);
  const formProps = useForm<ModalFormInput>({
    defaultValues: {
      ...itemDetail,
      // receiptDate: itemDetail.receiptDate || dayjs().add(-1, "month").format(INPUT_DATE_FORMAT),
      // warehouseId: itemDetail.defaultWarehouseId || 0
    },
  });
  // console.log(formProps);
  const errors = formProps.formState.errors;
  const closeHandler = useCallback<NonNullable<ModalProps["onClose"]>>(
    (...args) => {
      onClose?.(...args);
      //   reset();
    },
    [onClose],
  );

  useEffect(() => {
    // setDefaultValues({...itemDetail});
    if (!itemDetail) {
      console.log(itemDetail);
    }
  }, [itemDetail]);

  // const fix0IndexedDate = useCallback((date: string | number[] | undefined) => {
  //   if (Array.isArray(date)) {
  //     console.log(date);
  //     return dayjs([date[0], date[1] - 1, date[2]]).format("YYYY-MM-DD");
  //   }
  //   return date;
  // }, []);
  const accQty = formProps.watch("acceptedQty");
  useEffect(() => {
    formProps.clearErrors("acceptedQty")
  }, [accQty])

  const productLotNo = formProps.watch("productLotNo");
  const checkStockIn = useCallback(
    (data: ModalFormInput): boolean => {
      let hasErrors = false;
      if (accQty! <= 0 ) {
        formProps.setError("acceptedQty", {
          message: `${t("Accepted qty must greater than")} ${
            0
          }`,
          type: "required",
        });
        hasErrors = true;
      } else if (accQty! > itemDetail.acceptedQty) {
        formProps.setError("acceptedQty", {
          message: `${t("Accepted qty must not greater than")} ${
            itemDetail.acceptedQty
          }`,
          type: "required",
        });
        hasErrors = true;
      }

      if (isEmpty(productLotNo)) {
        formProps.setError("productLotNo", {
          message: `${t("Product Lot No must not be empty")}`,
          type: "required",
        });
        hasErrors = true;
      }

      if (itemDetail.shelfLife && !data.productionDate && !data.expiryDate) {
        formProps.setError("productionDate", {
          message: "Please provide at least one",
          type: "invalid",
        });
        formProps.setError("expiryDate", {
          message: "Please provide at least one",
          type: "invalid",
        });
        hasErrors = true;
      }
      if (!itemDetail.shelfLife && !data.expiryDate) {
        formProps.setError("expiryDate", {
          message: "Please provide expiry date",
          type: "invalid",
        });
        hasErrors = true;
      }

      if (data.expiryDate && data.expiryDate < data.receiptDate!) {
        formProps.setError("expiryDate", {
          message: "Expired",
          type: "invalid",
        });
        hasErrors = true;
      }
      return hasErrors;
    },
    [accQty, itemDetail.acceptedQty, itemDetail.shelfLife, productLotNo, formProps, t],
  );

  const checkPutaway = useCallback(
    (data: ModalFormInput): boolean => {
      let hasErrors = false;
      console.log(data.warehouseId);
      if (!data.warehouseId || data.warehouseId <= 0) {
        formProps.setError("warehouseId", {
          message: "Please provide warehouseId",
          type: "invalid",
        });
        hasErrors = true;
      }
      return hasErrors;
    },
    [itemDetail, formProps],
  );

  const onSubmit = useCallback<SubmitHandler<ModalFormInput>>(
    async (data, event) => {
      setBtnIsLoading(true);
      setIsUploading(true);
      formProps.clearErrors();
      let hasErrors = false;
      console.log(errors);
      console.log(data);
      console.log(itemDetail);
      // console.log(fix0IndexedDate(data.receiptDate));
      try {
        // add checking
        if (type === "stockIn") {
          hasErrors = checkStockIn(data);
          console.log(hasErrors);
        }
        if (type === "putaway") {
          hasErrors = checkPutaway(data);
          console.log(hasErrors);
        }
        //////////////////////// modify this mess later //////////////////////
        let productionDate = null;
        let expiryDate = null;
        let receiptDate = null;
        let acceptedQty = null;
        if (data.productionDate) {
          productionDate = dayjs(data.productionDate).format(INPUT_DATE_FORMAT);
        }
        if (data.expiryDate) {
          expiryDate = dayjs(data.expiryDate).format(INPUT_DATE_FORMAT);
        }
        if (data.receiptDate) {
          receiptDate = dayjs(data.receiptDate).format(INPUT_DATE_FORMAT);
        }
        // if ()
        if (data.qcResult) {
          acceptedQty =
            itemDetail.acceptedQty -
            data.qcResult.reduce((acc, curr) => acc + curr.failQty, 0);
        }
        const args = {
          id: itemDetail.id,
          purchaseOrderId: parseInt(params.get("id")!),
          purchaseOrderLineId: itemDetail.purchaseOrderLineId,
          itemId: itemDetail.itemId,
          ...data,
          productionDate: productionDate,
          expiryDate: expiryDate,
          receiptDate: receiptDate,
        } as StockInLineEntry & ModalFormInput;
        //////////////////////////////////////////////////////////////////////
        if (hasErrors) {
          console.log(args);
          setServerError(t("An error has occurred. Please try again later."));
          setBtnIsLoading(false);
          setIsUploading(false);
          return;
        }
        console.log(args);
        // setBtnIsLoading(false);
        // setIsUploading(false)
        // return
        const res = await updateStockInLine(args);
        if (Boolean(res.id)) {
          // update entries
          const newEntries = res.entity as StockInLine[];
          console.log(newEntries);
          if (setEntries) {
            setEntries((prev) => {
              const updatedEntries = [...prev]; // Create a new array
              newEntries.forEach((item) => {
                const index = updatedEntries.findIndex((p) => p.id === item.id);
                if (index !== -1) {
                  // Update existing item
                  console.log(item);
                  updatedEntries[index] = item;
                } else {
                  // Add new item
                  updatedEntries.push(item);
                }
              });
              return updatedEntries; // Return the new array
            });
          }
          if (setStockInLine) {
            setStockInLine((prev) => {
              const updatedEntries = [...prev]; // Create a new array
              newEntries.forEach((item) => {
                const index = updatedEntries.findIndex((p) => p.id === item.id);
                if (index !== -1) {
                  // Update existing item
                  console.log(item);
                  updatedEntries[index] = item;
                } else {
                  // Add new item
                  updatedEntries.push(item);
                }
              });
              return updatedEntries; // Return the new array
            });
          }
          // add loading
          setBtnIsLoading(false);
          setIsUploading(false);
          setItemDetail(undefined);
          closeHandler({}, "backdropClick");
        }
        console.log(res);
        // if (res)
      } catch (e) {
        // server error
        setBtnIsLoading(false);
        setIsUploading(false);
        setServerError(t("An error has occurred. Please try again later."));
        console.log(e);
      }
    },
    [setIsUploading, formProps, errors, itemDetail, type, params, checkStockIn, checkPutaway, t, setEntries, setStockInLine, setItemDetail, closeHandler],
  );

  const printQrcode = useCallback(async () => {
    setBtnIsLoading(true);
    setIsUploading(true);
    const postData = { stockInLineIds: [itemDetail.id] };
    // const postData = { stockInLineIds: [42,43,44] };
    const response = await fetchPoQrcode(postData);
    if (response) {
      console.log(response);
      downloadFile(new Uint8Array(response.blobValue), response.filename!);
    }
    setBtnIsLoading(false);
    setIsUploading(false);
  }, [setIsUploading, itemDetail.id]);

  const renderSubmitButton = useMemo((): boolean => {
    if (itemDetail) {
      const status = itemDetail.status;
      console.log(status);
      switch (type) {
        case "qc":
          return (
            stockInLineStatusMap[status] >= 1 &&
            stockInLineStatusMap[status] <= 2
          );
        case "escalation":
          return (
            stockInLineStatusMap[status] === 1 ||
            stockInLineStatusMap[status] >= 3 ||
            stockInLineStatusMap[status] <= 5
          );
        case "stockIn":
          return (
            stockInLineStatusMap[status] >= 3 &&
            stockInLineStatusMap[status] <= 6
          );
        case "putaway":
          return stockInLineStatusMap[status] === 7;
        case "reject":
          return (
            stockInLineStatusMap[status] >= 1 &&
            stockInLineStatusMap[status] <= 6
          );
        default:
          return false; // Handle unexpected type
      }
    } else return false;
  }, [type, itemDetail]);
  // useEffect(() => {
  //   console.log(renderSubmitButton)
  // }, [renderSubmitButton])

  return (
    <>
      <FormProvider {...formProps}>
        <Modal open={open} onClose={closeHandler} sx={{ overflow: "scroll" }}>
          <Box
            sx={style}
            component="form"
            onSubmit={formProps.handleSubmit(onSubmit)}
          >
            {itemDetail !== undefined && type === "qc" && (
              <QcForm
                qc={qc!}
                itemDetail={itemDetail}
                disabled={!renderSubmitButton}
              />
            )}
            {itemDetail !== undefined && type === "escalation" && (
              <EscalationForm
                itemDetail={itemDetail}
                disabled={!renderSubmitButton}
              />
            )}
            {itemDetail !== undefined && type === "stockIn" && (
              <StockInFormOld
                itemDetail={itemDetail}
                disabled={!renderSubmitButton}
              />
            )}
            {itemDetail !== undefined && type === "putaway" && (
              <PutAwayForm
                itemDetail={itemDetail}
                warehouse={warehouse!}
                disabled={!renderSubmitButton}
              />
            )}
            {itemDetail !== undefined && type === "reject" && (
              <RejectForm
                itemDetail={itemDetail}
                disabled={!renderSubmitButton}
              />
            )}
            <Stack direction="row" justifyContent="flex-end" gap={1}>
              {renderSubmitButton ? (
                <Button
                  name="submit"
                  variant="contained"
                  startIcon={<Check />}
                  type="submit"
                  disabled={btnIsLoading}
                >
                  {t("submit")}
                </Button>
              ) : undefined}
              {itemDetail !== undefined && type === "putaway" && (
                <Button
                  name="print"
                  variant="contained"
                  // startIcon={<Check />}
                  onClick={printQrcode}
                  disabled={btnIsLoading}
                >
                  {t("print")}
                </Button>
              )}
            </Stack>
          </Box>
        </Modal>
      </FormProvider>
    </>
  );
};
export default PoQcStockInModal;
