import { WorkflowSchema } from '@data-wrangling-components/schema';
import { FileCollection, FileType } from '@data-wrangling-components/utilities';
import { useCallback, useMemo } from 'react';
function useCsvHandler(onUpdateTables) {
    return useCallback(async (fc)=>{
        let tableFiles = fc.list(FileType.table);
        if (!tableFiles.length) {
            return;
        }
        const regex = /metadata\.json$/i;
        const jsonFile = fc.list(FileType.json).find((f)=>regex.test(f.name));
        const metadata = jsonFile ? await jsonFile.toJson() : null;
        const { input =[]  } = metadata || {};
        if (input.length) {
            tableFiles = tableFiles.filter((t)=>input.includes(t.name));
        }
        const tableContainer = [];
        for await (const t of tableFiles){
            const { name  } = t;
            const table = {
                table: await t.toTable(),
                id: name
            };
            tableContainer.push(table);
        }
        onUpdateTables(tableContainer);
    }, [
        onUpdateTables
    ]);
}
function useJsonHandler(onUpdateWorkflow, onErrorHandler) {
    const validator = useMemo(()=>new WorkflowSchema(), []);
    return useCallback(async (fc)=>{
        const regex = /workflow(.*)\.json$/i;
        const files = fc.list(FileType.json);
        if (!files.length) {
            return;
        }
        const json = files.length > 1 ? files.find((f)=>regex.test(f.name)) : files[0];
        if (!json) {
            return;
        }
        const workflow = await json.toJson();
        const isValid = await validator.isValid(workflow);
        if (!isValid) {
            return onErrorHandler?.('Invalid workflow definition');
        }
        if (workflow && onUpdateWorkflow) {
            onUpdateWorkflow(workflow);
        }
    }, [
        onUpdateWorkflow,
        onErrorHandler,
        validator
    ]);
}
export function useHandleCsvUpload(onUpdateTables) {
    const csvHandler = useCsvHandler(onUpdateTables);
    return useHandleFilesUpload([
        '.csv'
    ], csvHandler);
}
export function useHandleJsonUpload(onUpdateWorkflow, onErrorHandler) {
    const jsonHandler = useJsonHandler(onUpdateWorkflow, onErrorHandler);
    return useHandleFilesUpload([
        '.json'
    ], jsonHandler);
}
export function useHandleFileUpload(onUpdateWorkflow, onUpdateTables, onErrorHandler) {
    const jsonHandler = useJsonHandler(onUpdateWorkflow, onErrorHandler);
    const csvHandler = useCsvHandler(onUpdateTables);
    return useCallback(async (fc)=>{
        /* eslint-disable @essex/adjacent-await */ await csvHandler(fc);
        await jsonHandler(fc);
    }, [
        csvHandler,
        jsonHandler
    ]);
}
export function useHandleZipUpload(onUpdateWorkflow, onUpdateTables, onErrorHandler) {
    const jsonHandler = useJsonHandler(onUpdateWorkflow, onErrorHandler);
    const csvHandler = useCsvHandler(onUpdateTables);
    const handler = useCallback(async (fc)=>{
        onUpdateTables([]);
        /* eslint-disable @essex/adjacent-await */ await csvHandler(fc);
        await jsonHandler(fc);
    }, [
        csvHandler,
        jsonHandler,
        onUpdateTables
    ]);
    return useHandleFilesUpload([
        '.zip'
    ], handler);
}
export function useHandleFilesUpload(acceptedFileTypes, handleCollection) {
    return useCallback(()=>{
        let input = document.createElement('input');
        input.type = 'file';
        input.multiple = true;
        input.accept = acceptedFileTypes.toString();
        input.onchange = async (e)=>{
            if (e?.target?.files?.length) {
                const { files  } = e.target;
                const fileCollection = new FileCollection();
                try {
                    for (const file of files){
                        await fileCollection.add(file);
                    }
                    handleCollection?.(fileCollection);
                } catch (e1) {
                    console.error(e1);
                }
            }
        };
        input.click();
        input = null;
    }, [
        acceptedFileTypes,
        handleCollection
    ]);
}
