const { PluginSidebar } = wp.editor;
const { createHigherOrderComponent } = wp.compose;
const { BlockControls, InspectorControls } = wp.blockEditor;
const { ToolbarGroup, ToolbarButton, PanelBody, ToolbarDropdownMenu, TextareaControl, Button, TextControl } = wp.components;
const { Fragment, createElement, RawHTML, useState, useEffect } = wp.element;
const { registerPlugin } = wp.plugins;
const { useDispatch, useSelect } = wp.data;
const { store } = wp.editPost;
const { addFilter } = wp.hooks;
const { __ } = wp.i18n;
const { Notice } = wp.components;


const TextModes = [
    { text: __('Lengthen', 'swpanel-ai'), mode: 'lengthen', icon: 'menu' },
    { text: __('Shorten', 'swpanel-ai'), mode: 'shorten', icon: 'menu' },
    { text: __('Correct', 'swpanel-ai'), mode: 'correct', icon: 'menu' },
    { text: __('Improve', 'swpanel-ai'), mode: 'improve', icon: 'menu' },
    { text: __('Generate', 'swpanel-ai'), mode: 'generate', icon: 'menu' }
];

const MyCustomIcon = createElement(
    'svg',
    {
        width: 20,
        height: 20,
        viewBox: '0 0 500 500',
        xmlns: 'http://www.w3.org/2000/svg',
        fill: 'currentColor',
    },
    createElement(
        'g',
        null,
        createElement('path', { d: 'M309.1,245.49c-2.31-30.63-27.89-54.76-59.1-54.76c-32.74,0-59.27,26.54-59.27,59.27   c0,32.74,26.54,59.27,59.27,59.27s59.27-26.54,59.27-59.27h-0.17V245.49z'}),
        createElement('path', { d: 'M459.58,0H40.42C18.1,0,0,18.1,0,40.42v419.16C0,481.9,18.1,500,40.42,500h419.16   c22.32,0,40.42-18.1,40.42-40.42V40.42C500,18.1,481.9,0,459.58,0z M250,389.44c-21.26,0-41.41-4.76-59.44-13.27v43.67h-80.16V250   h0.17c0-77.01,62.43-139.44,139.44-139.44c21.13,0,41.16,4.7,59.1,13.11V80.16h80.16v162.92c0.11,2.29,0.17,4.6,0.17,6.91   C389.44,327.01,327.01,389.44,250,389.44z' })
    )
);

const CustomIconWithText = createElement(
    'span',
    { style: { display: 'flex', alignItems: 'center', gap: '5px' } },
    MyCustomIcon,
    createElement('span', null, 'SWPanel AI')
);

const getTextAttribute = (name) => {
    switch (name) {
        case 'core/button': return 'text';
        case 'core/quote': return 'citation';
        default: return 'content';
    }
};

const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);

