"use client";

import {
  Box, Card, CardContent, Checkbox, Collapse, FormControl,
  FormControlLabel, Grid, Radio, RadioGroup, Stack, Tab,
  Tabs, TabsProps, TextField, Tooltip, Typography,
} from "@mui/material";
import { useFormContext, Controller, FieldPath } from "react-hook-form";
import { useTranslation } from "react-i18next";
import StyledDataGrid from "../StyledDataGrid";
import { Dispatch, SetStateAction, useCallback, useEffect, useMemo, useState } from "react";
import {
  GridColDef,
  GridRowIdGetter,
  GridRowModel,
  useGridApiContext,
  GridRenderCellParams,
  GridRenderEditCellParams,
  useGridApiRef,
  GridRowSelectionModel,
} from "@mui/x-data-grid";
import InputDataGrid from "../InputDataGrid";
import { TableRow } from "../InputDataGrid/InputDataGrid";
import TwoLineCell from "../PoDetail/TwoLineCell";
import QcSelect from "../PoDetail/QcSelect";
import { GridEditInputCell } from "@mui/x-data-grid";
import { ModalFormInput, StockInLine } from "@/app/api/stockIn";
import { fetchQcCategory, fetchQcResult } from "@/app/api/qc/actions";
import { QcCategory, QcData, QcInput, QcFormInput, QcResult } from "@/app/api/qc";
import axios from "@/app/(main)/axios/axiosInstance";
import { NEXT_PUBLIC_API_URL } from "@/config/api";
import axiosInstance from "@/app/(main)/axios/axiosInstance";
import EscalationComponent from "../PoDetail/EscalationComponent";
import QcDataGrid from "../PoDetail/QCDatagrid";
import { dummyEscalationHistory,
  dummyQcData_A1, dummyQcData_E1, dummyQcData_E2,
  dummyQcHeader_A1, dummyQcHeader_E1, dummyQcHeader_E2 } from "./dummyQcTemplate";
import { escape, isNull, min, template } from "lodash";
import { PanoramaSharp } from "@mui/icons-material";
import EscalationLogTable from "../DashboardPage/escalation/EscalationLogTable";
import { EscalationResult } from "@/app/api/escalation";
import { EscalationCombo } from "@/app/api/user";
import { fetchEscalationLogsByStockInLines } from "@/app/api/escalation/actions";
import CollapsibleCard from "../CollapsibleCard/CollapsibleCard";
import LoadingComponent from "../General/LoadingComponent";
import QcForm from "./QcForm";

interface Props {
  itemDetail: QcInput;
  // itemDetail: StockInLine & { qcResult?: PurchaseQcResult[] } & { escResult?: EscalationResult[] };
  // qc: QcItemWithChecks[];
  disabled: boolean;
  // qcItems: QcData[]
  // setQcItems: Dispatch<SetStateAction<QcData[]>>
}

type EntryError =
  | {
      [field in keyof QcData]?: string;
    }
  | undefined;

