<?php

defined('ABSPATH') or exit('Hey, what are you doing here? You silly human!');

if (! class_exists('Dusky_Hooks')) {
    class Dusky_Hooks
    {
        private static $instance = null;

        public function __construct()
        {

            if (! dusky_enable_devise()) {
                return;
            }

            if (! is_admin()) {
                if (dusky_get_settings('frontDark', true)) {
                    add_action('init', function () {
                        $mode = dusky_get_mode();

                        if (dusky_get_settings('performanceMode', false) || 'light' === $mode) {
                            add_filter(
                                'script_loader_tag',
                                [$this, 'add_defer_attribute'],
                                10,
                                2
                            );
                        }
                    });

                    add_action('wp_footer', [$this, 'render_floating_toggle']);
                    add_filter('wp_nav_menu_items', [$this, 'dusky_toggle_menu_item'], 10, 2);
                    add_action('wp_head', [$this, 'wp_head']);
                }
            } else {
                $adminMode = dusky_get_admin_settings(dusky_get_current_user_id(), 'adminMode', true);

                if ($adminMode) {
                    add_action('admin_head', [$this, 'admin_head']);
                    add_action('admin_footer', [$this, 'render_admin_floating_toggle']);
                    add_filter('wp_nav_menu_items', [$this, 'dusky_toggle_menu_item'], 10, 2);
                }
            }
        }

        public function wp_head()
        {
            if (!dusky_get_settings('frontDark', true) && !get_query_var('dusky-live-edit', false)) {
                return;
            }

            $mode = dusky_get_mode();

            $theme = dusky_get_theme_settings();
            $settings = dusky_get_settings();

            if (!empty($theme['imageReplacement']) || !empty($theme['videoReplacement'])) {
                ?>
                <style>
                    html[data-dusky-dark-mode="dark"] body.dusky-image-replacement img, html[data-dusky-dark-mode="dark"] body.dusky-image-replacement video {
                        filter: brightness(0) !important;
                        animation: blinking 0.3s infinite alternate;
                    }

                    @keyframes blinking {
                        from {
                            opacity: 0.2;
                        }
                        to {
                            opacity: 1;
                        }
                    }
                </style>
                <?php
            }

            ?>

                <script>
                    (function () {
                        function duskyImageFilter(action) {
                        const settings_data = '<?php echo wp_json_encode($settings); ?>';
                        const parseSettings = JSON.parse(settings_data);

                        const { imgInvert, imgInvertInput, imgLowBrightness, imgLowBrightnessInput, imgGrayscale, imgGrayscaleInput } = parseSettings;
                        
                        let filterValue = '';
                        if(action === 'enable') {
                            if (imgGrayscale) {
                                filterValue += `grayscale(${imgGrayscaleInput}%) `;
                            }
                            if (imgInvert) {
                                filterValue += `invert(${imgInvertInput}%) `;
                            }
                            if (imgLowBrightness) {
                                filterValue += `brightness(${100 - imgLowBrightnessInput}%) `;
                            }
                            if(filterValue) {
                                document.body?.classList.add('dusky-image-filters');
                                document.body.style.setProperty('--dusky-image-filters', filterValue.trim());
                            }
                        } else {
                            document.body?.classList.remove('dusky-image-filters');
                            document.body.style.removeProperty('--dusky-image-filters');
                        }
                    }

                    function duskyVideoFilter(action) {
                        const settings_data = '<?php echo wp_json_encode($settings); ?>';
                        const parseSettings = JSON.parse(settings_data);

                        const { videoLowBrightness, videoLowBrightnessInput, videoGrayscale, videoGrayscaleInput } = parseSettings;

                        let filterValue = '';
                        if(action === 'enable') {
                            if (videoGrayscale) {
                                filterValue += `grayscale(${videoGrayscaleInput}%) `;
                            }
                            if (videoLowBrightness) {
                                filterValue += `brightness(${100 - videoLowBrightnessInput}%) `;
                            }
                            if(filterValue) {
                                document.body?.classList.add('dusky-video-filters');
                                document.body?.style.setProperty('--dusky-video-filters', filterValue.trim());
                            }
                        } else {
                            document.body?.classList.remove('dusky-video-filters');
                            document.body?.style.removeProperty('--dusky-video-filters');
                        }
                    }

                    function duskyToggle(isLoad = false) {

                        const theme_data = '<?php echo wp_json_encode($theme); ?>';
                        const parseData = JSON.parse(theme_data);

                        const settings_data = '<?php echo wp_json_encode($settings); ?>';
                        const parseSettings = JSON.parse(settings_data);

                        var dusky_mode = '<?php echo esc_js($mode); ?>';

                        

                        const imageReplacement = parseData?.imageReplacement ?? [];
                        const videoReplacement = parseData?.videoReplacement ?? [];

                        if(!isLoad && (imageReplacement.length || videoReplacement.length)) {

                            document.body?.classList.remove('dusky-image-replacement');
                        
                            [...imageReplacement, ...videoReplacement].forEach(element => {
                                if (element.lightModeURL && element.darkModeURL) {
                                    const darkImage = element.darkModeURL;
                                    const lightImage = element.lightModeURL;

                                    const lightImageUrl = lightImage
                                        .replace(".jpg", "")
                                        .replace(".png", "")
                                        .replace("-scaled", "")
                                        .replace(".gif", "")
                                        .replace("mp4", "");

                                    const changeableImages = document.querySelectorAll(
                                        `img[src^="${lightImageUrl}"], video[src^="${lightImageUrl}"], iframe[src^="${lightImageUrl}"],img[src^="${darkImage}"], video[src^="${darkImage}"], iframe[src^="${darkImage}"]`,
                                    );

                                    changeableImages.forEach((_item) => {
                                        const exactTheme = dusky_mode === "auto" ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : dusky_mode;

                                        const nextImage = exactTheme === "dark" ? darkImage : lightImage;
                                        _item.setAttribute("src", nextImage);

                                        if (_item.hasAttribute("srcset")) {
                                            _item.setAttribute("srcset", nextImage, "1024w");
                                        }
                                    });
                                }
                            })
                        }
                        

                        if (window.DUSKY && isLoad) { 
                            if (dusky_mode == 'dark') {
                                window.DUSKY.enable(parseData);
                            } else if (dusky_mode == 'light') {
                                window.DUSKY.disable();
                            } else if (dusky_mode == 'auto') {
                                window.DUSKY.auto(parseData);
                            }
                        }
                    }

                    window.addEventListener('DOMContentLoaded', function() {
                        DUSKY.isEnabled() ? (
                            duskyImageFilter('enable'),
                            duskyVideoFilter('enable')
                        ) : (
                            duskyImageFilter('disable'),
                            duskyVideoFilter('disable')
                        );
                        duskyToggle();

                    });
                    duskyToggle(true);
                    })()
                </script>

            <?php
        }

        public function admin_head()
        {

            $urlParameter = dusky_get_settings('urlParameter', false);

            $duskyUrlMode = sanitize_text_field(wp_unslash(get_query_var('dusky-mode') ?? '')) ?? false;

            $isDarkMode = $duskyUrlMode === 'dark';
            $isLightMode = $duskyUrlMode === 'light';
            $theme = dusky_get_theme_settings();

            if ($isDarkMode && $urlParameter) { ?>
                <script>window.DUSKY.enable(JSON.parse(<?php echo wp_json_encode($theme); ?>))</script>
                <?php
                return;
            } elseif ($isLightMode && $urlParameter) {
                echo '<script>window.DUSKY.disable()</script>';
                return;
            } else {

                $adminMode = dusky_get_admin_settings(get_current_user_id(), 'adminMode', 'light');
                $themeMode = $adminMode ?: 'light';
                ?>

                <script>
                    var admin_dusky_mode = '<?php echo esc_js($themeMode); ?>';
                    const theme_data_json = '<?php echo wp_json_encode($theme); ?>';

                    const theme = JSON.parse(theme_data_json);

                    if (admin_dusky_mode == 'dark') {
                        window.DUSKY.enable(theme);
                    }
                </script>

<?php

            }
        }

        public function dusky_toggle_menu_item($items, $args)
        {

            $toggleType = dusky_get_settings('toggleType', 'floating');
            if ($toggleType !== 'menu' || (!dusky_get_settings('frontDark', true) && !get_query_var('dusky-live-edit', false))) {
                return $items;
            }

            $menuToggleLocation = dusky_get_settings('selectMenu', []);

            if (! empty($menuToggleLocation)) {
                $menu = $args->menu;

                if (is_object($menu)) {
                    $menu = $menu->slug;
                }

                if (is_array($menuToggleLocation) && in_array($menu, $menuToggleLocation)) {
                    $this->add_defer_attribute($items, 'data-defer');

                    $custom_menu_item = $this->render_floating_toggle(true);

                    $togglePosition = dusky_get_settings('toggleMenuPosition', false);

                    if ($togglePosition) {
                        $items = $custom_menu_item . $items;
                    } else {
                        $items .= $custom_menu_item;
                    }
                }
            }

            return $items;
        }

        public function render_admin_floating_toggle()
        {
            $user_id = get_current_user_id();

            $toggleButton = dusky_get_admin_settings($user_id, 'toggleButton', 'floatingToggle');
            if ($toggleButton === 'floatingToggle') {
                echo '<div id="dusky-floating-toggle"></div>';
            }
        }

        public function render_floating_toggle($return = false)
        {
            $toggleType = dusky_get_settings('toggleType', 'floating');

            if ($toggleType !== 'floating' || (!dusky_get_settings('frontDark', true) && !get_query_var('dusky-live-edit', false))) {
                return;
            }

            $theme = dusky_get_theme_settings();

            if (!empty($theme['imageReplacement']) || !empty($theme['videoReplacement'])) {
                ?>
                <script>
                    document.body?.classList.add('dusky-image-replacement');
                </script>
                <?php
            }

            if (current_user_can('manage_options')) {
                echo '<div id="dusky-frontend-render"></div>';

                if ($return) {
                    return '<li id="menu-item-dusky-toggle" class="menu-item menu-item-type-dusky menu-item-dusky-toggle"><li>';
                }
            } else {
                $mode = dusky_get_mode();
                $toggleStyle = dusky_get_settings('toggleStyle', '1');
                $toggleSize = dusky_get_settings('toggleSize', 'medium');
                $togglePosition = dusky_get_settings('togglePosition', 'right');

                if ($return) {
                    $menuToggleStyle = dusky_get_settings('menuToggleStyle', false);
                    if ($menuToggleStyle) {
                        $lightSvg = '<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-6 h-6 mr-2"><path d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" class="fill-sky-400/20 stroke-sky-500"></path><path d="M12 4v1M17.66 6.344l-.828.828M20.005 12.004h-1M17.66 17.664l-.828-.828M12 20.01V19M6.34 17.664l.835-.836M3.995 12.004h1.01M6 6l.835.836"></path></svg>';

                        $darkSvg = '<svg viewBox="0 0 24 24" fill="none" class="w-6 h-6 mr-2"><path fill-rule="evenodd" clip-rule="evenodd" d="M17.715 15.15A6.5 6.5 0 0 1 9 6.035C6.106 6.922 4 9.645 4 12.867c0 3.94 3.153 7.136 7.042 7.136 3.101 0 5.734-2.032 6.673-4.853Z" class="fill-transparent"></path><path d="m17.715 15.15.95.316a1 1 0 0 0-1.445-1.185l.495.869ZM9 6.035l.846.534a1 1 0 0 0-1.14-1.49L9 6.035Zm8.221 8.246a5.47 5.47 0 0 1-2.72.718v2a7.47 7.47 0 0 0 3.71-.98l-.99-1.738Zm-2.72.718A5.5 5.5 0 0 1 9 9.5H7a7.5 7.5 0 0 0 7.5 7.5v-2ZM9 9.5c0-1.079.31-2.082.845-2.93L8.153 5.5A7.47 7.47 0 0 0 7 9.5h2Zm-4 3.368C5 10.089 6.815 7.75 9.292 6.99L8.706 5.08C5.397 6.094 3 9.201 3 12.867h2Zm6.042 6.136C7.718 19.003 5 16.268 5 12.867H3c0 4.48 3.588 8.136 8.042 8.136v-2Zm5.725-4.17c-.81 2.433-3.074 4.17-5.725 4.17v2c3.552 0 6.553-2.327 7.622-5.537l-1.897-.632Z" stroke-width=".3px"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M17 3a1 1 0 0 1 1 1 2 2 0 0 0 2 2 1 1 0 1 1 0 2 2 2 0 0 0-2 2 1 1 0 1 1-2 0 2 2 0 0 0-2-2 1 1 0 1 1 0-2 2 2 0 0 0 2-2 1 1 0 0 1 1-1Z" fill="#94a3b8"></path></svg>';

                        $activeSvg = $mode === 'dark' ? $darkSvg : ($mode === 'light' ? $lightSvg : '');

                        $activeClassForDark = $mode === 'dark' ? 'ddm-drop-active' : '';
                        $activeClassForLight = $mode === 'light' ? 'ddm-drop-active' : '';
                        $activeClassForSystem = $mode === 'auto' ? 'ddm-drop-active' : '';

                        // active-dropbox Class to show the dropdown
                        return sprintf('<div class="dusky-toggle-dropdown-menu-wrapper menu-item dusky-ignore" tabindex="1">
                            <div class="ddm-toggle-menu-active dusky-active-%s">
                                %s
                            </div>

                            <div class="ddm-toggle-dropdown-list">
                                <span id="ddm-toggle-dropdown-light" data-value="light" class="ddm-toggle-dropdown-list-item %s">
                                    %s
                                Light</span>

                                <span id="ddm-toggle-dropdown-dark" data-value="dark" class="ddm-toggle-dropdown-list-item %s">
                                    %s
                                Dark</span>

                                <span id="ddm-toggle-dropdown-system" data-value="system" class="ddm-toggle-dropdown-list-item %s">
                                <svg viewBox="0 0 24 24" fill="none" class="w-6 h-6 mr-2"><path d="M4 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6Z" stroke-width="2" stroke-linejoin="round" class="stroke-slate-400 dark:stroke-slate-500"></path><path d="M14 15c0 3 2 5 2 5H8s2-2 2-5" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg>
                                System</span>
                            </div>
                        </div>', esc_attr($mode), $activeSvg, esc_attr($activeClassForLight), $lightSvg, esc_attr($activeClassForDark), $darkSvg, esc_attr($activeClassForSystem));
                    }
                    return sprintf('<li id="menu-item-dusky-toggle" class="menu-item menu-item-type-dusky menu-item-dusky-toggle"><div data-dusky_mode="%s" class="dusky-toggle-wrap dusky-%s dusky-active-%s dusky-toggle-style-%s dusky-toggle-%s dusky-ignore"><div class="dusky-toggle-icon"><div class="dusky-toggle-main-icon"></div></div><div class="dusky-toggle-text"><span class="dusky-toggle-%s">%s</span></div></div></li>', esc_attr($mode), esc_attr($togglePosition), esc_attr($mode), esc_attr($toggleStyle), esc_attr($toggleSize), esc_attr($mode), esc_html(ucfirst($mode)));
                }

                printf('<div data-dusky_mode="%s" class="dusky-toggle-wrap dusky-floating dusky-%s dusky-active-%s dusky-toggle-style-%s dusky-toggle-%s dusky-ignore"><div class="dusky-toggle-icon"><div class="dusky-toggle-main-icon"></div></div><div class="dusky-toggle-text"><span class="dusky-toggle-%s">%s</span></div></div>', esc_attr($mode), esc_attr($togglePosition), esc_attr($mode), esc_attr($toggleStyle), esc_attr($toggleSize), esc_attr($mode), esc_html(ucfirst($mode)));
            }
        }

        public function add_defer_attribute($tag, $handle)
        {
            if (in_array($handle, ['dusky-frontend', 'dusky-frontend-config'])) {
                $tag = str_replace(' src', ' defer src', $tag);
            }
            return $tag;
        }

        public static function instance()
        {
            if (self::$instance === null) {
                return self::$instance = new self();
            }
        }
    }
}

Dusky_Hooks::instance();
