"use client";
import { StockInLine } from "@/app/api/po";
import { ModalFormInput, PurchaseQcResult, StockInLineEntry, updateStockInLine, PurchaseQCInput, printQrCodeForSil, PrintQrCodeForSilRequest } from "@/app/api/po/actions";
import { QcItemWithChecks, QcData } from "@/app/api/qc";
import {
  Autocomplete,
  Box,
  Button,
  Grid,
  Modal,
  ModalProps,
  Stack,
  TextField,
  Typography,
} from "@mui/material";
import { Dispatch, SetStateAction, useCallback, useEffect, useMemo, useState } from "react";
import { FormProvider, SubmitErrorHandler, SubmitHandler, useForm } from "react-hook-form";
import { StockInLineRow } from "./PoInputGrid";
import { useTranslation } from "react-i18next";
import StockInForm from "./StockInForm";
import StockInFormVer2 from "./StockInFormVer2";
import QcComponent from "./QcComponent";
import { dummyPutAwayLine, dummyQCData } from "./dummyQcTemplate";
// import QcFormVer2 from "./QcFormVer2";
import PutAwayForm from "./PutAwayForm";
import { GridRowModes, useGridApiRef } from "@mui/x-data-grid";
import {submitDialogWithWarning} from "../Swal/CustomAlerts";
import { INPUT_DATE_FORMAT, arrayToDateString, arrayToInputDateString, dayjsToInputDateString } from "@/app/utils/formatUtil";
import dayjs from "dayjs";
import { fetchPoQrcode } from "@/app/api/pdf/actions";
import { downloadFile } from "@/app/utils/commonUtil";
import { PrinterCombo } from "@/app/api/settings/printer";
import { EscalationResult } from "@/app/api/escalation";
import { SessionWithTokens } from "@/config/authConfig";
import { GridRowModesModel } from "@mui/x-data-grid";
import { isEmpty } from "lodash";


