import { __ } from '@wordpress/i18n';
import metadata from '../block.json';
import { useState, useEffect } from 'react';
import { dispatch, useSelect, useDispatch } from '@wordpress/data';
import { createBlock } from '@wordpress/blocks';
import Fetch from '../../../content-editor/helpers/fetch';
import GenerateImage from './generate-image';
import GeneratedImages from './generated-images';
import ButtonsBar from './buttons-bar';
import GeneratedImageSection from './generated-image-section';

const GenerateImagesBlock = ({
    attributes,
    generatedImages, setGeneratedImages,
    selectedImg, setSelectedImg,
    userPrompt, setUserPrompt,
    generateAltText
}) => {
    const [ isGenerating, setIsGenerating ] = useState(false);
    const [ isUseBusy, setIsUseBusy ] = useState(false);
    const [ showGenerateForm, setShowGenerateForm ] = useState(true);
    const [ width, setWidth ] = useState( 1024 );
    const [ height, setHeight ] = useState( 768 );
    const [ style, setStyle ] = useState('Photorealism');

    const editorDispatcher = dispatch('core/editor');
    const noticesDispatcher = dispatch('core/notices');
    const {
        getBlockIndex,
        getSelectedBlock
    } = useSelect( 'core/block-editor' );
    const imageCredit = useSelect((select) =>
        select('SEOAIBlocks').getImageCredit()
    );
    const { setImageCredit } = useDispatch('SEOAIBlocks');


    useEffect(() => {
        setUserPrompt(attributes.userPrompt || "");

        Fetch.get('options/seoaic_options/seoaic_image_generate_width_default', (res) => {
            const val = parseInt(res.data.value, 10);
            setWidth(!isNaN(val) ? val : 1024);
        });

        Fetch.get('options/seoaic_options/seoaic_image_generate_height_default', (res) => {
            const val = parseInt(res.data.value, 10);
            setHeight(!isNaN(val) ? val : 768);
        });

        Fetch.get('options/seoaic_options/seoaic_image_generate_style', (res) => {
            const val = res.data.value;
            setStyle(val);
        });

    }, []);

    const generateImagesCallback = (resp) => {
        if (
            resp
            && resp.data
            && resp.data.image
        ) {

            Fetch.post('blocks/generate-image/save-image', {
                'image': resp.data.image
            }, (res) => {
                resp.data.image.id = res.data.id;
                resp.data.image.sizes = res.data.sizes;
                setGeneratedImages([...generatedImages, resp.data.image]);

                if (imageCredit.seoaic_images_credit) {
                    setImageCredit({
                        seoaic_images_credit: imageCredit.seoaic_images_credit - 1,
                        seoaic_images_credit_limit: imageCredit.seoaic_images_credit_limit
                    });
                }

                noticesDispatcher.createSuccessNotice(__('Image generated successfully', 'seoaic'), {
                    id: 'seoaic-request-failed',
                    isDismissible: true,
                    type: 'snackbar',
                });
            })
                .catch((err) => {
                    console.error('[seoaic]:', err.message);

                    noticesDispatcher.createErrorNotice(__('Image save failed', 'seoaic'), {
                        id: 'seoaic-request-failed',
                        isDismissible: true,
                        type: 'snackbar',
                    });
                });
        }

        editorDispatcher.unlockPostSaving('process-remote');
        editorDispatcher.unlockPostAutosaving('process-remote');
    };

    const generateClickHandler = () => {
        if ("" == userPrompt) {
            noticesDispatcher.createErrorNotice(__('Prompt is empty', 'seoaic'), {
                id: 'seoaic-prompt-is-empty',
                isDismissible: true,
                type: 'snackbar',
            });

        } else {
            editorDispatcher.lockPostSaving('process-remote');
            editorDispatcher.lockPostAutosaving('process-remote');

            setSelectedImg(false);
            setIsGenerating(true);
            setShowGenerateForm(false);

            Fetch.post('blocks/generate-image/generate-images', {
                'user_prompt': userPrompt,
                'width': width,
                'height': height,
                'style': style
            }, generateImagesCallback)
            .catch((err) => {
                console.error('[seoaic]:', err.message);

                noticesDispatcher.createErrorNotice(__('Request failed', 'seoaic'), {
                    id: 'seoaic-request-failed',
                    isDismissible: true,
                    type: 'snackbar',
                });
            })
            .finally(() => {
                setIsGenerating(false);
                editorDispatcher.unlockPostSaving('process-remote');
                editorDispatcher.unlockPostAutosaving('process-remote');
            });
        }
    };

    const improveClickHandler = () => {
        setShowGenerateForm(true);
        setSelectedImg(false);
    };

    const useClickHandler = () => {
        if ("" == selectedImg.url) {
            noticesDispatcher.createErrorNotice(__('Image is not selected', 'seoaic'), {
                id: 'seoaic-image-not-selected',
                isDismissible: true,
                type: 'snackbar',
            });

        } else {
            setIsUseBusy(true);
            const image = generatedImages.find(item => item.url === selectedImg.url);
            const seoaicBlock = getSelectedBlock();
            const seoaicBlockIndex = getBlockIndex(seoaicBlock.clientId);
            const createdImageBlock = createBlock('core/image', {
                id: image.id,
                url: image.sizes.full,
                sizeSlug: 'full'
            });

            createdImageBlock.attributes.userPrompt = selectedImg.user_prompt;

            const generateAltTextPromise = new Promise((resolve, reject) => {
                generateAltText((resp) => {
                    const generatedAlt = resp?.data?.alt ?? "";
                    createdImageBlock.attributes.alt = generatedAlt;

                    if ("" == generatedAlt) {
                        reject(resp?.message ?? "");
                    }

                    resolve();
                });
            });

            generateAltTextPromise
                .catch((msg) => {
                    noticesDispatcher.createErrorNotice(__('Could not generate the Alt text', 'seoaic') + ': ' + msg, {
                        id: 'seoaic-alt-failed',
                        isDismissible: false,
                        type: 'snackbar',
                    });
                })
                .finally(() => {
                    setIsUseBusy(false);

                    // insert the Image block right after the seoaic one
                    dispatch('core/block-editor').insertBlock(
                        createdImageBlock,
                        seoaicBlockIndex + 1
                    );

                    // remove seoai block
                    dispatch('core/block-editor').removeBlock(seoaicBlock.clientId);
                });
        }
    };

    if (
        "undefined" !== typeof attributes.url
        && "" != attributes.url) {
        return (
            <div className="seoaic-generate-image-block-wrpaper">
                <div className="seoaic-generated-image-block">
                    <GeneratedImageSection
                        attributes={ attributes }
                    />
                </div>
            </div>
        );
    }

    return (
        <div className="seoaic-generate-image-block-wrpaper">
            <div className="seoaic-generate-image-block">
                <div className="seoaic-logo"></div>
                <div className="seoaic-block-title">
                    <span>{metadata.title}</span>
                    {
                        (imageCredit.seoaic_images_credit && imageCredit.seoaic_images_credit_limit) ? (
                            <span className="seoaic-block-title seoaic-block-title--credit">
                                {imageCredit.seoaic_images_credit} {__('out of', 'seoaic')} {imageCredit.seoaic_images_credit_limit} {__('images left', 'seoaic')}
                            </span>
                        ) : (
                            <span className="seoaic-block-title seoaic-block-title--credit">
                                {__('Loading image credit...', 'seoaic')}
                            </span>
                        )
                    }
                </div>
                {
                    (
                        !isGenerating
                        && (
                            0 == generatedImages.length
                            || showGenerateForm
                        )
                    )
                    ? <GenerateImage
                        userPrompt={ userPrompt }
                        setUserPrompt={ setUserPrompt }
                        generateClickHandler={ generateClickHandler }
                        generatedImages={ generatedImages }
                        setShowGenerateForm={ setShowGenerateForm }
                        style={ style }
                        setStyle={ setStyle }
                        width={ width }
                        setWidth={ setWidth }
                        height={ height }
                        setHeight={ setHeight }
                    />
                    : (
                        <>
                            <GeneratedImages
                                isGenerating={ isGenerating }
                                generatedImages={ generatedImages }
                                setSelectedImg={ setSelectedImg }
                            />
                            <ButtonsBar
                                isGenerating={ isGenerating }
                                isUseBusy={ isUseBusy }
                                generateClickHandler={ generateClickHandler }
                                improveClickHandler={ improveClickHandler }
                                useClickHandler={ useClickHandler }
                                selectedImg={ selectedImg }
                            />
                        </>
                    )
                }
            </div>
        </div>
    );
};

export default GenerateImagesBlock;
