import Button from '@mui/material/Button';
import FormControl from '@mui/material/FormControl';
import { Importer, TextImporterFactory } from '@wisemapping/mindplot';
import React from 'react';

import { FormattedMessage, useIntl } from 'react-intl';
import { useMutation } from 'react-query';
import { useSelector } from 'react-redux';
import Client, { ErrorInfo } from '../../../../classes/client';
import { activeInstance } from '../../../../redux/clientSlice';
import Input from '../../../form/input';
import BaseDialog from '../base-dialog';

export type ImportModel = {
    title: string;
    description?: string;
    contentType?: string;
    content?: null | string;
};

export type CreateProps = {
    onClose: () => void;
};

const defaultModel: ImportModel = { title: '' };
const ImportDialog = ({ onClose }: CreateProps): React.ReactElement => {
    const client: Client = useSelector(activeInstance);
    const [model, setModel] = React.useState<ImportModel>(defaultModel);
    const [error, setError] = React.useState<ErrorInfo>();
    const intl = useIntl();

    const mutation = useMutation<number, ErrorInfo, ImportModel>(
        (model: ImportModel) => { 
            return client.importMap(model);
        },
        {
            onSuccess: (mapId: number) => {
                window.location.href = `/c/maps/${mapId}/edit`;
            },
            onError: (error) => {
                setError(error);
            },
        }
    );

    const handleOnClose = (): void => {
        onClose();
        setModel(defaultModel);
        setError(undefined);
    };

    const handleOnSubmit = (event: React.FormEvent<HTMLFormElement>): void => {
        event.preventDefault();
        mutation.mutate(model);
    };

    const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
        event.preventDefault();

        const name = event.target.name;
        const value = event.target.value;
        setModel({ ...model, [name as keyof ImportModel]: value });
    };

    const handleOnFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
        const files = event?.target?.files;
        const reader = new FileReader();

        if (files) {
            const file = files[0];
            // Closure to capture the file information.
            reader.onload = (event) => {
                // Suggest file name ...
                const fileName = file.name;
                if (fileName) {
                    const title = fileName.split('.')[0];
                    if (!model.title || 0 === model.title.length) {
                        model.title = title;
                    }
                }

                const extensionFile = file.name.split('.')[1]
                const extensionAccept = ['wxml', 'mm'];

                if ( extensionAccept.find(ext => ext === extensionFile) ) {
                    new Error('The file extension is invalid');
                }

                model.contentType = 'application/xml'

                const fileContent = event?.target?.result;
                const mapConent: string = typeof fileContent === 'string' ? fileContent : fileContent.toString();

                let importer: Importer
                switch(extensionFile) {
                    case 'wxml':  {
                        importer = TextImporterFactory.create('wxml', mapConent);
                        break;
                    }

                    case 'mm': { 
                        importer = TextImporterFactory.create('mm', mapConent);
                        break;
                    } 
                }

                importer.import(model.title, model.description)
                    .then(res => {
                        model.content = res;
                        setModel({ ...model });
                    })
                    .catch(e => console.log(e));
            };
 
            // Read in the image file as a data URL.
            reader.readAsText(file);
        }
    };

    return (
        <div>
            <BaseDialog
                onClose={handleOnClose}
                onSubmit={handleOnSubmit}
                error={error}
                title={intl.formatMessage({
                    id: 'import.title',
                    defaultMessage: 'Import existing mindmap',
                })}
                description={intl.formatMessage({
                    id: 'import.description',
                    defaultMessage:
                        'You can import WiseMapping maps to your list of maps. Select the file you want to import.',
                })}
                submitButton={intl.formatMessage({ id: 'import.button', defaultMessage: 'Create' })}
            >
                <FormControl fullWidth={true}>
                    <input
                        accept=".wxml,.mm"
                        id="contained-button-file"
                        type="file"
                        required={true}
                        style={{ display: 'none' }}
                        onChange={handleOnFileChange}
                    />

                    <Input
                        name="title"
                        type="text"
                        label={intl.formatMessage({
                            id: 'action.rename-name-placeholder',
                            defaultMessage: 'Name',
                        })}
                        value={model.title}
                        onChange={handleOnChange}
                        error={error}
                        fullWidth={true}
                    />

                    <Input
                        name="description"
                        type="text"
                        label={intl.formatMessage({
                            id: 'action.rename-description-placeholder',
                            defaultMessage: 'Description',
                        })}
                        value={model.description}
                        onChange={handleOnChange}
                        required={false}
                        fullWidth={true}
                    />

                    <label htmlFor="contained-button-file">
                        <Button
                            variant="outlined"
                            color="primary"
                            component="span"
                            style={{ margin: '10px 5px', width: '100%' }}
                        >
                            <FormattedMessage
                                id="maps.choose-file"
                                defaultMessage="Choose a file"
                            />
                        </Button>
                    </label>
                </FormControl>
            </BaseDialog>
        </div>
    );
};

export default ImportDialog;
