"use client"
import { JoDetail } from "@/app/api/jo"
import { useRouter } from "next/navigation";
import { useTranslation } from "react-i18next";
import useUploadContext from "../UploadProvider/useUploadContext";
import { FormProvider, SubmitErrorHandler, SubmitHandler, useForm } from "react-hook-form";
import React, { useCallback, useEffect, useLayoutEffect, useMemo, useState } from "react";
import { Button, Stack, Typography } from "@mui/material";
import StartIcon from "@mui/icons-material/Start";
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import { releaseJo } from "@/app/api/jo/actions";
import InfoCard from "./InfoCard";
import PickTable from "./PickTable";
import ActionButtons from "./ActionButtons";
import { useQrCodeScannerContext } from "../QrCodeScannerProvider/QrCodeScannerProvider";
import { fetchStockInLineInfo } from "@/app/api/po/actions";

type Props = {
    id?: number;
    defaultValues: Partial<JoDetail> | undefined;
}

const JoSave: React.FC<Props> = ({
    defaultValues,
    id,
}) => {
    const { t } = useTranslation("jo")
    const router = useRouter();
    const { setIsUploading } = useUploadContext();
    const scanner = useQrCodeScannerContext()
    const [serverError, setServerError] = useState("");

    const finalDefaultValues = useMemo(() => {
        const values = {
            ...defaultValues,
            pickLines: defaultValues?.pickLines?.map(line => ({
                ...line,
                pickedLotNo: Array.isArray(line.pickedLotNo)
                    ? line.pickedLotNo.map(lot => ({
                        ...lot,
                        isScanned: false
                    }))
                    : line.pickedLotNo
            }))
        }

        return values;
    }, [defaultValues])

    const formProps = useForm<JoDetail>({
        defaultValues: finalDefaultValues
    })
    const pickLines = useMemo(() => {
        return formProps.watch("pickLines")
    }, [formProps.watch("pickLines")])

    // --------------------------------------------- Qr Code Scan --------------------------------------------- //
    const needScan = useMemo(() => {
        return pickLines.some((line) => line.status === "pending")
    }, [pickLines.some((line) => line.status === "pending")])

    useLayoutEffect(() => {
        if (needScan && !scanner.isScanning) {
            scanner.startScan();
        } else if (!needScan) {
            scanner.stopScan();
        }
    }, [needScan])

    const checkScannedId = useCallback(async (stockInLineId: number | undefined) => {
        try {
            setIsUploading(true)
            if (stockInLineId) {
                const response = await fetchStockInLineInfo(stockInLineId);
                // const pickLines = formProps.watch("pickLines")
                const pickedLotNoIndex = pickLines.findIndex((line) => line.pickedLotNo?.some((pln) => pln.lotNo === response?.lotNo))
                if (pickedLotNoIndex >= 0) {
                    const updatedPickLines = [...pickLines]
                    const matchedLotNoIndex = updatedPickLines[pickedLotNoIndex].pickedLotNo?.findIndex((line) => line?.lotNo === response?.lotNo && Boolean(line?.isScanned) === false)
                    if (matchedLotNoIndex !== null && matchedLotNoIndex !== undefined && matchedLotNoIndex >= 0) {
                        const updatedPickedLotNo = [...(updatedPickLines[pickedLotNoIndex].pickedLotNo || [])]
                        updatedPickedLotNo[matchedLotNoIndex] = {
                            ...updatedPickedLotNo[matchedLotNoIndex],
                            isScanned: true,
                        }
    
                        updatedPickLines[pickedLotNoIndex] = {
                            ...updatedPickLines[pickedLotNoIndex],
                            pickedLotNo: updatedPickedLotNo,
                        };
    
                        formProps.setValue("pickLines", updatedPickLines, {
                            shouldValidate: true,
                            shouldDirty: true,
                        });
                    }
                }
            }
        } finally {
        scanner.resetScan()
        setIsUploading(false)
        }
    }, [])

    useEffect(() => {
        const result = scanner.result
        console.log(scanner.result)
        if (result?.value) {
            if (!isNaN(Number(result.value))) { checkScannedId(Number(result?.value)); }
        } else if (result?.stockInLineId) {
            checkScannedId(result?.stockInLineId)
        }
    }, [scanner.result])

    // --------------------------------------------- Button Actions --------------------------------------------- //
    const handleBack = useCallback(() => {
        router.replace(`/jo`)
    }, [])

    const handleRelease = useCallback(async () => {
        try {
            setIsUploading(true)
            if (id) {
                const response = await releaseJo({ id: id })
                if (response) {
                    formProps.setValue("status", response.entity.status)
                }
            }

        } catch (e) {
            // backend error
            setServerError(t("An error has occurred. Please try again later."));
            console.log(e);
        } finally {
            setIsUploading(false)
        }
    }, [])

    const handleStart = useCallback(async () => {
        console.log("first")
    }, [])

    // --------------------------------------------- Form Submit --------------------------------------------- //
    const onSubmit = useCallback<SubmitHandler<JoDetail>>(async (data, event) => {
        console.log(data)
    }, [t])

    const onSubmitError = useCallback<SubmitErrorHandler<JoDetail>>((errors) => {
        console.log(errors)
    }, [t])

    return <>
        <FormProvider {...formProps}>
            <Stack
                spacing={2}
                component="form"
                onSubmit={formProps.handleSubmit(onSubmit, onSubmitError)}
            >
                {serverError && (
                    <Typography variant="body2" color="error" alignSelf="flex-end">
                        {serverError}
                    </Typography>
                )}
                <ActionButtons handleRelease={handleRelease} handleStart={handleStart}/>
                <InfoCard />
                <PickTable />
                <Stack direction="row" justifyContent="flex-end" gap={1}>
                    <Button
                        variant="outlined"
                        startIcon={<ArrowBackIcon />}
                        onClick={handleBack}
                    >
                        {t("Back")}
                    </Button>
                </Stack>
            </Stack>
        </FormProvider>
    </>
}

export default JoSave;