<?php

namespace BookWellAB;

defined('ABSPATH') || exit;

if (!class_exists('BOOKWELL')) {

    class BOOKWELL
    {

        private static $instance = null;
        private $bwdb;

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

        public static function render()
        {
            do_action('bookwellab_admin_html_file');
        }

        private function __construct()
        {
            $this->bwdb = new BookWellAB_Database();

            add_action('init', [$this, 'maybe_upgrade_database'], 5);
            if (is_admin()) {

                // Ensure Admin has capabilities (Dev/Update fix)
                $role = get_role('administrator');
                if ($role && !$role->has_cap('bookwellab_manage_appointments')) {
                    $bookwellab_capability = $this->bookwellab_capability();
                    foreach ($bookwellab_capability as $bookwellcap) {
                        $role->add_cap($bookwellcap);
                    }
                }

                \BookWellAB\BookWellAB_Adminmenu::init();
                add_filter('admin_body_class', [$this, 'bookwellab_admin_body_class']);
                add_action('admin_enqueue_scripts', [$this, 'admin_enqueue_assets'], 10);
                add_action('bookwellab_admin_html_file', [$this, 'bookwellab_admin_html_file_func']);
                add_action('bookwellab_admin_svg_image', [$this, 'bookwellab_admin_svg_image_func'], 10);
            }

        }

        // ... (skipping lines)

        public function bookwellab_capability()
        {
            $bookwellab_capability = [
                'bookwellab_manage_services',
                'bookwellab_manage_staff',
                'bookwellab_manage_customers',
                'bookwellab_manage_appointments',
                'bookwellab_manage_settings'
            ];
            return $bookwellab_capability;
        }

        public function bookwellab_admin_svg_image_func($type = '')
        {
            if ($type == 'loader') {
                ?>
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" width="127" height="127"
                    style="shape-rendering: auto; display: block; background: rgb(255, 255, 255);"
                    xmlns:xlink="http://www.w3.org/1999/xlink">
                    <g>
                        <circle stroke-linecap="round" fill="none" stroke-dasharray="34.55751918948772 34.55751918948772"
                            stroke="#000000" stroke-width="4" r="22" cy="50" cx="50">
                            <animateTransform values="0 50 50;360 50 50" keyTimes="0;1" dur="1.8867924528301885s"
                                repeatCount="indefinite" type="rotate" attributeName="transform"></animateTransform>
                        </circle>
                        <g></g>
                    </g>
                    <?php
            } else if ($type == 'up_position_arrow') {
                ?>
                        <svg fill="#000000" width="25px" height="25px" viewBox="0 0 24 24" id="up-arrow" data-name="Flat Color"
                            xmlns="http://www.w3.org/2000/svg" class="icon flat-color">
                            <path id="primary"
                                d="M15.71,5.29l-3-3a1,1,0,0,0-1.42,0l-3,3A1,1,0,0,0,9.71,6.71L11,5.41V21a1,1,0,0,0,2,0V5.41l1.29,1.3a1,1,0,0,0,1.42,0A1,1,0,0,0,15.71,5.29Z"
                                style="fill: rgb(0, 0, 0);"></path>
                        </svg>
                    <?php
            } else if ($type == 'down_position_arrow') {
                ?>
                            <svg fill="#000000" width="25px" height="25px" viewBox="0 0 24 24" id="down-arrow" data-name="Flat Color"
                                xmlns="http://www.w3.org/2000/svg" class="icon flat-color">
                                <path id="primary"
                                    d="M15.71,17.29a1,1,0,0,0-1.42,0L13,18.59V3a1,1,0,0,0-2,0V18.59l-1.29-1.3a1,1,0,0,0-1.42,1.42l3,3a1,1,0,0,0,1.42,0l3-3A1,1,0,0,0,15.71,17.29Z"
                                    style="fill: rgb(0, 0, 0);"></path>
                            </svg>
                    <?php
            }


        }

        public function bookwellab_admin_html_file_func()
        {
            $settings = \BookWellAB\BookWellAB_Settings::get_settings();
            $setup_completed = isset($settings['general']['setup_completed']) ? $settings['general']['setup_completed'] : false;

            if (!$setup_completed) {
                $settings_class = \BookWellAB\BookWellAB_Settings::get_instance();
                $defaults_data = $settings_class->get_defaults();
                
                // Ensure general defaults exist
                $general_defaults = isset($defaults_data['general']) ? $defaults_data['general'] : [];

                $bw_setup_data = [
                    'blog_name'   => get_bloginfo('name'),
                    'admin_name'  => wp_get_current_user()->display_name,
                    'admin_email' => wp_get_current_user()->user_email,
                    'currencies'  => \BookWellAB\BookWellAB_Settings::get_currencies(),
                    'countries'   => \BookWellAB\BookWellAB_Settings::get_countries_list(),
                    'phone_codes' => \BookWellAB\BookWellAB_Settings::get_phone_codes(),
                    'defaults'    => $general_defaults
                ];
                require_once BOOKWELLAB_HTML_PATH . 'setup_wizard_view.php';
            } else {
                require BOOKWELLAB_HTML_PATH . 'main_view.php';
            }
        }

        /**
         * Map a WordPress admin screen/hook ID to this plugin's menu page slug.
         *
         * @param string $hook_id e.g. toplevel_page_bookwell or bookwell_page_bookwell-calendar.
         * @return string Menu slug (e.g. bookwell, bookwell-calendar) or empty string.
         */
        private function menu_page_slug_from_admin_hook($hook_id)
        {
            if ('' === $hook_id || strpos($hook_id, 'bookwell') === false) {
                return '';
            }

            if ('toplevel_page_bookwell' === $hook_id) {
                return 'bookwell';
            }

            $prefix = 'bookwell_page_';
            if (0 === strpos($hook_id, $prefix)) {
                return substr($hook_id, strlen($prefix));
            }

            return '';
        }

        /**
         * Resolve the current BookWell admin menu page slug without relying on $_GET when possible.
         *
         * @param string $hook_suffix Optional value from admin_enqueue_scripts.
         * @return string Sanitized menu slug or empty string.
         */
        private function get_admin_menu_page_slug($hook_suffix = '')
        {
            if (!is_admin()) {
                return '';
            }

            if ('' !== $hook_suffix) {
                $slug = $this->menu_page_slug_from_admin_hook($hook_suffix);
                if ('' !== $slug) {
                    return $slug;
                }
            }

            if (function_exists('get_current_screen')) {
                $screen = get_current_screen();
                if ($screen && !empty($screen->id)) {
                    $slug = $this->menu_page_slug_from_admin_hook($screen->id);
                    if ('' !== $slug) {
                        return $slug;
                    }
                }
            }

            // Fallback when the screen object is not available yet (e.g. early init).
            global $plugin_page;
            if (!empty($plugin_page) && is_string($plugin_page)) {
                return sanitize_text_field($plugin_page);
            }

            $page = filter_input(INPUT_GET, 'page', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
            if (is_string($page) && '' !== $page) {
                return $page;
            }

            return '';
        }

        public function is_bookwell_admin_page($hook_suffix = '')
        {
            $current_page = $this->get_admin_menu_page_slug($hook_suffix);

            return ('' !== $current_page && strpos($current_page, 'bookwell') !== false);
        }

        /**
         * @param string $hook_suffix Optional value from admin_enqueue_scripts.
         * @return string Normalized page key (e.g. calendar, settings) or empty string.
         */
        public function get_bookwell_admin_page($hook_suffix = '')
        {
            $current_page = $this->get_admin_menu_page_slug($hook_suffix);

            if ('' !== $current_page && strpos($current_page, 'bookwell') !== false) {
                return str_replace('bookwell-', '', $current_page);
            }

            return '';
        }

        /**
         * Mark Bookwell admin screens for scoped premium shell styling.
         *
         * @param string $classes Admin body classes.
         * @return string
         */
        public function bookwellab_admin_body_class($classes)
        {
            $is_bookwell_screen = false;

            if (function_exists('get_current_screen')) {
                $screen = get_current_screen();
                if ($screen && isset($screen->id) && strpos((string) $screen->id, 'bookwell') !== false) {
                    $is_bookwell_screen = true;
                }
            }

            if (!$is_bookwell_screen) {
                // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Admin screen detection only.
                $page = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : '';
                if ($page !== '' && strpos($page, 'bookwell') !== false) {
                    $is_bookwell_screen = true;
                }
            }

            if ($is_bookwell_screen) {
                $classes .= ' bookwellab-admin-page';

                $settings = \BookWellAB\BookWellAB_Settings::get_settings();
                $setup_completed = isset($settings['general']['setup_completed']) ? $settings['general']['setup_completed'] : false;
                if (!$setup_completed) {
                    $classes .= ' bookwellab-setup-wizard-active';
                }
            }

            return $classes;
        }

        public function admin_enqueue_assets($hook_suffix)
        {

            if (strpos($hook_suffix, 'bookwell') === false) {
                return;
            }

            if ($this->is_bookwell_admin_page($hook_suffix)) {
                wp_enqueue_media();

                // Keep admin assets self-hosted for WordPress.org compliance.

                wp_register_style(
                    'bookwellab-admin-style',
                    plugin_dir_url(BOOKWELLAB_FILE) . 'assets/css/admin.css',
                    ['bookwellab-elements-style'],
                    BOOKWELLAB_VERSION
                );

                wp_register_style(
                    'bookwellab-elements-style',
                    plugin_dir_url(BOOKWELLAB_FILE) . 'assets/css/elements.css',
                    [],
                    BOOKWELLAB_VERSION
                );

                wp_register_style(
                    'bookwellab-wizard-style',
                    plugin_dir_url(BOOKWELLAB_FILE) . 'assets/css/wizard.css',
                    ['bookwellab-admin-popups-style'],
                    BOOKWELLAB_VERSION
                );

                wp_register_style(
                    'bookwellab-calendar-style',
                    plugin_dir_url(BOOKWELLAB_FILE) . 'assets/css/calendar.css',
                    [],
                    BOOKWELLAB_VERSION
                );

                wp_enqueue_style('bookwellab-admin-style');
                wp_enqueue_style('bookwellab-elements-style');
                wp_enqueue_style('bookwellab-calendar-style');
                if (is_rtl()) {
                    wp_register_style(
                        'bookwellab-admin-rtl-style',
                        plugin_dir_url(BOOKWELLAB_FILE) . 'assets/css/admin-rtl.css',
                        ['bookwellab-admin-style'],
                        BOOKWELLAB_VERSION
                    );
                    wp_enqueue_style('bookwellab-admin-rtl-style');
                }
                $this->enqueue_admin_popup_font_assets();

                wp_add_inline_style(
                    'bookwellab-admin-style',
                    'body.bookwellab-admin-page #wpcontent,body.bookwellab-admin-page #wpbody,body.bookwellab-admin-page #wpbody-content{background:#f6f5fa!important;}body.bookwellab-admin-page .bookwellab_page_main,body.bookwellab-admin-page #bookwellab_root_app,body.bookwellab-admin-page .bookwellab_page_wrapper,body.bookwellab-admin-page .book-now-adm--container{background:#f6f5fa!important;}'
                );

                $settings = \BookWellAB\BookWellAB_Settings::get_settings();
                $setup_completed = isset($settings['general']['setup_completed']) ? $settings['general']['setup_completed'] : false;

                wp_register_script(
                    'bookwellab-vue-script',
                    plugin_dir_url(BOOKWELLAB_FILE) . 'assets/js/vue.cjs.min.js',
                    [],
                    BOOKWELLAB_VERSION,
                    true
                );

                wp_register_script(
                    'bookwellab-elements-plus-script',
                    plugin_dir_url(BOOKWELLAB_FILE) . 'assets/js/elements-plus.js',
                    ['bookwellab-vue-script'],
                    BOOKWELLAB_VERSION,
                    true
                );
                wp_register_script('bookwellab-axios-script', plugin_dir_url(BOOKWELLAB_FILE) . 'assets/js/axios.min.js', [], BOOKWELLAB_VERSION, true);
                wp_register_script('bookwellab-qs-script', plugin_dir_url(BOOKWELLAB_FILE) . 'assets/js/qs.min.js', [], BOOKWELLAB_VERSION, true);
                wp_register_script('bookwellab-icons-script', plugin_dir_url(BOOKWELLAB_FILE) . 'assets/js/element-plus-icons.iife.min.js', ['bookwellab-vue-script'], BOOKWELLAB_VERSION, true);

                wp_localize_script(
                    'bookwellab-vue-script',
                    'bookwellab_ajax_obj',
                    ['ajax_url' => admin_url('admin-ajax.php'), 'bookwellab_nonce' => esc_html(wp_create_nonce('bw_wp_nonce'))]
                );

                wp_enqueue_script('bookwellab-vue-script');
                wp_enqueue_script('bookwellab-elements-plus-script');
                wp_enqueue_script('bookwellab-icons-script');

                if (!$setup_completed) {
                    wp_enqueue_style('bookwellab-wizard-style');
                    wp_register_script(
                        'bookwellab-setup-wizard-script',
                        plugin_dir_url(BOOKWELLAB_FILE) . 'assets/js/setup-wizard.js',
                        ['bookwellab-vue-script', 'bookwellab-elements-plus-script', 'bookwellab-icons-script'],
                        BOOKWELLAB_VERSION,
                        true
                    );

                    $setup_wizard_data = \BookWellAB\BookWellAB_Setup::get_setup_wizard_data();
                    $setup_wizard_ui = \BookWellAB\BookWellAB_Setup::get_setup_wizard_i18n();
                    $setup_wizard_script_data = [
                        'ui' => $setup_wizard_ui,
                        'i18n' => [
                            'company_required' => esc_html__('Company name and phone are required.', 'bookwellnow-appointment-booking'),
                            'service_required' => esc_html__('Please fill all required service fields.', 'bookwellnow-appointment-booking'),
                            'staff_required' => esc_html__('Name and email are required.', 'bookwellnow-appointment-booking'),
                            'success' => esc_html__('Success', 'bookwellnow-appointment-booking'),
                            'setup_failed' => esc_html__('Setup failed.', 'bookwellnow-appointment-booking'),
                            'server_error' => esc_html__('Server error occurred.', 'bookwellnow-appointment-booking'),
                            'skip_setup_msg' => esc_html__('Are you sure you want to skip the setup? You will need to configure your services and staff manually.', 'bookwellnow-appointment-booking'),
                            'skip_setup_title' => esc_html__('Skip Setup', 'bookwellnow-appointment-booking'),
                            'yes_skip' => esc_html__('Yes, Skip', 'bookwellnow-appointment-booking'),
                            'cancel' => esc_html__('Cancel', 'bookwellnow-appointment-booking'),
                        ],
                        'days' => [
                            'monday' => esc_html__('Monday', 'bookwellnow-appointment-booking'),
                            'tuesday' => esc_html__('Tuesday', 'bookwellnow-appointment-booking'),
                            'wednesday' => esc_html__('Wednesday', 'bookwellnow-appointment-booking'),
                            'thursday' => esc_html__('Thursday', 'bookwellnow-appointment-booking'),
                            'friday' => esc_html__('Friday', 'bookwellnow-appointment-booking'),
                            'saturday' => esc_html__('Saturday', 'bookwellnow-appointment-booking'),
                            'sunday' => esc_html__('Sunday', 'bookwellnow-appointment-booking'),
                        ],
                        'nonce' => wp_create_nonce('bw_wp_nonce'),
                        'defaults' => [
                            'blog_name' => isset($setup_wizard_data['blog_name']) ? $setup_wizard_data['blog_name'] : '',
                            'admin_name' => isset($setup_wizard_data['admin_name']) ? $setup_wizard_data['admin_name'] : '',
                            'admin_email' => isset($setup_wizard_data['admin_email']) ? $setup_wizard_data['admin_email'] : '',
                            'currencies' => isset($setup_wizard_data['currencies']) ? $setup_wizard_data['currencies'] : [],
                            'countries' => isset($setup_wizard_data['countries']) ? $setup_wizard_data['countries'] : [],
                            'phone_codes' => isset($setup_wizard_data['phone_codes']) ? $setup_wizard_data['phone_codes'] : [],
                            'general' => isset($setup_wizard_data['defaults']) ? $setup_wizard_data['defaults'] : [],
                        ],
                    ];

                    $setup_wizard_json = wp_json_encode(bookwellab_ensure_utf8($setup_wizard_script_data));
                    if (false === $setup_wizard_json) {
                        $setup_wizard_json = '{}';
                    }

                    wp_add_inline_script(
                        'bookwellab-setup-wizard-script',
                        'window.bookwellabSetupWizardData = ' . $setup_wizard_json . ';',
                        'before'
                    );
                    wp_enqueue_script('bookwellab-setup-wizard-script');
                } else {
                    wp_enqueue_script('bookwellab-axios-script');
                    wp_enqueue_script('bookwellab-qs-script');
                    wp_enqueue_script('bookwellab-sortable-script', plugin_dir_url(BOOKWELLAB_FILE) . 'assets/js/sortable.min.js', [], BOOKWELLAB_VERSION, true);

                    $bookwell_page = $this->get_bookwell_admin_page($hook_suffix);
                    $this->localize_bookwell_admin_script_data($bookwell_page);
                    $bookwell_script_data = $this->get_bookwell_admin_app_bootstrap_script($bookwell_page);

                    // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Contains dynamic JavaScript bootstrapper generated by the plugin.
                    wp_add_inline_script('bookwellab-elements-plus-script', $bookwell_script_data, 'after');

                    do_action('bookwellab_add_extra_admin_assets');
                }

            }


        }

        /**
         * Build admin Vue app data array (settings, locale, RTL, etc.).
         *
         * @param string $bookwell_page Current admin page slug.
         * @return array<string, mixed>
         */
        private function build_bookwell_admin_script_data($bookwell_page)
        {
            $bookwellab_admin_script_vriable_data = array();

            $settings = \BookWellAB\BookWellAB_Settings::get_settings();
            $bookwellab_admin_script_vriable_data['date_format'] = isset($settings['general']['date_format']) ? $settings['general']['date_format'] : 'Y-m-d';
            $bookwellab_admin_script_vriable_data['time_format'] = isset($settings['general']['time_format']) ? $settings['general']['time_format'] : 'H:i';
            $bookwellab_admin_script_vriable_data['week_starts_on'] = \BookWellAB\BookWellAB_Settings::get_week_starts_on($settings);
            // Element Plus: 1=Monday … 7=Sunday
            $week_starts_on = (int) $bookwellab_admin_script_vriable_data['week_starts_on'];
            $bookwellab_admin_script_vriable_data['el_first_day_of_week'] = $week_starts_on === 0 ? 7 : $week_starts_on;

            $currency_code = isset($settings['general']['currency_code']) ? $settings['general']['currency_code'] : 'USD';
            $currencies = \BookWellAB\BookWellAB_Settings::get_currencies();
            $currency_symbol = isset($currencies[$currency_code]) ? $currencies[$currency_code]['symbol'] : '$';

            if (!isset($settings['general'])) {
                $settings['general'] = array();
            }
            $settings['general']['currency_symbol'] = $currency_symbol;

            $bookwellab_admin_script_vriable_data['settings_data'] = $settings;
            $bookwellab_admin_script_vriable_data['is_rtl'] = is_rtl();
            $bookwellab_admin_script_vriable_data['drawer_direction'] = is_rtl() ? 'ltr' : 'rtl';
            $bookwellab_admin_script_vriable_data['calendar_locale'] = str_replace('_', '-', determine_locale());
            $bookwellab_admin_script_vriable_data['pagination_pager_count'] = 5;

            return apply_filters('bookwellab_admin_script_vriable_data', $bookwellab_admin_script_vriable_data, $bookwell_page);
        }

        /**
         * Output admin app data as JSON on the Vue handle (safe for script context; preserves booleans).
         *
         * @param string $bookwell_page Current admin page slug.
         * @return void
         */
        public function localize_bookwell_admin_script_data($bookwell_page)
        {
            $script_data = bookwellab_ensure_utf8($this->build_bookwell_admin_script_data($bookwell_page));
            $script_json = wp_json_encode($script_data);

            if (false === $script_json) {
                $script_json = '{}';
            }

            wp_add_inline_script(
                'bookwellab-vue-script',
                'window.bookwellab_admin_script_vriable_data = ' . $script_json . ';',
                'before'
            );
        }

        /**
         * Vue admin app bootstrap (mount only). Data is localized via localize_bookwell_admin_script_data().
         *
         * Page method/mounted blocks are admin-capability-gated plugin-generated JS from PHP templates.
         *
         * @param string $bookwell_page Current admin page slug.
         * @return string
         */
        public function get_bookwell_admin_app_bootstrap_script($bookwell_page)
        {
            $bookwellab_admin_script_define_data = apply_filters('bookwellab_admin_script_define_data', '', $bookwell_page);
            $bookwellab_define_script_vriable_data = apply_filters('bookwellab_define_script_vriable_data', '', $bookwell_page);
            $bookwellab_page_method_data = apply_filters('bookwellab_page_method_data', '', $bookwell_page);
            $bookwellab_page_mounted_data = apply_filters('bookwellab_page_mounted_data', '', $bookwell_page);

            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Static admin-only Vue bootstrap; page hooks are plugin PHP strings gated by capability.
            return '
                const { onMounted, onUpdated, onUnmounted, ref, reactive, getCurrentInstance, createApp } = Vue;
                var bookwellabp;
                window.addEventListener("DOMContentLoaded", function() {
                    bookwellabp = createApp({
                        data(){
                            ' . $bookwellab_define_script_vriable_data . '
                            const appData = Object.assign({}, window.bookwellab_admin_script_vriable_data || {});
                            Object.keys(appData).forEach(function(key){
                                if(!/(^bw_.*_popup$|_drawer$|_dialog_visible$|_visible$)/.test(key)){
                                    return;
                                }
                                const value = appData[key];
                                if(value === true || value === 1 || value === "1" || value === "true"){
                                    appData[key] = true;
                                    return;
                                }
                                if(value === false || value === 0 || value === "0" || value === "false" || value === "" || value === null || typeof value === "undefined"){
                                    appData[key] = false;
                                }
                            });
                            appData.bw_add_edit_popup = false;
                            appData.bw_list_loader = "0";
                            ' . $bookwellab_admin_script_define_data . '
                            return appData;
                        },
                        beforeCreate(){

                        },
                        created(){

                        },
                        mounted(){
                            ' . $bookwellab_page_mounted_data . '
                        },
                        computed:{

                        },
                        methods: {
                          ' . $bookwellab_page_method_data . '
                        }
                    });
                    bookwellabp.use(ElementPlus);
                    if (document.querySelector("#bookwellab_root_app")) {
                        bookwellabp.mount("#bookwellab_root_app");
                    }
                });
            ';
        }

        /**
         * @deprecated Use localize_bookwell_admin_script_data() and get_bookwell_admin_app_bootstrap_script().
         *
         * @param string $bookwell_page Current admin page slug.
         * @return string
         */
        public function get_bookwell_admin_script($bookwell_page)
        {
            $this->localize_bookwell_admin_script_data($bookwell_page);

            return $this->get_bookwell_admin_app_bootstrap_script($bookwell_page);
        }



        /**
         * Backend admin font is fixed to bundled local Poppins (not frontend font setting).
         */
        private function enqueue_admin_popup_font_assets()
        {
            wp_enqueue_style(
                'bookwellab-admin-font',
                plugin_dir_url(BOOKWELLAB_FILE) . 'assets/css/admin-fonts.css',
                [],
                BOOKWELLAB_VERSION
            );

            $font_stack = "'Poppins', Arial, Helvetica, sans-serif";

            wp_register_style(
                'bookwellab-admin-popups-style',
                plugin_dir_url(BOOKWELLAB_FILE) . 'assets/css/admin-popups.css',
                ['bookwellab-elements-style', 'bookwellab-admin-font'],
                BOOKWELLAB_VERSION
            );
            wp_enqueue_style('bookwellab-admin-popups-style');

            wp_add_inline_style(
                'bookwellab-admin-popups-style',
                'body.bookwellab-admin-page{--bw-admin-font:' . $font_stack . ';--bw-popup-font:var(--bw-admin-font);--bw-drawer-font:var(--bw-admin-font);}'
            );
        }

        public function maybe_upgrade_database()
        {
            $installed_version = \BookWellAB\BookWellAB_Database::get_db_store_option('db_version', '');

            if (version_compare((string) $installed_version, BOOKWELLAB_VERSION, '<')) {
                $this->bwdb->add_missing_columns();
                $this->update_db_latest();
            }

            $this->maybe_flush_plugin_caches_on_version_change();
        }

        /**
         * Flush plugin transients/object cache once per plugin version bump.
         *
         * @return void
         */
        private function maybe_flush_plugin_caches_on_version_change()
        {
            $stored = \BookWellAB\BookWellAB_Database::get_db_store_option('assets_cache_version', '');
            if ((string) $stored === BOOKWELLAB_VERSION) {
                return;
            }

            \BookWellAB\BookWellAB_Frontend::flush_upgrade_caches();
            \BookWellAB\BookWellAB_Database::update_db_store_option('assets_cache_version', BOOKWELLAB_VERSION);
        }

        /**
         * Run version upgrades from a dedicated update file (AffiliatePress-like flow).
         *
         * @return void
         */
        public function update_db_latest()
        {
            $upgrade_file = BOOKWELLAB_INCLUDES_PATH . 'views/update_db_store.php';
            if (is_readable($upgrade_file)) {
                include $upgrade_file;
                return;
            }

            // Fallback: ensure baseline tables/version remain valid if file is missing.
            $this->bwdb->install_tables();
            \BookWellAB\BookWellAB_Database::update_db_store_option('db_version', BOOKWELLAB_VERSION);
        }

    }

}

class BookWellAB_Permissions
{
    public static function has_permission($capability)
    {
        return current_user_can($capability);
    }
}