type QcRow = TableRow<Partial<QcResult>, EntryError>;
// fetchQcItemCheck
const QcComponent: React.FC<Props> = ({ itemDetail, disabled = false }) => {
  const { t } = useTranslation("purchaseOrder");
  const apiRef = useGridApiRef();
  const {
    register,
    formState: { errors, defaultValues, touchedFields },
    watch,
    control,
    setValue,
    getValues,
    reset,
    resetField,
    setError,
    clearErrors,
  } = useFormContext<QcFormInput>();
  
  const [tabIndex, setTabIndex] = useState(0);
  const [rowSelectionModel, setRowSelectionModel] = useState<GridRowSelectionModel>();
  const [escalationHistory, setEscalationHistory] = useState(dummyEscalationHistory);
  const qcAccept = watch("qcAccept");
  const qcDecision = watch("qcDecision"); //WIP
  // const qcResult = useMemo(() => [...watch("qcResult")], [watch("qcResult")]);
  
  const [qcCategory, setQcCategory] = useState<QcCategory>();

  const qcRecord = useMemo(() => { // Need testing
    const value = watch('qcResult'); //console.log("%c QC update!", "color:green", value);
    return Array.isArray(value) ? [...value] : [];
  }, [watch('qcResult')]);
  const [qcHistory, setQcHistory] = useState<QcResult[]>([]);
  const [qcResult, setQcResult] = useState<QcResult[]>([]);
  const [escResult, setEscResult] = useState<EscalationResult[]>([]);

  // const [qcAccept, setQcAccept] = useState(true);
  // const [qcItems, setQcItems] = useState(dummyQCData)

  const qcDisabled = (row : QcResult) => {
    return disabled || isExist(row.escalationLogId);
  };

  const isExist = (data : string | number | undefined) => {
    return (data !== null && data !== undefined);
  }

  const handleTabChange = useCallback<NonNullable<TabsProps["onChange"]>>(
    (_e, newValue) => {
      setTabIndex(newValue);
    },
    [],
  );

  const qcType = useMemo(() => {
    if (itemDetail) {
      const d = itemDetail;
      if (isExist(d.jobOrderId)) {
        return "EPQC";
      }
    }
    return "IQC"; // Default
  }, [itemDetail]);

  const detailMode = useMemo(() => {
    const isDetailMode = itemDetail.status == "escalated" || isExist(itemDetail.jobOrderId);
    return isDetailMode;
  }, [itemDetail]);

    // W I P //
  const validateFieldFail = (field : FieldPath<QcFormInput>, condition: boolean, message: string) : boolean => {
    // console.log("Checking if " + message)
    if (condition) { setError(field, { message: message}); return false; }
    else { clearErrors(field); return true; }
  }

  //// validate form
  const accQty = watch("acceptQty");
  const validateForm = useCallback(() => {
    if (qcDecision == 1) {
      if (isNaN(accQty) || accQty === undefined || accQty === null || typeof(accQty) != "number") {
        setError("acceptQty", { message: t("value must be a number") });
      } else
      if (!Number.isInteger(accQty)) {
        setError("acceptQty", { message: t("value must be integer") });
      }
      if (accQty > itemDetail.acceptedQty) {
        setError("acceptQty", { message: `${t("acceptQty must not greater than")} ${
            itemDetail.acceptedQty}` });
      } else
      if (accQty < 1) {
        setError("acceptQty", { message: t("minimal value is 1") });
      } else
      console.log("%c Validated accQty:", "color:yellow", accQty);
    }

  },[setError, qcDecision, accQty, itemDetail])
  useEffect(() => {   // W I P // -----
    if (qcDecision == 1) {
      if (validateFieldFail("acceptQty", accQty > itemDetail.acceptedQty, `${t("acceptQty must not greater than")} ${
            itemDetail.acceptedQty}`)) return;

      if (validateFieldFail("acceptQty", accQty < 1, t("minimal value is 1"))) return;
      if (validateFieldFail("acceptQty", isNaN(accQty), t("value must be a number"))) return;
    }

    const qcResultItems = qcResult; //console.log("Validating:", qcResultItems);
    // Check if failed items have failed quantity
    const failedItemsWithoutQty = qcResultItems.filter(item => 
      item.qcPassed === false && (!item.failQty || item.failQty <= 0)
    );
    if (validateFieldFail("qcResult", failedItemsWithoutQty.length > 0, `${t("Failed items must have failed quantity")}`)) return;

    // Check if all QC items have results
    const itemsWithoutResult = qcResultItems.filter(item => item.qcPassed === undefined);
    if (validateFieldFail("qcDecision", (itemsWithoutResult.length > 0  && itemDetail.status != "escalated"),
      `${t("QC items without result")}`)) return;

    if (validateFieldFail("qcDecision", (!qcResultItems.every((qc) => qc.qcPassed) && qcDecision == 1  && itemDetail.status != "escalated"),
      "有不合格檢查項目，無法收貨！")) return; // TODO: Fix it please
      // submitDialogWithWarning(() => postStockInLineWithQc(qcData), t, {title:"有不合格檢查項目，確認接受收貨？",
      //   confirmButtonText: t("confirm putaway"), html: ""});
      // return;

    // console.log("Validated without errors");
  }, [accQty, qcDecision, watch("qcResult")]);

  useEffect(() => {
    clearErrors();
    validateForm();
  }, [clearErrors, validateForm]);

  /// validate datagrid
  const validation = useCallback(
    (newRow: GridRowModel<QcRow>): EntryError => {
      const error: EntryError = {};
      // const { qcItemId, failQty } = newRow;
      return Object.keys(error).length > 0 ? error : undefined;
    },
    [],
  );


  // Set initial value for acceptQty
  useEffect(() => {
    if (itemDetail?.demandQty > 0) { //!== undefined) {
      setValue("acceptQty", itemDetail.demandQty);  // TODO: THIS NEED TO UPDATE TO NOT USE DEMAND QTY
    } else {
      setValue("acceptQty", itemDetail?.acceptedQty);
    }
  }, [itemDetail?.demandQty, itemDetail?.acceptedQty, setValue]);

  // Fetch Qc Data
  useEffect(() => {
    // console.log("%c QC ItemDetail updated:", "color: gold", itemDetail);
    if (itemDetail) {
      const d = itemDetail;
      fetchNewQcData(d);
      if (d.status == "pending") {
        // 
      } else {
        fetchQcResultData(d);
      }
    }
  }, [itemDetail]);

  const fetchNewQcData = useCallback(
    async (input: QcInput) => {
      try {
        const res = await fetchQcCategory(input.itemId, qcType);
        if (res.qcItems.length > 0) {
          console.log("%c Fetched Qc Template: ", "color:orange", res);

          setQcCategory(res);
          // setQcResult(res.qcItems);
          // setValue("qcResult", res.qcItems);
        } else throw("Result is undefined");
      } catch (e) {
        console.log("%c Error when fetching Qc Template: ", "color:red", e);
        alert(t("Missing QC Template, please contact administrator"));
        // closeHandler({}, "backdropClick");
      }
    },[fetchQcCategory, setValue]
  );

  const fetchQcResultData = useCallback(
    async (input: QcInput) => {
      try {
        const res = await fetchQcResult(input.id);  // StockInLineId for now
        if (res.length > 0) {
          console.log("%c Fetched Qc Result: ", "color:orange", res);
          setValue("qcResult", res);

          fetchEscalationLogData(input.id);
        // } else {setStockInLineInfo((prev) => ({...prev, qcResult: []} as StockInLine));}
        } else throw("Result is undefined");
      } catch (e) {
        console.log("%c Error when fetching Qc Result: ", "color:red", e);
        // alert("Something went wrong, please retry");
        // closeHandler({}, "backdropClick");
      }
    },[fetchQcResult, setValue]
  );

  const fetchEscalationLogData = useCallback(
    async (stockInLineId: number) => {
      try {
        const res = await fetchEscalationLogsByStockInLines([stockInLineId]);
        if (res.length > 0) {
          console.log("%c Fetched Escalation Log: ", "color:orange", res[0]);
          setEscResult(res);
          // formProps.setValue("escalationLog", res[0]);

        }// else throw("Result is undefined");
      } catch (e) {
        console.log("%c Error when fetching EscalationLog: ", "color:red", e);
        // alert("Something went wrong, please retry");
        // closeHandler({}, "backdropClick");
      }
    },[fetchEscalationLogsByStockInLines]
  );

  // Set QC Data
  useEffect(() => {
    if (itemDetail) {
      const d = itemDetail;
      if (qcRecord.length < 1) {  // No QC Data
        if (d.status == "pending") {  // New QC
          if (qcCategory) {
            if (qcCategory.qcItems.length > 0) {
              const filledQcItems = fillQcResult(qcCategory.qcItems);
              setValue("qcResult", filledQcItems);
              console.log("%c New QC Record applied:", "color:green", filledQcItems);
            }
          }
        } else {
          console.log("%c No QC Record loaded:", "color:green");
          //
        }
      } else {  // QC Result fetched
        if (qcRecord.some(qc => qc.order !== undefined)) {  // If QC Result is filled with order
          if (d.status == "escalated") { // Copy the previous QC data for editing

            // If no editable Qc Data
            if (!qcRecord.some((qc) => !isExist(qc.escalationLogId))) {
              const mutableQcData = qcRecord.map(qc => ({ ...qc, escalationLogId: undefined }));
              const copiedQcData = [...mutableQcData, ...qcRecord];
              setValue("qcResult", copiedQcData);
              console.log("%c QC Record copied:", "color:green", copiedQcData);
              return;
            }
          }

          // Set QC Result
          // const filteredQcResult = qcRecord;
          const filteredQcResult = qcRecord.filter((qc) => !isExist(qc.escalationLogId));
          console.log("%c QC Result loaded:", "color:green", filteredQcResult);
          setQcResult(filteredQcResult);

          // Set QC History
          if (filteredQcResult.length < qcRecord.length) {  // If there are Qc History
            if (qcHistory.length < 1) {
              const filteredQcHistory = qcRecord.filter((qc) => isExist(qc.escalationLogId));
              console.log("%c QC History loaded:", "color:green", filteredQcHistory);
              setQcHistory(filteredQcHistory);
            }
          }
          
        } else {
          if (qcCategory) {
            const filledQcData = fillQcResult(qcRecord, qcCategory?.qcItems);
            console.log("%c QC Result filled:", "color:green", filledQcData);
            setValue("qcResult", filledQcData);
          }
        }
      }
    }
  }, [qcRecord, qcCategory, setValue, itemDetail])

  const fillQcResult = (qcResults: QcResult[], qcItems: QcData[] = []) => {
    let result = [] as QcResult[];
    qcResults.forEach((r, index) => {
      const target = qcItems.find((t) => t.qcItemId === r.qcItemId);
      const n = { ...target, ...r }; //, id: index };
      result.push(n);
    });
    result.sort((a,b) => a.order! - b.order!);
    return result;
  };

  // const [openCollapse, setOpenCollapse] = useState(false)
  const [isCollapsed, setIsCollapsed] = useState<boolean>(true);

  const onFailedOpenCollapse = useCallback((qcItems: QcResult[]) => {
    const isFailed = qcItems.some((qc) => !qc.qcPassed)
    // console.log(isFailed)
    if (isFailed) {
      setIsCollapsed(true)
    } else {
      setIsCollapsed(false)
    }
  }, [])

  // const handleRadioChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
  //   const value = event.target.value === 'true';
  //   setValue("qcAccept", value);
  // }, [setValue]);


  const setDefaultQcDecision = (status : string | undefined) => {
    const param = status?.toLowerCase();
    if (param !== undefined && param !== null) {
      if (param == "received" || param == "completed" || param == "partially_completed") {
        return 1;
      } else if (param == "rejected") {
        return 2;
      } else if (param == "escalated") {
        return 1; // For new flow
        // return 3;
      } else { return undefined; }
    } else {
      return undefined;
    }
  }

  // }, [watch("qcResult")]);
  // useEffect(() => {
  //   // onFailedOpenCollapse(qcItems)
  // }, [qcItems]);

  const getRowId = (row :any) => {
    return qcRecord.findIndex(qc => qc == row);
    // return row.id || `${row.name}-${Math.random().toString(36).substr(2, 9)}`;
  };

  const getRowHeight = (row :any) => {  // Not used?
    console.log("row", row);
    if (!row.model.name) {
      return (row.model.name.length ?? 10) * 1.2 + 30;
    } else { return 60}
  };

  const formattedDesc = (content: string = "") => {
    return (
      <>
        {content.split("\\n").map((line, index) => (
          <span key={index}> {line} <br/></span>
        ))}
      </>
    );
  }

  const QcHeader = useMemo(() => () => {
    if (qcCategory === undefined || qcCategory === null) {
      return (
        <Typography variant="h5" component="h2" sx={{ fontWeight: 'bold', color: '#333' }}>
          N/A
        </Typography>
      );
    } else
    return (
      <>
      <Box sx={{ mb: 2, p: 2, backgroundColor: '#f5f5f5', borderRadius: 1 }}>
        <Typography variant="h5" component="h2" sx={{ fontWeight: 'bold', color: '#333' }}>
            {qcCategory?.name} ({qcCategory?.code})
        </Typography>
        <Typography variant="subtitle1" sx={{ color: '#666' }}>
            <b>品檢類型</b>：{qcType}
        </Typography>
        <Typography variant="subtitle2" sx={{ color: '#666' }}>
            {formattedDesc(qcCategory?.description)}
        </Typography>
      </Box>
      </>
    );
  }, [qcType, qcCategory]);

  return (
    <>
    <Grid container justifyContent="flex-start" alignItems="flex-start">
    {(qcRecord.length > 0) ? (
    // {(qcRecord.length > 0 && qcCategory) ? (
      <Grid
        container
        justifyContent="flex-start"
        alignItems="flex-start"
        spacing={2}
        sx={{ mt: 0.5 }}
      >
        <Grid item xs={12}>
          <Tabs
            value={tabIndex}
            onChange={handleTabChange}
            variant="scrollable"
          >
            <Tab label={t("QC Info")} iconPosition="end" />
            {(escResult && escResult?.length > 0) &&
              (<Tab label={t("Escalation History")} iconPosition="end" />)}
          </Tabs>
        </Grid>
        {tabIndex == 0 && (
          <>
            <Grid item xs={12}>
              <QcHeader/>
              {/* <QcDataGrid<ModalFormInput, QcData, EntryError>
                apiRef={apiRef}
                columns={qcColumns}
                _formKey="qcResult"
                validateRow={validation}
              /> */}
              <QcForm
                rows={qcResult}
                disabled={disabled}
              />
            </Grid>
          </>
        )}
        {tabIndex == 1 && (
          <>
            {/* <Grid item xs={12}>
              <StockInFormVer2
                itemDetail={itemDetail}
                disabled={false}
              />
            </Grid> */}
            {/* <Grid item xs={12}>
              <Typography variant="h6" display="block" marginBlockEnd={1}>
                {t("Escalation Info")}
              </Typography>
            </Grid> */}
            <Grid item xs={12}>
              <EscalationLogTable type="qc" items={escResult || []}/>
              <CollapsibleCard title={t("QC Record")}>
                <QcHeader/>
                <QcForm
                  disabled={disabled}
                  rows={qcHistory}
                />
              </CollapsibleCard>
            </Grid>
          </>
        )}
        <Grid item xs={12}>
          <Card sx={{p:2}}>
            <Typography variant="h6" display="block" marginBlockEnd={1}>
              {t("Qc Decision")}
            </Typography>
            <FormControl>
              <Controller
                name="qcDecision"
                // name="qcAccept"
                control={control}
                defaultValue={setDefaultQcDecision(itemDetail?.status)}
                // defaultValue={true}
                render={({ field }) => (
                  <>
                    {/* <Typography sx={{color:"red"}}>
                      {errors.qcDecision?.message}
                    </Typography> */}
                    <RadioGroup
                      row
                      aria-labelledby="demo-radio-buttons-group-label"
                      {...field}
                      value={field.value}
                      // value={field.value?.toString() || "true"}
                      onChange={(e) => {
                        const value = e.target.value.toString();// === 'true';

                        const input = document.getElementById('accQty') as HTMLInputElement;  //TODO improve
                        // console.log("%c AccQty Error", "color:red", errors.acceptQty);
                        if (input) {   // Selected Reject in new flow with Error
                          if (value == "1") { // Selected Accept
                            input.value = Number(accQty).toString();
                          } else {
                            if (Boolean(errors.acceptQty)) {
                              setValue("acceptQty", 0);
                            }
                            input.value = '0';
                          }
                        }
                          // setValue("acceptQty", itemDetail.acceptedQty ?? 0);
                          // clearErrors("acceptQty");
                        // }
                        field.onChange(value);
                      }}
                    >
                      <FormControlLabel disabled={disabled}
                        value="1" control={<Radio />} label="接受來貨" />
                      
                      {(detailMode || (disabled && accQty != itemDetail.acceptedQty && qcDecision == 1)) && ( //TODO Improve
                        <Box sx={{mr:2}}>
                        <TextField
                          // type="number"
                          id="accQty"
                          label={t("acceptQty")}
                          sx={{ width: '150px' }}
                          // value={Number(accQty)}
                          defaultValue={Number(accQty)}
                          // defaultValue={(qcDecision == 1)? Number(accQty) : 0}
                          // value={(qcDecision == 1)? Number(accQty) : undefined }
                          // value={qcAccept? accQty : 0 }
                          disabled={qcDecision != 1 || disabled}
                          // disabled={!qcAccept || disabled}
                          onBlur={(e) => {
                            const value = e.target.value;
                            const input = document.getElementById('accQty') as HTMLInputElement;
                            input.value = Number(value).toString()
                            setValue(`acceptQty`, Number(value));
                          }}
                          onInput={(e: React.ChangeEvent<HTMLInputElement>) => {
                            const input = e.target.value;

                            const numReg = /^[0-9]+$/
                            let r = '';
                            if (!numReg.test(input)) {
                              const result = input.replace(/\D/g, "");
                              r = (result === '' ? result : Number(result)).toString();
                            } else {
                              r = Number(input).toString()
                            }
                            e.target.value = r;
                          }}
                          inputProps={{ min: 1, max:itemDetail.acceptedQty }}
                          // onChange={(e) => {
                          //   const inputValue = e.target.value;
                          //   if (inputValue === '' || /^[0-9]*$/.test(inputValue)) {
                          //     setValue("acceptQty", Number(inputValue === '' ? null : parseInt(inputValue, 10)));
                          //   }
                          // }}
                          // {...register("acceptQty", {
                          //   required: "acceptQty required!",
                          // })}
                          error={Boolean(errors.acceptQty)}
                          helperText={errors.acceptQty?.message}
                          />
                        <TextField
                          type="number"
                          label={t("rejectQty")}
                          sx={{ width: '150px' }}
                          value={
                            (!Boolean(errors.acceptQty) && qcDecision !== undefined) ?
                            (qcDecision == 1 ? itemDetail.acceptedQty - accQty : itemDetail.acceptedQty)
                            : ""
                          }
                          error={Boolean(errors.acceptQty)}
                          disabled={true}
                        />
                      </Box>)}

                      <FormControlLabel disabled={disabled}
                        value="2" control={<Radio />}
                        sx={{"& .Mui-checked": {color: "red"}}}
                        label= {detailMode ? "全部拒絕並退貨" : "不接受並需要退貨"} />
                        
                      {(itemDetail.status == "pending" || disabled) && (<>
                      <FormControlLabel disabled={disabled}
                        value="3" control={<Radio />}
                        sx={{"& .Mui-checked": {color: "blue"}}}
                        label="暫時存放到置物區，並等待品檢結果" />
                        </>)}
                    </RadioGroup>
                  </>
                )}
              />
            </FormControl>
          </Card>
        </Grid>
        {qcDecision == 3 && (
        // {!qcAccept && (
          <Grid item xs={12}>
            <EscalationComponent 
              forSupervisor={false}
              isCollapsed={isCollapsed}
              setIsCollapsed={setIsCollapsed}
              />
          </Grid>)}
      </Grid>
    ) : <LoadingComponent/>}
    </Grid>
    </>
  );
};
export default QcComponent;
