import {createContext, useContext, useEffect, useState} from "react";
import {randomUUID} from "expo-crypto";
import {RootState, useAppDispatch} from "../redux/store";
import {openScanModalFormContext, resolveUuid} from "../features/scanModal/scanModalSlice";
import {useSelector} from "react-redux";

type ScanCallback = (data: string) => void;
type ScanProps = {
    callback: ScanCallback;
    data?: any;
}
type ScanningContextState = {
    scan: (props: ScanProps) => void;
}
const ScanningContext = createContext<ScanningContextState | undefined>(undefined);

export const useScanningContext = () => {
    const context = useContext(ScanningContext);
    if (!context) {
        throw new Error(
            "useScanningContext must be used within a ScanningContextProvider"
        );
    }
    return context;
};

type ScanningContextProviderProps = {
    children: React.ReactNode;
}

type CallbacksState = {
    uuid: string;
    callback: (data: string) => void;
}
type DataState = {
    uuid: string;
    data: any;
}
export const ScanningContextProvider = (props: ScanningContextProviderProps) => {
    const [callbacks, setCallbacks] = useState<CallbacksState[]>([]);
    const [data, setData] = useState<DataState[]>([]);
    const dispatch = useAppDispatch();
    const state = useSelector((state: RootState) => state.scanModal);
    const scan = (props: ScanProps) => {
        const {callback, data} = props
        const uuid = randomUUID();
        setCallbacks([...callbacks, {uuid, callback}]);
        dispatch(openScanModalFormContext({uuid}));
    }

    const handleChange = () => {
        if (!state.scannedData) return;
        const uuid = state.uuid;
        if (!uuid) return;
        const callback = callbacks.find(item => item.uuid === uuid);
        if (!callback) return;
        callback.callback(state.scannedData);
        dispatch(resolveUuid());
        setCallbacks(callbacks.filter(item => item.uuid !== uuid));
    }
    useEffect(() => {
        handleChange();
    }, [state.scannedData]);
    return (
        <ScanningContext.Provider value={{scan}}>
            {props.children}
        </ScanningContext.Provider>
    )
}