const style = {
  position: "absolute",
  top: "50%",
  left: "50%",
  transform: "translate(-50%, -50%)",
  bgcolor: "background.paper",
  pt: 5,
  px: 5,
  pb: 10,
  display: "block",
  width: { xs: "90%", sm: "90%", md: "90%" },
  //   height: { xs: "60%", sm: "60%", md: "60%" },
};
interface CommonProps extends Omit<ModalProps, "children"> {
  // setRows: Dispatch<SetStateAction<PurchaseOrderLine[]>>;
  setEntries?: Dispatch<SetStateAction<StockInLineRow[]>>;
  setStockInLine?: Dispatch<SetStateAction<StockInLine[]>>;
  itemDetail: StockInLine & { qcResult?: PurchaseQcResult[] } & { escResult?: EscalationResult[] };
  setItemDetail: Dispatch<
    SetStateAction<
      | (StockInLine & {
          warehouseId?: number;
        })
      | undefined
    >
  >;
  session: SessionWithTokens | null;
  qc?: QcItemWithChecks[];
  warehouse?: any[];
  //   type: "qc" | "stockIn" | "escalation" | "putaway" | "reject";
  handleMailTemplateForStockInLine: (stockInLineId: number) => void;
  printerCombo: PrinterCombo[];
  onClose: () => void;
}
interface Props extends CommonProps {
  itemDetail: StockInLine & { qcResult?: PurchaseQcResult[] } & { escResult?: EscalationResult[] };
}
const PoQcStockInModalVer2: React.FC<Props> = ({
  // type,
  // setRows,
  setEntries,
  setStockInLine,
  open,
  onClose,
  itemDetail,
  setItemDetail,
  session,
  qc,
  warehouse,
  handleMailTemplateForStockInLine,
  printerCombo
}) => {
  const {
    t,
    i18n: { language },
  } = useTranslation("purchaseOrder");

  // Select Printer
  const [selectedPrinter, setSelectedPrinter] = useState(printerCombo[0]);

const defaultNewValue = useMemo(() => {
  return (
    {
      ...itemDetail,
      status: itemDetail.status ?? "pending",
      dnDate: arrayToInputDateString(itemDetail.dnDate)?? dayjsToInputDateString(dayjs()),
      // putAwayLines: dummyPutAwayLine,
      // putAwayLines: itemDetail.putAwayLines.map((line) => (return {...line, printQty: 1})) ?? [],
      putAwayLines: itemDetail.putAwayLines?.map((line) => ({...line, printQty: 1, _isNew: false})) ?? [],
      // qcResult: (itemDetail.qcResult && itemDetail.qcResult?.length > 0) ? itemDetail.qcResult : [],//[...dummyQCData],
      escResult: (itemDetail.escResult && itemDetail.escResult?.length > 0) ? itemDetail.escResult : [],
      receiptDate: itemDetail.receiptDate ?? dayjs().add(0, "month").format(INPUT_DATE_FORMAT),
      acceptQty: itemDetail.demandQty?? itemDetail.acceptedQty,
      warehouseId: itemDetail.defaultWarehouseId ?? 1
    }
  )
},[itemDetail])

const [qcItems, setQcItems] = useState(dummyQCData)
  const formProps = useForm<ModalFormInput>({
    defaultValues: {
      ...defaultNewValue,
    },
  });
  
  const closeHandler = useCallback<NonNullable<ModalProps["onClose"]>>(
    () => {
      onClose?.();
      //   reset();
    },
    [onClose],
  );
  
  const isPutaway = () => {
    if (itemDetail) {
      const status = itemDetail.status;
      return status == "received";

    } else return false;
  };
  
  const [viewOnly, setViewOnly] = useState(false);
  useEffect(() => {
    if (itemDetail && itemDetail.status) {
      const isViewOnly = itemDetail.status.toLowerCase() == "completed"
        || itemDetail.status.toLowerCase() == "partially_completed" // TODO update DB
        || itemDetail.status.toLowerCase() == "rejected"
        || (itemDetail.status.toLowerCase() == "escalated" && session?.id != itemDetail.handlerId)
      setViewOnly(isViewOnly)
    }
    console.log("Modal ItemDetail updated:", itemDetail);
  }, [itemDetail]);

  useEffect(() => {
    const qcRes = itemDetail?.qcResult;
    // if (!qcRes || qcRes?.length <= 0) {
    //   itemDetail.qcResult = dummyQCData;
    // }
    formProps.reset({
      ...defaultNewValue
    })

    setQcItems(dummyQCData);
    setOpenPutaway(isPutaway);
    
  }, [open])

  const [openPutaway, setOpenPutaway] = useState(false);
  const onOpenPutaway = useCallback(() => {
    
    setOpenPutaway(true);
  }, []);
  const onClosePutaway = useCallback(() => {
    setOpenPutaway(false);
  }, []);

  // Stock In submission handler
  const onSubmitStockIn = useCallback<SubmitHandler<ModalFormInput>>(
    async (data, event) => {
      console.log("Stock In Submission:", event!.nativeEvent);
      // Extract only stock-in related fields
      const stockInData = {
        //    quantity: data.quantity,
        //    receiptDate: data.receiptDate,
        //    batchNumber: data.batchNumber,
        //    expiryDate: data.expiryDate,
        //    warehouseId: data.warehouseId,
        //    location: data.location,
        //    unitCost: data.unitCost,
        data: data,
        // Add other stock-in specific fields from your form
      };
      console.log("Stock In Data:", stockInData);
      // Handle stock-in submission logic here
      // e.g., call API, update state, etc.
    },
    [],
  );

  // QC submission handler
  const onSubmitErrorQc = useCallback<SubmitErrorHandler<ModalFormInput>>(
    async (data, event) => {
      console.log("Error", data);
    }, []
  );

  // QC submission handler
  const onSubmitQc = useCallback<SubmitHandler<ModalFormInput>>(
    async (data, event) => {
      console.log("QC Submission:", event!.nativeEvent);
      // TODO: Move validation into QC page

      // if (errors.length > 0) {
      //   alert(`未完成品檢: ${errors.map((err) => err[1].message)}`);
      //   return;
      // }

      // Get QC data from the shared form context
      const qcAccept = data.qcDecision == 1;
      // const qcAccept = data.qcAccept;
      const acceptQty = Number(data.acceptQty);
      const qcResults = data.qcResult || dummyQCData; // qcItems;
      // const qcResults = data.qcResult as PurchaseQcResult[]; // qcItems;
      // const qcResults = viewOnly? data.qcResult as PurchaseQcResult[] : qcItems;
      
      // Validate QC data
      const validationErrors : string[] = [];
      

      // Check if failed items have failed quantity
      const failedItemsWithoutQty = qcResults.filter(item => 
        item.qcPassed === false && (!item.failQty || item.failQty <= 0)
      );
      if (failedItemsWithoutQty.length > 0) {
        validationErrors.push(`${t("Failed items must have failed quantity")}`);
        // validationErrors.push(`${t("Failed items must have failed quantity")}: ${failedItemsWithoutQty.map(item => item.code).join(', ')}`);
      }

      // Check if QC accept decision is made
      if (data.qcDecision === undefined) {
      // if (qcAccept === undefined) {
        validationErrors.push(t("QC decision is required"));
      }

      // Check if accept quantity is valid
      if (acceptQty === undefined || acceptQty <= 0) {
        validationErrors.push("Accept quantity must be greater than 0");
      }

      // Check if dates are input
      if (data.productionDate === undefined || data.productionDate == null) {
        alert("請輸入生產日期！");
        return;
      }
      if (data.expiryDate === undefined || data.expiryDate == null) {
        alert("請輸入到期日！");
        return;
      }
      if (!qcResults.every((qc) => qc.qcPassed) && qcAccept  && itemDetail.status != "escalated") {  //TODO: fix it please!
        validationErrors.push("有不合格檢查項目，無法收貨！");
        // submitDialogWithWarning(() => postStockInLineWithQc(qcData), t, {title:"有不合格檢查項目，確認接受收貨？",
        //   confirmButtonText: t("confirm putaway"), html: ""});
        // return;
      }

      // Check if all QC items have results
      const itemsWithoutResult = qcResults.filter(item => item.qcPassed === undefined);
      
      if (itemsWithoutResult.length > 0  && itemDetail.status != "escalated") {  //TODO: fix it please!
        validationErrors.push(`${t("QC items without result")}`);
        // validationErrors.push(`${t("QC items without result")}: ${itemsWithoutResult.map(item => item.code).join(', ')}`);
      }

      if (validationErrors.length > 0) {
        console.error("QC Validation failed:", validationErrors);
        alert(`未完成品檢: ${validationErrors}`); 
        return;
      }

      const qcData = {
        dnNo : data.dnNo? data.dnNo : "DN00000",
        dnDate : data.dnDate? arrayToInputDateString(data.dnDate) : dayjsToInputDateString(dayjs()),
        productionDate : arrayToInputDateString(data.productionDate),
        expiryDate : arrayToInputDateString(data.expiryDate),
        receiptDate : arrayToInputDateString(data.receiptDate),
        
        qcAccept: qcAccept? qcAccept : false,
        acceptQty: acceptQty? acceptQty : 0,
        qcResult: itemDetail.status != "escalated" ? qcResults.map(item => ({
          id: item.id,
          qcItemId: item.id,
          // code: item.code,
          // qcDescription: item.qcDescription,
          qcPassed: item.qcPassed? item.qcPassed : false,
          failQty: (item.failQty && !item.qcPassed) ? item.failQty : 0,
          // failedQty: (typeof item.failedQty === "number" && !item.isPassed) ? item.failedQty : 0,
          remarks: item.remarks || ''
        })) : [],
      };
      // const qcData = data;

      console.log("QC Data for submission:", qcData);
      if (data.qcDecision == 3) { // Escalate
        const escalationLog = {
          type : "qc",
          status : "pending", // TODO: update with supervisor decision
          reason : data.escalationLog?.reason,
          recordDate : dayjsToInputDateString(dayjs()),
          handlerId : Number(session?.id),
        }
        console.log("Escalation Data for submission", escalationLog);
        await postStockInLine({...qcData, escalationLog});
      } else {
        await postStockInLine(qcData);
      }

      if (qcData.qcAccept) {
        // submitDialogWithWarning(onOpenPutaway, t, {title:"Save success, confirm to proceed?",
        //   confirmButtonText: t("confirm putaway"), html: ""});
        onOpenPutaway();
      } else {
        closeHandler({}, "backdropClick");
      }
      return ;

    },
    [onOpenPutaway, qcItems, formProps.formState.errors],
  );

  const postStockInLine = useCallback(async (args: ModalFormInput) => {
    const submitData = {
      ...itemDetail, ...args
    } as StockInLineEntry & ModalFormInput;
    console.log("Submitting", submitData);

    const res = await updateStockInLine(submitData);
    return res;
  },[itemDetail])

  // Email supplier handler
  const onSubmitEmailSupplier = useCallback<SubmitHandler<ModalFormInput>>(
    async (data, event) => {
      console.log("Email Supplier Submission:", event!.nativeEvent);
      // Extract only email supplier related fields
      const emailData = {
        //    supplierEmail: data.supplierEmail,
        //    issueDescription: data.issueDescription,
        //    qcComments: data.qcComments,
        //    defectNotes: data.defectNotes,
        //    attachments: data.attachments,
        //    escalationReason: data.escalationReason,
        data: data,

        // Add other email-specific fields
      };
      console.log("Email Supplier Data:", emailData);
      // Handle email supplier logic here
      // e.g., send email to supplier, log escalation, etc.
    },
    [],
  );

  // Put away model
  const [pafRowModesModel, setPafRowModesModel] = useState<GridRowModesModel>({})
  const pafSubmitDisable = useMemo(() => {
    // console.log("%c mode: ", "background:#90EE90; color:red", Object.entries(pafRowModesModel))
    // console.log("%c mode: ", "background:pink; color:#87CEEB", Object.entries(pafRowModesModel))
    return Object.entries(pafRowModesModel).length > 0 || Object.entries(pafRowModesModel).some(([key, value], index) => value.mode === GridRowModes.Edit)
  }, [pafRowModesModel])
  // Putaway submission handler
  const onSubmitPutaway = useCallback<SubmitHandler<ModalFormInput>>(
    async (data, event) => {
      // console.log("Putaway Submission:", event!.nativeEvent);
      // console.log(data.putAwayLines)
      // console.log(data.putAwayLines?.filter((line) => line._isNew !== false))
      // Extract only putaway related fields
      const putawayData = {
        //    putawayLine: data.putawayLine,
        //    putawayLocation: data.putawayLocation,
        //    binLocation: data.binLocation,
        //    putawayQuantity: data.putawayQuantity,
        //    putawayNotes: data.putawayNotes,
        acceptQty: Number(data.acceptQty?? (itemDetail.demandQty?? (itemDetail.acceptedQty))),  //TODO improve
        warehouseId: data.warehouseId,
        status: data.status, //TODO Fix it!
        // ...data,
        
        dnDate : data.dnDate? arrayToInputDateString(data.dnDate) : dayjsToInputDateString(dayjs()),
        productionDate : arrayToInputDateString(data.productionDate),
        expiryDate : arrayToInputDateString(data.expiryDate),
        receiptDate : arrayToInputDateString(data.receiptDate),

        // for putaway data
        inventoryLotLines: data.putAwayLines?.filter((line) => line._isNew !== false)

        // Add other putaway specific fields
      } as ModalFormInput;
      console.log("Putaway Data:", putawayData);

      console.log("DEBUG",data.putAwayLines);
      if (data.putAwayLines!!.filter((line) => line._isNew !== false).length <= 0) { 
        alert("請新增上架資料！");
        return;
       }
       console.log(typeof data.putAwayLines!![0].qty + " = 'number'");
       console.log(typeof data.putAwayLines!![0].qty !== "number");
      if (data.putAwayLines!!.filter((line) => /[^0-9]/.test(String(line.qty))).length > 0) {  //TODO Improve
        alert("上架數量不正確！");
        return;
      }
      if (data.putAwayLines!!.reduce((acc, cur) => acc + Number(cur.qty), 0) > putawayData.acceptQty!!) {
        alert(`上架數量不能大於 ${putawayData.acceptQty}！`);
        return;
      }
      // Handle putaway submission logic here
      const res = await postStockInLine(putawayData);
      console.log("result ", res);
      
      // Close modal after successful putaway
      closeHandler({}, "backdropClick");
    },
    [closeHandler],
  );
  // Print handler
  const [isPrinting, setIsPrinting] = useState(false)
  const handlePrint = useCallback(async () => {
    // console.log("Print putaway documents");
    console.log("%c data", "background: white; color: red", formProps.watch("putAwayLines"));
    // Handle print logic here
    // window.print();
    // const postData = { stockInLineIds: [itemDetail.id]};
    // const response = await fetchPoQrcode(postData);
    // if (response) {
    //   downloadFile(new Uint8Array(response.blobValue), response.filename)
    // }
    try {
      setIsPrinting(() => true)
      const data: PrintQrCodeForSilRequest = {
        stockInLineId: itemDetail.id,
        printerId: selectedPrinter.id,
        printQty: formProps.watch("putAwayLines")?.reduce((acc, cur) => acc + cur.printQty, 0)
      }
      const response = await printQrCodeForSil(data);
      if (response) {
        console.log(response)
      }
    } finally {
      setIsPrinting(() => false)
    }
  }, [itemDetail.id]);
  
  const acceptQty = formProps.watch("acceptedQty")

  const checkQcIsPassed = useCallback((qcItems: PurchaseQcResult[]) => {
    const isPassed = qcItems.every((qc) => qc.qcPassed);
    console.log(isPassed)
    if (isPassed) {
        formProps.setValue("passingQty", acceptQty)
    } else {
        formProps.setValue("passingQty", 0)
    }
    return isPassed
  }, [acceptQty, formProps])

  useEffect(() => {
    // maybe check if submitted before
    console.log("Modal QC Items updated:", qcItems);
    // checkQcIsPassed(qcItems)
  }, [qcItems, checkQcIsPassed])
  
  return (
    <>
      <FormProvider {...formProps}>
        <Modal open={open} onClose={closeHandler}>
          <Box
            sx={{
              ...style,
              padding: 2,
              maxHeight: "90vh",
              overflowY: "auto",
              marginLeft: 3,
              marginRight: 3,
            }}
          >
            {openPutaway ? (
              <Box
                component="form"
                onSubmit={formProps.handleSubmit(onSubmitPutaway)}
              >
                <PutAwayForm
                  printerCombo={printerCombo}
                  itemDetail={itemDetail}
                  warehouse={warehouse!}
                  disabled={viewOnly}
                  setRowModesModel={setPafRowModesModel}
                />
                <Stack direction="row" justifyContent="flex-end" gap={1}>
                  <Autocomplete
                    disableClearable
                    options={printerCombo}
                    defaultValue={selectedPrinter}
                    onChange={(event, value) => {
                      setSelectedPrinter(value)
                    }}
                    renderInput={(params) => (
                      <TextField
                        {...params}
                        variant="outlined"
                        label={t("Printer")}
                        sx={{ width: 300}}
                      />
                    )}
                  />
                  <Button
                    id="printButton"
                    type="button"
                    variant="contained"
                    color="primary"
                    sx={{ mt: 1 }}
                    onClick={handlePrint}
                    disabled={isPrinting || printerCombo.length <= 0}
                  >
                    {isPrinting ? t("Printing") : t("print")}
                  </Button>
                  <Button
                    id="putawaySubmit"
                    type="submit"
                    variant="contained"
                    color="primary"
                    sx={{ mt: 1 }}
                    onClick={formProps.handleSubmit(onSubmitPutaway)}
                    disabled={pafSubmitDisable}
                  >
                    {t("confirm putaway")}
                  </Button>
                </Stack>
              </Box>
            ) : (
              <>
                <Grid
                  container
                  justifyContent="flex-start"
                  alignItems="flex-start"
                >
                  <Grid item xs={12}>
                    <Typography variant="h6" display="block" marginBlockEnd={1}>
                      {t("qc processing")}
                    </Typography>
                  </Grid>
                  <Grid item xs={12}>
                    <StockInFormVer2 itemDetail={itemDetail} disabled={viewOnly} />
                  </Grid>
                </Grid>
                {/* <Stack direction="row" justifyContent="flex-end" gap={1}>
                  <Button
                    id="stockInSubmit"
                    type="button"
                    variant="contained"
                    color="primary"
                    onClick={formProps.handleSubmit(onSubmitStockIn)}
                  >
                    {t("submitStockIn")}
                  </Button>
                </Stack> */}
                <Grid
                  container
                  justifyContent="flex-start"
                  alignItems="flex-start"
                >
                  <QcComponent
                    qc={qc!}
                    itemDetail={itemDetail}
                    disabled={viewOnly}
                    // qcItems={qcItems}
                    // setQcItems={setQcItems}
                  />
                </Grid>
                <Stack direction="row" justifyContent="flex-end" gap={1}>
                  {!viewOnly && (<Button
                    id="qcSubmit"
                    type="button"
                    variant="contained"
                    color="primary"
                    sx={{ mt: 1 }}
                    onClick={formProps.handleSubmit(onSubmitQc, onSubmitErrorQc)}
                  >
                    {t("confirm qc result")}
                  </Button>)}
                </Stack>
              </>
            )}
          </Box>
        </Modal>
      </FormProvider>
    </>
  );
};
export default PoQcStockInModalVer2;