const MySidebar = () => {
    const selectedBlock = useSelect(
        (select) => select('core/block-editor').getSelectedBlock(),
        []
    );

    const clientId = selectedBlock?.clientId;
    const blockName = selectedBlock?.name;
    const blockAttributes = selectedBlock?.attributes || {};

    const suggestion = useSelect(
        (select) => clientId ? select('swpanel/ai-suggestions').getSuggestion(clientId) : null,
        [clientId]
    );

    const [editedSuggestion, setEditedSuggestion] = useState('');
    const [imageSuggestions, setImageSuggestions] = useState([]);
    const [loadingImages, setLoadingImages] = useState(false);
    const loading = useSelect((select) => select('swpanel/ai-suggestions').isLoading());
    const { setLoading } = useDispatch('swpanel/ai-suggestions');

	const [imagePrompt, setImagePrompt] = useState('');
    const [imagePage, setPage] = useState(1);
    const [activeTool, setActiveTool] = useState(null);
    const perPage = 10;

    const { clearSuggestion } = useDispatch('swpanel/ai-suggestions');
    const { updateBlockAttributes } = useDispatch('core/block-editor');

    const [errorText, setErrorText] = useState(null);
    const [errorImage, setErrorImage] = useState(null);

    useEffect(() => {
        if (suggestion) {
            setEditedSuggestion(suggestion);
        } else if (selectedBlock) {
            const attrName = getTextAttribute(blockName);
            setEditedSuggestion(blockAttributes[attrName] || '');
        }
    }, [suggestion, selectedBlock]);

    const applySuggestion = () => {
        const attr = getTextAttribute(blockName);
        updateBlockAttributes(clientId, {
            [attr]: editedSuggestion
        });
        try {
            clearSuggestion(clientId);
            setEditedSuggestion('');
        } catch (e) {
            console.error('Failed to clear suggestion:', e);
        }
    };

    const runAI = async (mode) => {
        setLoading(true);
        setErrorText(null);
        try {
            const result = await getAPIText(editedSuggestion, mode);
            setEditedSuggestion(result);
        } catch (err) {
            console.error('AI Text Error:', err);
            setErrorText(__('Could not generate text. Please try again.', 'swpanel-ai'));
        } finally {
            setLoading(false);
        }
    };

    const fetchImageSuggestions = async (newPage = imagePage) => {
        setLoadingImages(true);
        setErrorImage(null);
        try {
            const results = await getAPIImage(imagePrompt, newPage, perPage);
            setImageSuggestions(results);
            setPage(newPage);
        } catch (e) {
            console.error('Image fetch error:', e);
            setErrorImage(__('Could not load images. Please try again.', 'swpanel-ai'));
        } finally {
            setLoadingImages(false);
        }
    };

    const applyImage = ({url, alt, caption}) => {
        updateBlockAttributes(clientId, {
            url,
            alt: alt,
            caption: caption,
        });
    };

    const renderTextTools = () => createElement(
            PanelBody,
            { title: __('Edit with AI', 'swpanel-ai'), initialOpen: true, className: 'swpanel-font' },
            errorText && createElement('div',
                { style: { marginBottom: '12px' } },
                createElement(
                    Notice, {
                        status: 'error',
                        isDismissible: true,
                        onRemove: () => setErrorText(null),
                        className: 'swpanel-font',
                    }, errorText
            )),
            createElement(TextareaControl, {
                label: 'Text',
                value: editedSuggestion,
                onChange: (val) => setEditedSuggestion(val),
                rows: 8,
                __nextHasNoMarginBottom: true,
                className: 'swpanel-font',
            }),
            createElement('div', {
                style: { marginTop: '10px', display: 'flex', flexDirection: 'column', gap: '6px' }, className: 'swpanel-font'
            },
                TextModes.map(({ text, mode, icon }) => 
                    createElement(Button, {
                        key: mode,
                        isSecondary: true,
                        icon: icon,
                        onClick: () => runAI(mode),
                        disabled: loading, 
                        className: 'swpanel-button-white',
                    }, text)
                ),                  
            ),
            createElement(Button, {
                variant: 'primary',
                className: 'swpanel-button',
                onClick: applySuggestion,
                style: { marginTop: '12px' },
                disabled: loading,
            }, loading ? createElement('img', {
                src: `${swpanelData.pluginUrl}../admin/assets/img/loader_points_white.svg`,
                alt: __('Loading...', 'swpanel-ai'),
                width: '20',
                height: '20',
                className: 'swpanel-loader-img'
            }) : __('Apply to Block', 'swpanel-ai'))
    );

    const renderImageTools = () => {
        if (activeTool === 'search') {
            return createElement(
                PanelBody,
                { title: __('Search Images', 'swpanel-ai'), initialOpen: true, className: 'swpanel-font-title' },
                errorImage && createElement('div',
                    { style: { marginBottom: '12px' } },
                    createElement(
                        Notice, {
                            status: 'error',
                            isDismissible: true,
                            onRemove: () => setErrorImage(null),
                            className: 'swpanel-font'
                        }, errorImage
                )),
                createElement(TextControl, {
                    label: __('Describe the image', 'swpanel-ai'),
                    value: imagePrompt,
                    onChange: (val) => setImagePrompt(val),
                    onKeyDown: (event) => {
                        if (event.key === 'Enter' && imagePrompt.trim() && !loadingImages) {
                            event.preventDefault();
                            fetchImageSuggestions();
                        }
                    },
                    placeholder: __('e.g. car, flower', 'swpanel-ai'),
                    style: { marginBottom: '8px' },
                    className: 'swpanel-font'
                }),
                createElement(Button, {
                    isSecondary: true,
                    onClick: () => fetchImageSuggestions(),
                    disabled: loadingImages || !imagePrompt.trim(),
                    className: 'swpanel-button'
                }, __('Search Image', 'swpanel-ai')),
                imageSuggestions.length > 0 && createElement('div', {
                    style: { display: 'flex', flexWrap: 'wrap', marginTop: '10px', gap: '8px' }
                },
                    imageSuggestions.map((image, idx) => createElement('img', {
                        key: idx,
                        src: image.url,
                        style: {
                            aspectRatio: '1 / 1',
                            width: '100px',
                            objectFit: 'cover',
                            cursor: 'pointer',
                            border: '2px solid transparent'
                        },
                        onClick: () => applyImage(image)
                    }))
                ),
                imageSuggestions.length > 0 && createElement('div', {
                    style: { display: 'flex', justifyContent: 'space-between', marginTop: '10px' }
                },
                    createElement(Button, {
                        isSecondary: true,
                        disabled: imagePage === 1,
                        onClick: () => fetchImageSuggestions(imagePage - 1),
                        className: 'swpanel-button'
                    }, __('Previous', 'swpanel-ai')),
                    createElement(Button, {
                        isSecondary: true,
                        onClick: () => fetchImageSuggestions(imagePage + 1),
                        className: 'swpanel-button'
                    }, __('Next', 'swpanel-ai'))
                )
            );
        }

        return createElement(
            PanelBody,
            { title: __('AI Image Tools', 'swpanel-ai'), initialOpen: true, className: 'swpanel-font-title' },
            createElement(Button, {
                className: 'swpanel-button',
                isPrimary: true,
                onClick: () => setActiveTool('search'),
                style: { marginBottom: '10px' }
            }, __('Search Image', 'swpanel-ai')),
        );
    };

    const getPanelContent = () => {
        if (!selectedBlock || !clientId) {
            return createElement(
                    PanelBody,
                    { title: __('AI Tools', 'swpanel-ai'), initialOpen: true, className: 'swpanel-font' },
                    createElement('p', { className: 'swpanel-font' }, __('Select a block to use AI features.', 'swpanel-ai'))
            );
        }

        switch (blockName) {
            case 'core/button':
            case 'core/quote':
            case 'core/paragraph':
            case 'core/heading':
                return renderTextTools();
            case 'core/image':
            case 'core/cover':
                return renderImageTools();
            default:
                return createElement(PanelBody, { title: __('Unsupported Block', 'swpanel-ai'), className: 'swpanel-font' },
                        createElement('p', { className: 'swpanel-font' }, __('This block type is not supported yet.', 'swpanel-ai'))
                );
        }
    };

    return createElement(
        PluginSidebar,
        { name: 'swpanel-ai-sidebar', title: __('SWPanel AI Sidebar', 'swpanel-ai'), icon: MyCustomIcon, className: 'swpanel-font-title' },
        getPanelContent()
    );
};

