import {
    base64Encode,
    getConfig,
    handleBackgroundOverlay,
    initToggles,
    saveSettings,
    getColors,
    useMounted, colorBrightness, hexToRgba,
} from "../../includes/functions";

const {useState, useEffect} = React;

const {isPro, customToggles = [], settings = {}} = dracula;

const $ = jQuery;

export default function HandleChange({data = settings, isEditor, isLiveEdit}) {
    const draculaDarkMode = window.draculaDarkMode;

    let {
        frontendDarkMode = true,

        pageSpecificDarkMode,
        darkToLight,
        colorType = 'dynamic',
        colorMode = 'dynamic',
        preset = 'default',
        activeCustomPreset,
        customPresets = [],
        brightness = 100,
        contrast = 90,
        sepia = 10,
        grayscale = 0,
        scrollbarDarkMode = 'auto',
        scrollbarColor = '#181a1b',

        changeFont,
        fontFamily,
        toggleStyle = 1,
        textStroke = 0,
        fontSize = '1',
        customFontSize = 100,
        showToggle = true,
        floatingDevices = ["desktop", "tablet", "mobile"],
        toggleSize = 'normal',
        customToggleSize = 100,
        togglePosition = 'right',
        toggleSide = 'right',
        bottomOffset = 30,
        sideOffset = 30,
        draggableToggle,

        displayInMenu = false,
        toggleMenus = [],
        menuToggleStyle = 14,
        menuToggleSize = 'normal',
        customMenuToggleSize = 100,
        menuTogglePosition = 'end',

        darkenBackgroundImages = true,
        lowBrightnessImages = false,
        lowBrightnessLevel = 80,
        grayscaleImages = false,
        grayscaleImagesLevel = 80,
        invertImages = false,
        invertImagesLevel = 80,

        lowBrightnessVideos = false,
        videoBrightnessLevel = 80,
        grayscaleVideos = false,
        grayscaleVideosLevel = 80,
    } = data;

    const isMounted = useMounted();

    useEffect(() => {
        if(isEditor) return;

        if (frontendDarkMode) {
            draculaDarkMode.enable(getConfig(data));
        } else {
            draculaDarkMode.disable();
        }

    }, [frontendDarkMode]);

    useEffect(() => {
        if (!isMounted) return;

        saveSettings(data).then(() => {

            if (isLiveEdit) {
                const url = new URL(window.location.href);
                url.searchParams.set('tab', 'colors');
                window.location.href = url.toString();
            } else {
                window.location.reload();
            }

        });

    }, [colorType]);

    // Load Font
    useEffect(() => {
        // Append the link to the document head
        jQuery("head").append(jQuery("<link rel='stylesheet' type='text/css' href='https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&display=swap'>"));
    }, []);

    // Create input field for settings data if is editor
    useEffect(() => {
        if (!isPro || !isEditor) return;

        if (pageSpecificDarkMode) {

            if ('elementor' === isEditor) return;

            const input = jQuery('<input>', {
                type: 'hidden',
                id: 'dracula_settings',
                name: 'dracula_settings'
            });

            jQuery('.dracula-editor-live-edit').append(input);
        } else {
            if ('elementor' === isEditor) {
                window.parent.jQuery('[data-setting="dracula_settings"]').val('').trigger('input');
                return;
            }

            jQuery('#dracula_settings').remove();
        }

    }, [pageSpecificDarkMode]);

    // Update settings data
    useEffect(() => {
        if (!isPro || !isMounted) return;

        dracula.settings = {...dracula.settings, ...data};

        // Save settings on change if is editor input field
        if (isEditor) {
            const input = 'elementor' === isEditor ? window.parent.jQuery('[data-setting="dracula_settings"]') : jQuery('#dracula_settings');
            if (input.length) {
                input.val(base64Encode(JSON.stringify(data))).trigger('input');
            }
        }

    }, [data]);

    // Enable Dark Mode with updated settings
    useEffect(() => {

        if (!isMounted) return;

        if (isEditor && 'elementor' !== isEditor) return;

        if ('dynamic' === colorType) {
            if (draculaDarkMode.isEnabled()) {
                draculaDarkMode.disable();
            }

            draculaDarkMode.enable(getConfig(data));
        }

    }, [
        darkToLight,
        preset,
        colorMode,
        brightness,
        contrast,
        sepia,
        grayscale,
        changeFont,
        fontFamily,
        textStroke,
    ]);

    const [constrains, setConstraints] = useState({left: 0, right: 0, top: 0, bottom: 0});
    useEffect(() => {
        if (!isPro || isEditor) return;

        const element = document.querySelector('.dracula-live-edit');
        if (!element) return;

        const {left, bottom} = element.getBoundingClientRect();
        setConstraints({
            ...constrains,
            left: -left,
            bottom: bottom,
        });

    }, []);

    // Handle font-size change
    useEffect(() => {
        if (!isPro || !isMounted) return;

        if (changeFont) {
            if (fontSize === 'custom') {
                fontSize = customFontSize / 100;
            }

            let css = `html[data-dracula-scheme="dark"] body > *:not(#dracula-live-edit){zoom:${fontSize}}`;
            let cssElement = jQuery('#dracula-font-size-css');

            if (!cssElement.length) {
                cssElement = jQuery('<style>', {id: 'dracula-font-size-css'}).appendTo('head');
            }

            cssElement.html(css);
        } else {
            jQuery('#dracula-font-size-css').remove();
        }

    }, [changeFont, fontSize, customFontSize]);

    // Handle show toggle change
    useEffect(() => {
        if (!isPro || !isMounted) return;

        if (isEditor && 'elementor' !== isEditor) return;

        let floatingToggle = jQuery('.dracula-toggle-wrap.floating');

        if (!floatingToggle.length && showToggle) {
            floatingToggle = jQuery(`<div class="dracula-toggle-wrap floating position-${togglePosition}"></div>`);
            jQuery('body').append(floatingToggle);
        }

        if (!showToggle) {
            floatingToggle.hide();
        } else {
            floatingToggle.show();
        }

    }, [showToggle]);

    // Handle toggle devices change
    useEffect(() => {
        if (!isMounted) return;
        if (isEditor && 'elementor' !== isEditor) return;


        const isMobile = window.innerWidth < 768;
        const isTablet = window.innerWidth >= 768 && window.innerWidth < 1024;
        const isDesktop = window.innerWidth >= 1024;

        const shouldShow = (isMobile && floatingDevices.includes('mobile')) || (isTablet && floatingDevices.includes('tablet')) || (isDesktop && floatingDevices.includes('desktop'));

        let floatingToggle = jQuery('.dracula-toggle-wrap.floating');

        if (!floatingToggle.length && shouldShow) {
            floatingToggle = jQuery(`<div class="dracula-toggle-wrap floating position-${togglePosition}"></div>`);
            jQuery('body').append(floatingToggle);
        }

        if (!shouldShow) {
            floatingToggle.hide();
        }

        if (shouldShow) {
            floatingToggle.show();
        }


    }, [floatingDevices]);

    // Handle toggle size change
    useEffect(() => {
        if (!isMounted) return;
        if (!showToggle) return;
        if (isEditor && 'elementor' !== isEditor) return;

        let css = '';

        const selector = '.dracula-toggle-wrap.floating .dracula-toggle';
        if ('custom' !== toggleSize) {
            css += `${selector} {--toggle-scale:${'small' === toggleSize ? '.8' : 'large' === toggleSize ? '1.5' : '1'};}`;
        } else {
            css += `${selector}{--toggle-scale:${customToggleSize / 100};}`;
        }

        let cssElement = jQuery('#dracula-size-css');

        if (!cssElement.length) {
            cssElement = jQuery('<style>', {id: 'dracula-size-css'}).appendTo('head');
        }

        cssElement.html(css);
    }, [toggleSize, customToggleSize]);

    // Handle the positioning of the toggle switch
    useEffect(() => {
        // Exit early if the conditions aren't met
        if ( !isMounted || !showToggle || (isEditor && 'elementor' !== isEditor)) return;

        const toggle = jQuery('.dracula-toggle-wrap.floating');

        // Handle custom positioning
        if (togglePosition === 'custom') {
            toggle.removeAttr('style');
            localStorage.removeItem('dracula_floating_position');


            toggle.addClass('position-custom');

            // Construct custom CSS for toggle position
            const css = `
            .dracula-toggle-wrap.position-custom {
                --bottom-offset:${bottomOffset}px;
                --side-offset:${sideOffset}px;
            }
        `;

            let cssElement = jQuery('#dracula-position-css');

            // Append style tag if not already present
            if (cssElement.length === 0) {
                cssElement = jQuery('<style>', {id: 'dracula-position-css'}).appendTo('head');
            }

            cssElement.html(css);
        } else {
            toggle.removeClass('position-custom');
        }

        // Update toggle position class
        if (!toggle.hasClass(`position-${togglePosition}`)) {
            toggle.removeClass('position-right position-left').addClass(`position-${togglePosition}`);
        }

    }, [togglePosition, toggleSide, bottomOffset, sideOffset]);

    // Handle display in menu change
    useEffect(() => {
        if (!isPro || !isMounted) return;
        if (isEditor && 'elementor' !== isEditor) return;

        let menuToggle = jQuery('.dracula-toggle-wrap.menu-item');

        if (displayInMenu) {
            menuToggle.show();
        } else {
            menuToggle.hide();
        }


    }, [displayInMenu]);

    // Handle menu toggles
    useEffect(() => {
        if (!isPro || !isMounted) return;
        if (!displayInMenu) return;
        if (isEditor && 'elementor' !== isEditor) return;

        if (!toggleMenus.length) {
            $('.dracula-toggle-wrap.menu-item').hide();
            return;
        }

        toggleMenus.forEach((menu) => {
            const menuElement = $(`#menu-${menu}`);

            if (!menuElement.length) return;

            let menuToggle = menuElement.find('.dracula-toggle-wrap.menu-item');
            if (!menuToggle.length) {
                menuToggle = $(`<div class="dracula-toggle-wrap menu-item"></div>`);

                const isCustom = /^custom-/.test(String(menuToggleStyle));

                if (isCustom) {
                    const id = menuToggleStyle.replace('custom-', '');
                    const data = btoa(JSON.stringify(customToggles.find((item) => item.id == id)?.config));

                    menuToggle.addClass('custom-toggle');
                    menuToggle.data('id', id);
                    menuToggle.data('data', data);

                } else {
                    menuToggle.removeClass('custom-toggle');
                    menuToggle.data('id', '');
                    menuToggle.data('data', '');

                    menuToggle.data('style', menuToggleStyle);
                }

                if ('start' === menuTogglePosition) {
                    menuElement.prepend(menuToggle);
                } else {
                    menuElement.append(menuToggle);
                }

            } else {
                menuToggle.show();
            }

        });

        initToggles();

    }, [toggleMenus]);

    // Handle menu toggle size
    useEffect(() => {
        if (!isPro || !isMounted) return;
        if (!displayInMenu) return;
        if (isEditor && 'elementor' !== isEditor) return;

        let css = '';

        const selector = '.dracula-toggle-wrap.menu-item .dracula-toggle';
        if ('custom' !== menuToggleSize) {
            css += `${selector} {--toggle-scale:${'small' === menuToggleSize ? '.8' : 'large' === menuToggleSize ? '1.5' : '1'};}`;
        } else {
            css += `${selector}{--toggle-scale:${customMenuToggleSize / 100};}`;
        }

        let cssElement = jQuery('#dracula-menu-size-css');

        if (!cssElement.length) {
            cssElement = jQuery('<style>', {id: 'dracula-menu-size-css'}).appendTo('head');
        }

        cssElement.html(css);
    }, [menuToggleSize, customMenuToggleSize]);

    // Handle menu toggle position
    useEffect(() => {
        if (!isPro || !isMounted) return;
        if (!displayInMenu) return;
        if (isEditor && 'elementor' !== isEditor) return;


        const menuToggles = jQuery('.dracula-toggle-wrap.menu-item');

        menuToggles.each((index, element) => {
            const menuToggle = jQuery(element);
            const menu = menuToggle.parent();

            const isFirst = menuToggle.prev().length === 0;

            if ((isFirst && 'start' !== menuTogglePosition) || (!isFirst && 'end' !== menuTogglePosition)) {
                menuToggle.detach();
            }

            if (!isFirst && 'start' === menuTogglePosition) {
                menu.prepend(menuToggle);
            }

            if (isFirst && 'end' === menuTogglePosition) {
                menu.append(menuToggle);
            }

        });
    }, [menuTogglePosition]);

    // Handle floating toggle style change
    useEffect(() => {
        if (!isMounted) return;

        const $ = jQuery;

        let floatingToggle = $('.dracula-toggle-wrap.floating');
        if (floatingToggle.length) {

            const isCustom = /^custom-/.test(String(toggleStyle));

            if (isCustom) {
                const id = toggleStyle.replace('custom-', '');
                const data = btoa(JSON.stringify(customToggles.find((item) => item.id == id)?.config));

                floatingToggle.addClass('custom-toggle');
                floatingToggle.data('id', id);
                floatingToggle.data('data', data);

            } else {
                floatingToggle.removeClass('custom-toggle');
                floatingToggle.data('id', '');
                floatingToggle.data('data', '');

                floatingToggle.data('style', toggleStyle);
            }

        }

        initToggles();


    }, [toggleStyle]);

    // Handle menu toggle style change
    useEffect(() => {
        if (!isPro || !isMounted) return;

        const $ = jQuery;

        let menuToggle = $('.dracula-toggle-wrap.menu-item');
        if (menuToggle.length) {

            const isCustom = /^custom-/.test(String(menuToggleStyle));

            if (isCustom) {
                const id = menuToggleStyle.replace('custom-', '');
                const data = btoa(JSON.stringify(customToggles.find((item) => item.id == id)?.config));

                menuToggle.addClass('custom-toggle');
                menuToggle.data('id', id);
                menuToggle.data('data', data);

            } else {
                menuToggle.removeClass('custom-toggle');
                menuToggle.data('id', '');
                menuToggle.data('data', '');

                menuToggle.data('style', menuToggleStyle);
            }

        }

        initToggles();

    }, [menuToggleStyle]);

    // Handle Image Settings
    useEffect(() => {
        if ( !isMounted) return;
        if (isEditor && 'elementor' !== isEditor) return;

        if (!draculaDarkMode.isEnabled()) return;

        let css = '';

        css += `html[data-dracula-scheme="dark"] img:not(.dracula-toggle *, .dracula-ignore, .dracula-ignore * , .elementor-background-overlay, .elementor-element-overlay, .elementor-button-link, .elementor-button-link *, .elementor-widget-spacer, .elementor-widget-spacer *, .wp-block-button__link, .wp-block-button__link *){`;

        let filterCss = '';

        if (lowBrightnessImages) {
            filterCss += `brightness(${lowBrightnessLevel}%)`;
        }

        if (grayscaleImages) {
            filterCss += ` grayscale(${grayscaleImagesLevel}%)`;
        }

        if (invertImages) {
            filterCss += ` invert(${invertImagesLevel}%)`;
        }

        css += `filter:${filterCss};`;
        css += `}`;

        let cssElement = jQuery('#dracula-images-css');

        if (cssElement.length === 0) {
            cssElement = jQuery('<style>', {id: 'dracula-images-css'}).appendTo('head');
        }

        cssElement.html(css);

    }, [lowBrightnessImages, lowBrightnessLevel, grayscaleImages, grayscaleImagesLevel, invertImages, invertImagesLevel,]);

    // Handle Darken Background Images
    useEffect(() => {
        if (!isMounted) return;

        handleBackgroundOverlay(darkenBackgroundImages);
    }, [darkenBackgroundImages]);

    // Handle Video Settings
    useEffect(() => {
        if (!isPro || !isMounted) return;
        if (isEditor && 'elementor' !== isEditor) return;

        if (!draculaDarkMode.isEnabled()) return;

        let css = '';

        css += `html[data-dracula-scheme="dark"] video:not(.dracula-toggle *, .dracula-ignore, .dracula-ignore * ),`;
        css += `html[data-dracula-scheme="dark"] iframe[src*="youtube.com"],`;
        css += `html[data-dracula-scheme="dark"] iframe[src*="vimeo.com"],`;
        css += `html[data-dracula-scheme="dark"] iframe[src*="dailymotion.com"]{`;

        let filterCss = '';

        if (lowBrightnessVideos) {
            filterCss += `brightness(${videoBrightnessLevel}%)`;
        }

        if (grayscaleVideos) {
            filterCss += ` grayscale(${grayscaleVideosLevel}%)`;
        }

        css += `filter:${filterCss};`;
        css += `}`;

        let cssElement = jQuery('#dracula-videos-css');

        if (cssElement.length === 0) {
            cssElement = jQuery('<style>', {id: 'dracula-video-css'}).appendTo('head');
        }

        cssElement.html(css);


    }, [lowBrightnessVideos, videoBrightnessLevel, grayscaleVideos, grayscaleVideosLevel,]);

    // Handle Colors
    useEffect(() => {

        if (!isMounted) return;

        if ('static' === colorType || 'custom' === colorMode) {

            const colors = getColors({
                colorMode,
                preset,
                activeCustomPreset,
                customPresets,
            });

            const {
                bg = '#181a1b',
                text = '#e8e6e3',
                secondary_bg = '#202324',
                link = '#6ea5d9',
                link_hover = '#88b9e3',
                btn_bg = '#3b6f99',
                btn_text = '#dcdcdc',
                btn_text_hover = '#f0f0f0',
                btn_hover_bg = '#325d80',
                input_text = '#e8e6e3',
                input_bg = '#1f2223',
                input_placeholder = '#8c8c8c',
                border = '#2d2d2d',
            } = colors;

            //replace the colors in the :root selector variables with dracula prefix
            let css = `
                    :root {
                        --dracula-bg-color: ${bg};
                        --dracula-text-color: ${text};
                        --dracula-secondary-bg-color: ${secondary_bg};
                        --dracula-link-color: ${link};
                        --dracula-link-hover-color: ${link_hover};
                        --dracula-btn-bg-color: ${btn_bg};
                        --dracula-btn-text-color: ${btn_text};
                        --dracula-btn-text-hover-color: ${btn_text_hover};
                        --dracula-btn-hover-bg-color: ${btn_hover_bg};
                        --dracula-input-text-color: ${input_text};
                        --dracula-input-bg-color: ${input_bg};
                        --dracula-input-placeholder-color: ${input_placeholder};
                        --dracula-border-color: ${border};
                    }
                `;

            let cssElement = jQuery('#dracula-color-css');

            if (!cssElement.length) {
                cssElement = jQuery('<style>', {id: 'dracula-color-css'}).appendTo('head');
            }

            cssElement.html(css);

        } else {
            jQuery('#dracula-color-css').remove();
        }

        if ('dynamic' === colorType && 'custom' === colorMode) {
            draculaDarkMode.disable();
            draculaDarkMode.enable(getConfig(data));
        }

    }, [
        colorMode,
        preset,
        activeCustomPreset,
        customPresets,
    ]);

    // Handle Scrollbar Color
    useEffect(() => {

        if (!isMounted || !draculaDarkMode.isEnabled()) return;

        if ('dynamic' === colorType) {
            draculaDarkMode.disable();
            draculaDarkMode.enable(getConfig(data));
        } else {

            if ('disabled' === scrollbarDarkMode) {
                jQuery('#dracula-scrollbar-css').remove();
            } else {

                let cssElement = jQuery('#dracula-scrollbar-css');
                if (!cssElement.length) {
                    cssElement = jQuery('<style>', {id: 'dracula-scrollbar-css'}).appendTo('head');
                }

                const colors = getColors({
                    colorMode,
                    preset,
                    activeCustomPreset,
                    customPresets,
                });

                let trackColor = colorBrightness(colors.bg, 10);
                let thumbColor = colorBrightness(colors.secondary_bg, 30);

                if ('custom' === scrollbarDarkMode) {
                    trackColor = hexToRgba(scrollbarColor, .25);
                    thumbColor = scrollbarColor;
                }

                let css = `
                html[data-dracula-scheme="dark"], * {
                    scrollbar-width: thin;
                    scrollbar-color: ${thumbColor} ${trackColor};
                    }
                `;

                cssElement.html(css);
            }
        }


    }, [scrollbarDarkMode, scrollbarColor]);

    return null;
}