import * as React from 'react';
import { useReducer, useState, useEffect } from 'react';
import { prepareDataSource, prepareGridOptions } from './helper';
import ConfigurationDialog from './AdaptableConfigurationDialog';
import FileDroppable from '../../components/FileDroppable';
import { validDataSource } from './Utils';
import { Flex } from '../../components/Flex';
export const initialState = {
    dropped: false,
};
export const reducer = (state, action) => {
    if (action.type === 'DROPPED') {
        return {
            ...state,
            adaptableOptions: action.payload.adaptableOptions,
            gridOptions: action.payload.gridOptions,
            dropped: true,
            error: null,
        };
    }
    if (action.type === 'ERROR') {
        return {
            ...state,
            dropped: false,
            error: action.payload,
        };
    }
    if (action.type === 'CANCEL') {
        return {
            ...state,
            error: null,
            dropped: false,
        };
    }
    return state;
};
/**
 * The wizard in a few modes:
 *
 * 1. Based on data:
 * 1.1 Drag and drop a file
 * 1.2 Fetch data from a url
 *
 * 2. Based on configuration:
 * Provide a schema, on how the data looks like.
 */
export const Wizard = (props) => {
    const [state, dispatch] = useReducer(reducer, {
        ...initialState,
        adaptableOptions: props.adaptableOptions,
        gridOptions: props.gridOptions,
    });
    const [droppableKey, setDroppableKey] = useState(Date.now());
    const [isDataLoading, setIsDataLoading] = useState(false);
    const handleDataSource = (array, file) => {
        const dataSourceInfo = (props.prepareData || prepareDataSource)(array, file);
        try {
            validDataSource(dataSourceInfo);
        }
        catch (err) {
            return dispatch({
                type: 'ERROR',
                payload: `Invalid adaptable configuration - ${err}`,
            });
        }
        const gridOptions = prepareGridOptions(dataSourceInfo, props.gridOptions);
        const adaptableOptions = { ...props.adaptableOptions };
        adaptableOptions.adaptableId = adaptableOptions.adaptableId || (file ? file.name : '');
        if (dataSourceInfo.primaryKey) {
            adaptableOptions.primaryKey = dataSourceInfo.primaryKey;
        }
        const shouldShowWizard = props.fetchData ? Boolean(props.showFetchDataWizard) : true;
        if (shouldShowWizard) {
            dispatch({
                type: 'DROPPED',
                payload: { adaptableOptions, gridOptions },
            });
        }
        else {
            props.onInit(adaptableOptions, gridOptions);
        }
    };
    let wizard;
    if (props.skipToWizard || state.dropped) {
        wizard = (React.createElement(ConfigurationDialog, { startSections: props.startSections, adaptableConfig: {
                adaptableOptions: state.adaptableOptions,
                gridOptions: state.gridOptions,
            }, onCancel: () => {
                // change the file droppable component key
                // so it's remounted and it's in the initial state
                setDroppableKey(Date.now());
                dispatch({
                    type: 'CANCEL',
                });
            }, onFinish: (adaptableConfig) => {
                props.onInit(adaptableConfig.adaptableOptions, adaptableConfig.gridOptions);
            } }));
    }
    useEffect(() => {
        if (props.fetchData) {
            setIsDataLoading(true);
            props.fetchData().then((data) => {
                handleDataSource(data);
                setIsDataLoading(false);
            });
        }
    }, []);
    const ddEnabled = props.ddEnabled ?? !props.fetchData;
    return (React.createElement(React.Fragment, null,
        ddEnabled && (React.createElement(FileDroppable, { key: droppableKey, className: 'ab-NocodeWizard', toJSON: props.fileContentsToJSON, readFile: props.readFile, fileAccept: props.fileAccept, helpText: props.helpText, message: state.error, defaultText: props.defaultActionMessage, dragOverText: props.dragOverActionMessage, loadingText: props.loadingMessage, onDropSuccess: handleDataSource })),
        isDataLoading && (React.createElement(Flex, { className: 'ab-NocodeWizard', alignItems: "center", justifyContent: "center", flexDirection: "column" }, props.loadingMessage || 'Loading ...')),
        wizard));
};