const getAPIText = async (text, mode) => {
    const domain = window.location.origin.replace(/^https?:\/\//, '');
    const url = swpanelData.apiUrl + `/${domain}/text`;
    const response = await fetch(url
        ,{
        method: 'PUT',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            Authorization: 'Bearer ' + swpanelData.bearerToken
          },
        body: JSON.stringify({
          text: text,
          mode: mode,
          language: swpanelData.language
        }) }
    );
    if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
    }
    const data = await response.json();
    return data.result;
};

const getAPIImage = async (prompt, page = 1, perPage = 10) => {
    const domain = window.location.origin.replace(/^https?:\/\//, '');
    const url = swpanelData.apiUrl + `/${domain}/search/images?keyword=${prompt}&page=${page}&per_page=${perPage}&lang=${swpanelData.language}`;
    const response = await fetch(url ,{
        method: 'GET',
        headers: {
            Authorization: 'Bearer ' + swpanelData.bearerToken
        }}
    );
    if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
    }
    const data = await response.json();
    return data.result.map(image => ({
        url: image.url,
        alt: image.alt,
        caption: image.caption
    }));
};

const MyToolbarButton = createHigherOrderComponent((BlockEdit) => {
    return (props) => {
        const allowedBlocks = [
            'core/paragraph', 'core/heading', 'core/cover', 'core/image', 'core/quote', 'core/button'
        ];
        if (!allowedBlocks.includes(props.name)) {
          return createElement(BlockEdit, props);
        }

        const { openGeneralSidebar } = useDispatch(store);
        const { setSuggestion, setLoading } = useDispatch('swpanel/ai-suggestions');
        const loading = useSelect((select) => select('swpanel/ai-suggestions').isLoading());

        const handleText = async (mode, attributeName = 'content') => {
            try {
                setLoading(true);
                openGeneralSidebar('swpanel-ai-editor/swpanel-ai-sidebar');
                const originalText = props.attributes[attributeName] || '';
                const result = await getAPIText(originalText, mode);
                setSuggestion(props.clientId, result);
            } catch (error) {
                console.error('Error calling AI API:', error);
            } finally {
                setLoading(false);
            }
        };

        const handleImage = async () => {
            openGeneralSidebar('swpanel-ai-editor/swpanel-ai-sidebar');
        };

        const getControlsForBlock = (props) => {
            switch (props.name) {
                case 'core/paragraph':
                case 'core/heading':
                    return TextModes.map(({ text, mode, icon }) => ({
                        title: text,
                        icon: icon,
                        onClick: () => handleText(mode),
                        className: 'swpanel-font'
                    }));
                case 'core/button':
                    return TextModes.map(({ text, mode, icon }) => ({
                        title: text,
                        icon: icon,
                        onClick: () => handleText(mode, 'text'),
                        className: 'swpanel-font'
                    }));
                case 'core/quote':
                    return TextModes.map(({ text, mode, icon }) => ({
                        title: text,
                        icon: icon,
                        onClick: () => handleText(mode, 'citation'),
                        className: 'swpanel-font'
                    }));
                case 'core/cover':
                case 'core/image':
                    return [
                        {
                            title: __('Search image', 'swpanel-ai'),
                            icon: '',
                            onClick: () => handleImage(),
                            className: 'swpanel-font'
                        }
                    ];
                default:
                    return [];
            }
        };
        
        const controls = getControlsForBlock(props);

        return createElement(
            Fragment,
            null,
            createElement(BlockEdit, props),
            createElement(
                BlockControls,
                null,
                createElement(
                    ToolbarGroup,
                    null,
					createElement(
                        ToolbarDropdownMenu,
                        {
                            icon: CustomIconWithText,
                            label: 'SWPanel AI',
                            controls: controls
                        }
                    )
                )
            )
        );
    };
}, 'MyToolbarButton');

registerPlugin('swpanel-ai-editor', {
    render: MySidebar,
});

addFilter(
    'editor.BlockEdit',
    'swpanel-ai-editor/swpanel-ai-sidebar',
    MyToolbarButton
);
