import { __ } from '@wordpress/i18n';
import apiFetch from '@wordpress/api-fetch';
import { dispatch, select } from '@wordpress/data';

const editorDispatcher = dispatch('core/editor');
const blockEditorDispatcher = dispatch('core/block-editor');
const noticesDispatcher = dispatch('core/notices');
let selectedBlock;

const getSelectedBlock = () => select('core/block-editor').getSelectedBlock();

const hideNoticeWithTimeout = (id='', timeout=3000) => {
    setTimeout(() => {
        noticesDispatcher.removeNotice(id);
    }, timeout);
};

const processCommandRemote = (apiPath, data=false, callback=false) => {
    if ('' == apiPath) {
        return;
    }

    let save = false;

    data = data || {};
    callback = callback || function() {};

    editorDispatcher.lockPostSaving('process-remote');
    editorDispatcher.lockPostAutosaving('process-remote');

    dispatch('SEOAIBlocks').setBlockLoading(getSelectedBlock().clientId, true);

    return apiFetch({
        headers: {
            'X-WP-Nonce': wpApiSettings.nonce
        },
        path: '/seoaic/v1/' + apiPath,
        method: 'POST',
        data: data,
    })
    .then((res) => {
        if (res.success) {
            callback(res);
            save = true;

        } else {
            const message = __('Request failed. Details: ', 'seoaic') + res.message;

            noticesDispatcher.createErrorNotice(message, {
                id: 'remote-not-success',
                isDismissible: false,
                type: 'snackbar',
            });
        }
    })
    .catch((error) => {
        console.log('Error', error);
        noticesDispatcher.createErrorNotice(error.message, {
            id: 'remote-not-success',
            isDismissible: false,
            type: 'snackbar',
        });
    })
    .finally(() => {
        if (save) {
            editorDispatcher.unlockPostSaving('process-remote');
            editorDispatcher.unlockPostAutosaving('process-remote');

            editorDispatcher.autosave();

            noticesDispatcher.createSuccessNotice(__('Autosaved!', 'seoaic'), {
                id: 'seoaic-autosaved',
                isDismissible: false,
                type: 'snackbar',
            });

            hideNoticeWithTimeout('seoaic-autosaved');
        }

        dispatch('SEOAIBlocks').setBlockLoading(getSelectedBlock().clientId, false);
    });
};

const commands = {
    rephrase: {
        title: __('Rephrase'),
        apiPath: 'commands/rephrase',
        successMessage: __('Rephrased text generated!', 'seoaic')
    },
    shorten: {
        title: __('Shorten'),
        apiPath: 'commands/shorten',
        successMessage: __('Shortened text generated!', 'seoaic')
    },
    simplify: {
        title: __('Simplify'),
        apiPath: 'commands/simplify',
        successMessage: __('Simplified text generated!', 'seoaic')
    },
    paraphrase: {
        title: __('Paraphrase'),
        apiPath: 'commands/paraphrase',
        successMessage: __('Paraphrased text generated!', 'seoaic')
    },
    changeTone: {
        title: __('Change tone'),
        apiPath: 'commands/change-tone',
        successMessage: __('Text with changed tone generated!', 'seoaic')
    },
    makeItMore: {
        title: __('Change style'),
        apiPath: 'commands/make-it-more',
        successMessage: __('Text with changed style generated!', 'seoaic')
    },
    writeMore: {
        title: __('Write more'),
        apiPath: 'commands/write-more',
        successMessage: __('Added more!', 'seoaic')
    },
    translate: {
        title: __('Translate'),
        apiPath: 'commands/translate',
        successMessage: __('Content translated!', 'seoaic')
    },
    makeSummary: {
        title: __('Make summary'),
        apiPath: 'commands/make-summary',
        successMessage: __('Summary created!', 'seoaic')
    },
    improveContent: {
        title: __('Improve content'),
        apiPath: 'commands/improve-content',
        successMessage: __('Improved content generated!', 'seoaic')
    },
    rewrite: {
        title: __('Rewrite'),
        apiPath: 'commands/rewrite',
        successMessage: __('Rewritten content generated', 'seoaic')
    },
    fixGrammar: {
        title: __('Fix grammar'),
        apiPath: 'commands/fix-grammar',
        successMessage: __('Grammar fixed!', 'seoaic')
    }
};

const execCommand = (command, params = {}, callback = false) => {
    selectedBlock = getSelectedBlock();
    callback = callback || function() {};

    // if (!allowedBlocks.includes(selectedBlock.name)) {
    //     noticesDispatcher.createErrorNotice(__('Block type not allowed!', 'seoaic'), {
    //         id: 'error',
    //         isDismissible: false,
    //         type: 'snackbar',
    //     });

    //     return;
    // }

    if (
        '' == command
        || false === command in commands
    ) {
        noticesDispatcher.createErrorNotice(__('Command not found!', 'seoaic'), {
            id: 'error',
            isDismissible: false,
            type: 'snackbar',
        });

        return;
    }

    const post = select('core/editor').getCurrentPost();

    if ('apiPath' in commands[command]) {
        const basicData = {
            title: post.title,
            content: selectedBlock.attributes.content
        };

        // add params to existing data
        const data = Object.assign(basicData, params);

        return processCommandRemote(
            commands[command].apiPath,
            data,
            (res) => {
                // blockEditorDispatcher.updateBlock(selectedBlock.clientId, {
                //     attributes: {
                //         content: res.data.content
                //     }
                // });

                callback(res.data.content);

                let msg = __('Done!', 'seoaic');
                if ('successMessage' in commands[command]) {
                    msg = commands[command].successMessage;
                }

                noticesDispatcher.createSuccessNotice(msg, {
                    id: 'success',
                    isDismissible: false,
                    type: 'snackbar',
                });
            }
        );
    }
};

export { execCommand, commands };
