"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.readJSONFile = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const react_1 = require("react");
const join_1 = tslib_1.__importDefault(require("../../components/utils/join"));
const contains_1 = tslib_1.__importDefault(require("../../components/utils/contains"));
const SimpleButton_1 = tslib_1.__importDefault(require("../SimpleButton"));
const icons_1 = require("../icons");
const HelpBlock_1 = tslib_1.__importDefault(require("../HelpBlock"));
const reducer_1 = tslib_1.__importStar(require("./reducer"));
const Flex_1 = require("../Flex");
const initialState = {
    dragOver: false,
    message: null,
};
const preventEventPropagation = (e) => {
    e.preventDefault();
    e.stopPropagation();
};
const readJSONFile = async (file, toJSON) => {
    const reader = new FileReader();
    return new Promise((resolve, reject) => {
        reader.onload = function (e) {
            try {
                const fn = toJSON || JSON.parse;
                const json = fn(e.target.result);
                Promise.resolve(json).then(resolve);
            }
            catch (ex) {
                reject('Invalid JSON');
            }
        };
        reader.onerror = function (e) {
            reject(e);
        };
        reader.readAsText(file);
    });
};
exports.readJSONFile = readJSONFile;
const FileDroppable = (props = {}) => {
    const { onDropSuccess, message, fileAccept = '.json', helpText = 'AdapTable No Code Version', defaultText = 'Click here to select a JSON file to load or drag it here', dragOverText = 'Drop file here to start Adaptable Wizard', icon = React.createElement(icons_1.Icon, { name: "paperclip", size: 40 }), value, ...domProps } = props;
    const [state, dispatch] = (0, react_1.useReducer)(reducer_1.default, initialState);
    const onDragEnter = (e) => {
        dispatch({
            type: reducer_1.ActionTypes.DRAG_OVER,
        });
    };
    const onDragLeave = (event) => {
        preventEventPropagation(event);
        if (domRef.current != event.target &&
            (0, contains_1.default)(domRef.current, event.target)) {
            return;
        }
        dispatch({
            type: reducer_1.ActionTypes.DRAG_OUT,
        });
    };
    const onDrop = async (e) => {
        let files;
        preventEventPropagation(e);
        let nativeEvent = e.nativeEvent;
        if (nativeEvent && nativeEvent.dataTransfer) {
            files = nativeEvent.dataTransfer.files;
        }
        else {
            files = e.target.files;
        }
        onDragLeave(e);
        const file = files[0];
        if (file) {
            let json;
            try {
                json = await (props.readFile || exports.readJSONFile)(file, props.toJSON);
                dispatch({
                    type: reducer_1.ActionTypes.DROP_SUCCES,
                    payload: {
                        message: (React.createElement(Flex_1.Box, null, props.loadingText === undefined ? 'Initializing adaptable...' : props.loadingText)),
                    },
                });
                requestAnimationFrame(() => {
                    requestAnimationFrame(() => {
                        if (onDropSuccess) {
                            onDropSuccess(json, file);
                        }
                    });
                });
            }
            catch (err) {
                dispatch({
                    type: reducer_1.ActionTypes.SET_INVALID_FILE,
                    payload: {
                        message: React.createElement(Flex_1.Box, null, 'The file is not a valid JSON file! Please try again!'),
                    },
                });
            }
        }
    };
    const domRef = (0, react_1.useRef)(null);
    let form = (React.createElement("form", { onSubmit: preventEventPropagation },
        React.createElement(SimpleButton_1.default, { style: { cursor: 'pointer' }, variant: "outlined" },
            React.createElement("div", null, state.dragOver ? dragOverText : defaultText),
            React.createElement("input", { type: "file", onChange: onDrop, accept: fileAccept, value: props?.file?.name, style: {
                    opacity: 0,
                    position: 'absolute',
                    cursor: 'pointer',
                    fontSize: 0,
                    lineHeight: 0,
                    top: 0,
                    left: 0,
                    width: '100%',
                    height: '100%',
                    zIndex: 1,
                } }))));
    const msg = message || state.message;
    return (React.createElement(Flex_1.Flex, { ...domProps, flexDirection: "column", className: (0, join_1.default)(props.className, 'ab-FileDroppable', state.dragOver ? 'ab-FileDroppable--drag-over' : ''), alignItems: "center", justifyContent: "center", onDragEnter: onDragEnter, onDragLeave: onDragLeave, onDrop: onDrop, onDragOver: preventEventPropagation, ref: domRef },
        props.children,
        helpText || icon ? (React.createElement(Flex_1.Flex, { flexDirection: "column" },
            helpText ? (React.createElement(Flex_1.Flex, { flexDirection: "column", alignItems: "center", className: "twa:m-2" },
                React.createElement(HelpBlock_1.default, null,
                    React.createElement("b", null, helpText)))) : null,
            icon ? (React.createElement(Flex_1.Flex, { flexDirection: "column", alignItems: "center", className: "twa:m-2" }, icon)) : null)) : null,
        msg,
        form));
};
exports.default = FileDroppable;
