<?php
namespace BLR\Backline\Core;

if (!defined('ABSPATH')) { exit; }

final class Assets {
    private static string $frontend_context = '';

    public static function boot(): void {
        add_action('admin_enqueue_scripts', [self::class, 'admin_assets']);
        add_action('wp_enqueue_scripts', [self::class, 'frontend_assets'], 20);
        add_action('wp_enqueue_scripts', [self::class, 'strip_conflicting_frontend_styles'], 999);
        add_action('wp_enqueue_scripts', [self::class, 'strip_conflicting_frontend_scripts'], 999);
    }

    public static function set_frontend_context(string $context): void {
        $context = sanitize_key($context);
        self::$frontend_context = in_array($context, ['app', 'auth'], true) ? $context : '';
    }

    public static function admin_assets(string $hook): void {
        $allowed_hooks = [
            'toplevel_page_blr-backline',
        ];

        if (!in_array($hook, $allowed_hooks, true)) {
            return;
        }

        wp_enqueue_media();

        wp_enqueue_style(
            'blr-ba-admin',
            BLR_BA_URL . 'assets/blr-ba/css/blr-ba-admin.css',
            [],
            BLR_BA_VERSION
        );

        wp_enqueue_style(
            'blr-ba-select2',
            BLR_BA_URL . 'assets/vendor/select2/css/select2.css',
            [],
            BLR_BA_VERSION
        );

        wp_enqueue_script(
            'blr-ba-select2',
            BLR_BA_URL . 'assets/vendor/select2/js/select2.js',
            ['jquery'],
            BLR_BA_VERSION,
            true
        );

        wp_enqueue_script(
            'blr-ba-admin-settings',
            BLR_BA_URL . 'assets/blr-ba/js/blr-ba-admin-settings.js',
            ['jquery', 'blr-ba-select2'],
            self::asset_version('assets/blr-ba/js/blr-ba-admin-settings.js'),
            true
        );

        wp_add_inline_script(
            'blr-ba-select2',
            'jQuery(function($){
                $(".blr-ba-select2").select2({ width: "100%" });

                var sidebarLogoInput = $("#' . esc_js(SettingsPage::OPT_SIDEBAR_LOGO_ID) . '");
                var sidebarLogoPreview = $("#blr-ba-sidebar-logo-preview");
                var chooseSidebarLogoButton = $("#blr-ba-choose-sidebar-logo");
                var removeSidebarLogoButton = $("#blr-ba-remove-sidebar-logo");
                var fallbackLogoUrl = ' . wp_json_encode(BLR_BA_URL . 'assets/blr-ba/img/backline-icon.png') . ';
                var mediaFrame = null;

                function updateSidebarLogoPreview(url, hasCustomLogo) {
                    sidebarLogoPreview.attr("src", url || fallbackLogoUrl);
                    removeSidebarLogoButton.prop("disabled", !hasCustomLogo);
                }

                chooseSidebarLogoButton.on("click", function(e){
                    e.preventDefault();

                    if (mediaFrame) {
                        mediaFrame.open();
                        return;
                    }

                    mediaFrame = wp.media({
                        title: ' . wp_json_encode(__('Choose sidebar logo', 'blr-backline')) . ',
                        button: {
                            text: ' . wp_json_encode(__('Use this logo', 'blr-backline')) . '
                        },
                        library: {
                            type: "image"
                        },
                        multiple: false
                    });

                    mediaFrame.on("select", function(){
                        var attachment = mediaFrame.state().get("selection").first().toJSON();

                        if (!attachment || !attachment.id) {
                            return;
                        }

                        sidebarLogoInput.val(String(attachment.id));
                        updateSidebarLogoPreview(attachment.url || "", true);
                    });

                    mediaFrame.open();
                });

                removeSidebarLogoButton.on("click", function(e){
                    e.preventDefault();
                    sidebarLogoInput.val("");
                    updateSidebarLogoPreview(fallbackLogoUrl, false);
                });
            });'
        );
    }


    private static function asset_version(string $relative_path): string {
        $base_path = defined('BLR_BA_PATH')
            ? BLR_BA_PATH
            : trailingslashit(dirname(__DIR__, 2));

        $path = $base_path . ltrim($relative_path, '/\\');

        if (file_exists($path)) {
            return (string) filemtime($path);
        }

        return BLR_BA_VERSION;
    }

    public static function frontend_assets(): void {
        $context = self::detect_frontend_context();
        if ($context === '') {
            return;
        }

        self::$frontend_context = $context;

        if ($context === 'app') {
            self::enqueue_app_assets();
            return;
        }

        self::enqueue_auth_assets();
    }

    public static function enqueue_app_assets(): void {
        self::register_shared_frontend_assets();
        self::enqueue_theme_boot(SettingsPage::current_theme_mode(), true);

        if (self::is_frontend_settings_route()) {
            wp_enqueue_media();
        }

        wp_enqueue_style('blr-ba-bootstrap');
        wp_enqueue_style('blr-ba-adminkit');
        wp_enqueue_style('blr-ba-flatpickr');
        wp_enqueue_style('blr-ba-select2');
        wp_enqueue_style('blr-ba-frontend');
        self::apply_theme_variables();

        wp_enqueue_script('jquery');
        wp_enqueue_script('blr-ba-bootstrap');
        wp_enqueue_script('blr-ba-feather');
        wp_enqueue_script('blr-ba-flatpickr');
        wp_enqueue_script('blr-ba-select2');
        wp_enqueue_script('blr-ba-plugin');
        self::localize_plugin_script();
    }

    public static function enqueue_auth_assets(): void {
        self::register_shared_frontend_assets();
        self::enqueue_theme_boot(is_user_logged_in() ? SettingsPage::current_theme_mode() : 'light', is_user_logged_in());

        wp_enqueue_style('blr-ba-bootstrap');
        wp_enqueue_style('blr-ba-adminkit');
        wp_enqueue_style('blr-ba-flatpickr');
        wp_enqueue_style('blr-ba-select2');
        wp_enqueue_style('blr-ba-frontend');
        self::apply_theme_variables();

        wp_enqueue_script('jquery');
        wp_enqueue_script('blr-ba-bootstrap');
        wp_enqueue_script('blr-ba-feather');
        wp_enqueue_script('blr-ba-flatpickr');
        wp_enqueue_script('blr-ba-select2');
        wp_enqueue_script('blr-ba-plugin');
        self::localize_plugin_script();
    }

    private static function enqueue_theme_boot(string $theme_mode, bool $prefer_server_mode): void {
        wp_register_script('blr-ba-theme-boot', false, [], BLR_BA_VERSION, false);
        wp_enqueue_script('blr-ba-theme-boot');
        wp_add_inline_script('blr-ba-theme-boot', SettingsPage::theme_mode_boot_code($theme_mode, $prefer_server_mode));
    }

    private static function apply_theme_variables(): void {
        wp_add_inline_style('blr-ba-frontend', SettingsPage::theme_css_variables());
    }

    private static function localize_plugin_script(): void {
        wp_localize_script('blr-ba-plugin', 'blrBaL10n', [
            'ajaxUrl' => admin_url('admin-ajax.php'),
            'sidebarLogo' => [
                'enabled' => self::is_frontend_settings_route(),
                'fieldId' => SettingsPage::OPT_SIDEBAR_LOGO_ID,
                'fallbackUrl' => BLR_BA_URL . 'assets/blr-ba/img/backline-icon.png',
                'chooseTitle' => __('Choose sidebar logo', 'blr-backline'),
                'chooseButton' => __('Use this logo', 'blr-backline'),
            ],
            'themeMode' => SettingsPage::current_theme_mode(),
            'themeModeNonce' => wp_create_nonce('blr_ba_theme_mode'),
            'lightMode' => __('Light mode', 'blr-backline'),
            'darkMode' => __('Dark mode', 'blr-backline'),
            'switchToLightMode' => __('Switch to light mode', 'blr-backline'),
            'switchToDarkMode' => __('Switch to dark mode', 'blr-backline'),
            'noImageSet' => __('No image set.', 'blr-backline'),
            'noAudioSet' => __('No audio file selected.', 'blr-backline'),
            'dragToReorder' => __('Drag to reorder', 'blr-backline'),
            'edit' => __('Edit', 'blr-backline'),
            'remove' => __('Remove', 'blr-backline'),
            'play' => __('Play', 'blr-backline'),
            'pause' => __('Pause', 'blr-backline'),
            'playCurrentTrack' => __('Play current track', 'blr-backline'),
            'pauseCurrentTrack' => __('Pause current track', 'blr-backline'),
            'selectedTrackNoAudio' => __('Selected track has no audio file attached.', 'blr-backline'),
            'readyToPlay' => __('Ready to play.', 'blr-backline'),
            'playing' => __('Playing.', 'blr-backline'),
            'paused' => __('Paused.', 'blr-backline'),
            'playbackFinished' => __('Playback finished.', 'blr-backline'),
            'noTracksAvailable' => __('No tracks available.', 'blr-backline'),
            'noAudioAttachedForTrack' => __('No audio file attached for this track.', 'blr-backline'),
            'untitledTrack' => __('Untitled Track', 'blr-backline'),
        ]);
    }

    /**
     * Keep Backline frontend routes isolated from theme/plugin CSS.
     *
     * Backline renders a self-contained dashboard UI. These removals are scoped
     * to Backline-owned frontend routes only; normal theme pages, posts, admin
     * screens, and unrelated plugin views are not touched. The goal is to prevent
     * theme/block/WooCommerce styles or duplicate Bootstrap bundles from breaking
     * the dashboard environment. Site owners can opt out with the
     * `blr_backline_strip_conflicting_assets` filter.
     */
    public static function strip_conflicting_frontend_styles(): void {
        if (!self::is_plugin_frontend_request() || !self::should_strip_conflicting_assets()) {
            return;
        }

        global $wp_styles;

        if (!($wp_styles instanceof \WP_Styles)) {
            return;
        }

        $keep_handles = [
            'blr-ba-adminkit',
            'blr-ba-flatpickr',
            'blr-ba-select2',
            'blr-ba-frontend',
            'dashicons',
            'admin-bar',
            'blr-ba-bootstrap',
        ];

        $remove_handles = [
            'global-styles',
            'classic-theme-styles',
            'wp-block-library',
            'wp-block-library-theme',
            'wc-block-style',
        ];

        $theme_uris = array_filter([
            untrailingslashit(get_stylesheet_directory_uri()),
            untrailingslashit(get_template_directory_uri()),
        ]);

        foreach ($remove_handles as $handle) {
            if (wp_style_is($handle, 'enqueued') || wp_style_is($handle, 'registered')) {
                wp_dequeue_style($handle);
                wp_deregister_style($handle);
            }
        }

        self::remove_bootstrap_conflicts($wp_styles, $keep_handles, true);

        $queued_handles = is_array($wp_styles->queue) ? $wp_styles->queue : [];

        foreach ($queued_handles as $handle) {
            if (in_array($handle, $keep_handles, true)) {
                continue;
            }

            if (!isset($wp_styles->registered[$handle])) {
                continue;
            }

            $registered = $wp_styles->registered[$handle];
            $src = isset($registered->src) ? (string) $registered->src : '';

            if ($src === '') {
                continue;
            }

            $normalized_src = self::normalize_asset_src($src);
            if ($normalized_src === '') {
                continue;
            }

            foreach ($theme_uris as $theme_uri) {
                if (self::starts_with($normalized_src, $theme_uri . '/')) {
                    wp_dequeue_style($handle);
                    wp_deregister_style($handle);
                    break;
                }
            }
        }
    }

    /**
     * Keep Backline frontend routes isolated from theme/plugin JavaScript.
     *
     * This is intentionally strict, but only inside Backline's own app/auth
     * layouts. The filter lets unusual installations disable the strip behavior
     * without editing plugin files.
     */
    public static function strip_conflicting_frontend_scripts(): void {
        if (!self::is_plugin_frontend_request() || !self::should_strip_conflicting_assets()) {
            return;
        }

        global $wp_scripts;

        if (!($wp_scripts instanceof \WP_Scripts)) {
            return;
        }

        $keep_handles = [
            'jquery',
            'jquery-core',
            'jquery-migrate',
            'blr-ba-bootstrap',
            'blr-ba-feather',
            'blr-ba-flatpickr',
            'blr-ba-select2',
            'blr-ba-plugin',
            'blr-ba-theme-boot',
            'admin-bar',
        ];

        $remove_handles = [
            'wp-embed',
        ];

        $theme_uris = array_filter([
            untrailingslashit(get_stylesheet_directory_uri()),
            untrailingslashit(get_template_directory_uri()),
        ]);

        foreach ($remove_handles as $handle) {
            if (wp_script_is($handle, 'enqueued') || wp_script_is($handle, 'registered')) {
                wp_dequeue_script($handle);
                wp_deregister_script($handle);
            }
        }

        self::remove_bootstrap_conflicts($wp_scripts, $keep_handles, false);

        $queued_handles = is_array($wp_scripts->queue) ? $wp_scripts->queue : [];

        foreach ($queued_handles as $handle) {
            if (in_array($handle, $keep_handles, true)) {
                continue;
            }

            if (!isset($wp_scripts->registered[$handle])) {
                continue;
            }

            $registered = $wp_scripts->registered[$handle];
            $src = isset($registered->src) ? (string) $registered->src : '';

            if ($src === '') {
                continue;
            }

            $normalized_src = self::normalize_asset_src($src);
            if ($normalized_src === '') {
                continue;
            }

            foreach ($theme_uris as $theme_uri) {
                if (self::starts_with($normalized_src, $theme_uri . '/')) {
                    wp_dequeue_script($handle);
                    wp_deregister_script($handle);
                    break;
                }
            }
        }
    }

    private static function should_strip_conflicting_assets(): bool {
        /**
         * Controls whether Backline strips likely-conflicting theme/plugin assets on its own frontend routes.
         *
         * @param bool $enabled Default true.
         */
        return (bool) apply_filters('blr_backline_strip_conflicting_assets', true);
    }

    private static function register_shared_frontend_assets(): void {
        wp_register_style(
            'blr-ba-bootstrap',
            BLR_BA_URL . 'assets/vendor/bootstrap/css/bootstrap.css',
            [],
            self::asset_version('assets/vendor/bootstrap/css/bootstrap.css')
        );

        wp_register_style(
            'blr-ba-adminkit',
            BLR_BA_URL . 'assets/adminkit/css/app.css',
            ['blr-ba-bootstrap'],
            self::asset_version('assets/adminkit/css/app.css')
        );

        wp_register_style(
            'blr-ba-flatpickr',
            BLR_BA_URL . 'assets/vendor/flatpickr/css/flatpickr.css',
            ['blr-ba-adminkit'],
            self::asset_version('assets/vendor/flatpickr/css/flatpickr.css')
        );

        wp_register_style(
            'blr-ba-select2',
            BLR_BA_URL . 'assets/vendor/select2/css/select2.css',
            [],
            self::asset_version('assets/vendor/select2/css/select2.css')
        );

        wp_register_style(
            'blr-ba-frontend',
            BLR_BA_URL . 'assets/blr-ba/css/frontend.css',
            ['blr-ba-adminkit', 'blr-ba-flatpickr', 'blr-ba-select2'],
            self::asset_version('assets/blr-ba/css/frontend.css')
        );

        wp_register_script(
            'blr-ba-bootstrap',
            BLR_BA_URL . 'assets/vendor/bootstrap/js/bootstrap.js',
            [],
            self::asset_version('assets/vendor/bootstrap/js/bootstrap.js'),
            true
        );

        wp_register_script(
            'blr-ba-feather',
            BLR_BA_URL . 'assets/vendor/feather/js/feather.js',
            [],
            self::asset_version('assets/vendor/feather/js/feather.js'),
            true
        );

        wp_register_script(
            'blr-ba-flatpickr',
            BLR_BA_URL . 'assets/vendor/flatpickr/js/flatpickr.js',
            [],
            self::asset_version('assets/vendor/flatpickr/js/flatpickr.js'),
            true
        );

        wp_register_script(
            'blr-ba-select2',
            BLR_BA_URL . 'assets/vendor/select2/js/select2.js',
            ['jquery'],
            self::asset_version('assets/vendor/select2/js/select2.js'),
            true
        );

        wp_register_script(
            'blr-ba-plugin',
            BLR_BA_URL . 'assets/blr-ba/js/blr-ba.js',
            ['jquery', 'blr-ba-bootstrap', 'blr-ba-feather', 'blr-ba-flatpickr', 'blr-ba-select2'],
            self::asset_version('assets/blr-ba/js/blr-ba.js'),
            true
        );
    }

    private static function detect_frontend_context(): string {
        if ((string) get_query_var('blr_band_admin') !== '1') {
            return '';
        }

        $route = self::current_frontend_route();
        $first_segment = sanitize_key(strtok($route !== '' ? $route : 'dashboard', '/') ?: 'dashboard');

        if (in_array($first_segment, ['login', 'not-allowed'], true)) {
            return 'auth';
        }

        return 'app';
    }

    private static function is_plugin_frontend_request(): bool {
        $context = self::detect_frontend_context();
        if ($context !== '') {
            self::$frontend_context = $context;
        }

        return self::$frontend_context === 'app' || self::$frontend_context === 'auth';
    }

    private static function current_frontend_route(): string {
        return trim(sanitize_text_field((string) get_query_var('blr_ba_path')), '/');
    }

    private static function is_frontend_settings_route(): bool {
        return self::detect_frontend_context() === 'app' && self::current_frontend_route() === 'settings';
    }

    private static function is_bootstrap_conflict_handle(string $handle, string $normalized_src, array $allowed_handles = []): bool {
        if ($handle === '') {
            return false;
        }

        if (in_array($handle, $allowed_handles, true)) {
            return false;
        }

        if (preg_match('/(^|[-_])blr-ba-bootstrap([\-_]|$)/i', $handle) === 1) {
            return true;
        }

        // Detect common standalone Bootstrap handles while preserving icon-only packages.
        // This method is called only on Backline frontend routes after the opt-out filter has passed.
        $handle_looks_like_bootstrap = preg_match('/(^|[-_])(bootstrap|bootstrap[45]|twbs-bootstrap|bs-bootstrap)([-_]|$)/i', $handle) === 1;
        $handle_is_icons = preg_match('/bootstrap[-_]?icons/i', $handle) === 1;
        if ($handle_looks_like_bootstrap && !$handle_is_icons) {
            return true;
        }

        if ($normalized_src === '') {
            return false;
        }

        if (preg_match('/(^|[\/.-])blr-ba-bootstrap([\/.-]|$)/i', $normalized_src) === 1) {
            return true;
        }

        return preg_match('/(?:[\/.-]|^)bootstrap(?:[45])?(?:\.bundle)?(?:\.min)?\.(?:css|js)(?:\?.*)?$/i', $normalized_src) === 1
            || preg_match('/(?:[\/.-]|^)bootstrap(?:[45])?(?:[\/.-]|$)/i', $normalized_src) === 1;
    }

    private static function remove_bootstrap_conflicts(\WP_Dependencies $dependencies, array $keep_handles, bool $is_style): void {
        $queued_handles = is_array($dependencies->queue) ? $dependencies->queue : [];

        foreach ($queued_handles as $handle) {
            if (in_array($handle, $keep_handles, true)) {
                continue;
            }

            if (!isset($dependencies->registered[$handle])) {
                continue;
            }

            $registered = $dependencies->registered[$handle];
            $src = isset($registered->src) ? (string) $registered->src : '';
            $normalized_src = self::normalize_asset_src($src);

            if (!self::is_bootstrap_conflict_handle($handle, $normalized_src, $keep_handles)) {
                continue;
            }

            if ($is_style) {
                wp_dequeue_style($handle);
                wp_deregister_style($handle);
            } else {
                wp_dequeue_script($handle);
                wp_deregister_script($handle);
            }
        }
    }

    private static function normalize_asset_src(string $src): string {
        if ($src === '') {
            return '';
        }

        if (strpos($src, '//') === 0) {
            $src = (is_ssl() ? 'https:' : 'http:') . $src;
        } elseif (strpos($src, '/') === 0) {
            $src = home_url($src);
        }

        return $src;
    }

    private static function starts_with(string $haystack, string $needle): bool {
        if ($needle === '') {
            return true;
        }

        return substr($haystack, 0, strlen($needle)) === $needle;
    }


}
