<?php
/*
Plugin Name:  Gocars Online
Plugin URI:   https://github.com/go-creations/gocars-online.git
Description:  Gocars Online is a Car Rental Booking System
Author:       Alexis Tarantos
Author URI:   https://gocars.online
Text Domain:  gocars
Version:      2.5.7
*/
 
if (!defined('ABSPATH')) {
    exit;
}

// Load configuration helper
require_once plugin_dir_path(__FILE__) . 'inc/gocars-config.php';
 
/**
 * @package GocarsOnline
 */
if ( !class_exists( 'GocarsOnline' ) ) {

    class GocarsOnline {

        public $plugin;
        private $config;

        public function __construct() {

            // Initialize configuration
            $this->config = GocarsConfig::get_instance();
            
            // Check if plugin is properly configured
            if (!$this->config->is_configured() && is_admin()) {
                add_action('admin_notices', array($this, 'configuration_notice'));
            }

            $this->plugin = plugin_basename( __FILE__ );

            //Gocars Post Type
            add_action( 'init', array( $this,'gocars_shortcode_register_post_type' ) );

            //Gocars Shortcode Generate
            add_action( 'init', array( $this,'gocars_shortcode_generate' ) );

            //Load Style
            add_action( 'wp_head', array( $this, 'load_style' ) );

            //Load JS
            add_action( 'wp_footer', array( $this, 'load_scripts' ) );

            add_action('template_redirect', array( $this, 'redirect_to_homepage' ) );

            // Hook to handle update check via URL parameter
            add_action('init', array($this, 'handle_update_check'));

        }

        function register() {

            add_action( 'wp_enqueue_scripts', array( $this, 'enqueue' ) );

            add_action( 'wp_enqueue_scripts', array( $this, 'add_shortcode_assets' ) );

            add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue' ) );

            add_action( 'admin_menu', array( $this, 'add_admin_pages' ) );

            add_action( 'post_submitbox_misc_actions', array( $this, 'custom_publish_box' ) );

            add_filter('parent_file', array( $this,'activate_custom_menu_item' ));

            add_filter( "plugin_action_links_$this->plugin", array( $this, 'settings_link' ) );

            add_action( 'admin_head', array( $this,'custom_dashboard_items') ); 

            // advanced settings
            add_action( 'admin_init',   array( $this, 'display_advanced_settings') );
            
            // head scripts
            add_action( 'wp_head',  array( $this,'wp_head_scripts') );

            // Cookie consent — Consent Mode v2 defaults (must be before GTM)
            add_action( 'wp_head',  array( $this, 'cookie_consent_head' ), 1 );
                  
            // body scripts
            add_action( 'wp_body_open',  array( $this,'wp_body_scripts') ); // after body ensure funtion wp_body_open() exists

            //footer scripts
            add_action( 'wp_footer',  array( $this,'wp_footer_scripts') );

            // Cookie consent — banner init config (after all other footer scripts)
            add_action( 'wp_footer',  array( $this, 'cookie_consent_footer' ), 100 );

            // Load Functions
            add_action( 'init', array( $this, 'load_functions' ) );
            // add_action( 'admin_init', array( $this, 'load_functions' ) );

            // advanced css
            add_action( 'wp_head',  array( $this,'wp_advanced_css') );

            add_action( 'add_meta_boxes', array( $this,'gocars_shortcode_meta' ) );

            add_filter( 'save_post', array( $this, 'save_gocars_shortcode_meta' ) );

            add_action( 'wp_ajax_gocars_refresh_shortcode_cache', array( $this, 'ajax_refresh_shortcode_cache' ) );

        }

        public function add_admin_pages() {
            add_menu_page( 'Gocars Online', 'Gocars Online', 'manage_options', 'gocars_online', array( $this, 'gocars_admin' ), plugin_dir_url( __FILE__ ) . 'assets/images/gocars-logo.png' , null);
            
            // Add Settings page
            add_submenu_page( 
                'gocars_online', 
                'Gocars Settings', 
                'Settings', 
                'manage_options', 
                'gocars_settings', 
                array( $this, 'gocars_settings_page' ) 
            );
            
            add_submenu_page( 'gocars_online', 'Gocars Online Advanced Settings', 'Advanced', 'manage_options', 'gocars_online_advanced', array( $this, 'admin_advanced_settings' ) );
        }
        
        function display_advanced_settings() {

            // Advanced fields
            add_settings_section('head_scripts', null, 'display_head_scripts', 'gocars_online_advanced','advanced_options');
            add_settings_section('body_scripts', null, 'display_body_scripts', 'gocars_online_advanced','advanced_options');
            add_settings_section('footer_scripts', null, 'display_footer_scripts', 'gocars_online_advanced','advanced_options');
            add_settings_section('advanced_css', null, 'display_advanced_css', 'gocars_online_advanced','advanced_options');
            register_setting('advanced_options', 'head_scripts');
            register_setting('advanced_options', 'body_scripts');
            register_setting('advanced_options', 'footer_scripts');
            register_setting('advanced_options', 'advanced_css');
        }

        function activate_custom_menu_item($parent_file) {
            global $post;
        
            $post_types = array('gocars_db', 'gocars_shortcode');
        
            if ($post != null && in_array($post->post_type, $post_types)) {
                $parent_file = 'gocars_online';
            }
        
            return $parent_file;
        }

        public function gocars_admin() {
            require_once plugin_dir_path( __FILE__ ) . 'admin/admin.php';
        }

        // advanced
        public function admin_advanced_settings() {
            require_once plugin_dir_path( __FILE__ ) . 'admin/advanced.php';
        }
     
        // settings page
        public function gocars_settings_page() {
            require_once plugin_dir_path( __FILE__ ) . 'admin/settings.php';
        }
     
        // settings
        public function settings_link( $links ) {
            $settings_link = '<a href="admin.php?page=gocars_online">Settings</a>';
            array_push( $links, $settings_link);
            return $links;
        }

        // Custom Style On Dashboard
        function custom_dashboard_items() {
            echo '
            <style>
                .toplevel_page_gocars_online img {
                    width: 20px;
                    height: 16px;
                    object-fit: contain;
                }
            </style>';
        }

        function enqueue() {

            // CSS
            wp_enqueue_style( 'gocars-online', plugin_dir_url( __FILE__ ) . 'css/style.css', array(), time(), 'all'); 
           
            // JS
            wp_enqueue_script( 'gocars-online-js', plugin_dir_url( __FILE__ ) . 'js/script.js', array ('jquery'), time(), true);

            // AJAX
            wp_localize_script('gocars-online-js', 'gocars_ajax', array(
                'ajax_url'              => admin_url('admin-ajax.php'),
                'nonce'                 => wp_create_nonce('update_post_meta_nonce'),
                'utm_tracking_enabled'  => get_option('gocars_utm_tracking_enabled', '1'),
                'cookie_banner_enabled' => get_option('gocars_cookie_banner_enabled', '0'),
            ));

            // Cookie consent banner assets — loaded in <head> so the class is available before footer init
            if (get_option('gocars_cookie_banner_enabled', '0') === '1') {
                wp_enqueue_style('gocars-consent-css',
                    plugin_dir_url(__FILE__) . 'css/consent-manager.css', [], time(), 'all');
                wp_enqueue_script('gocars-consent-js',
                    plugin_dir_url(__FILE__) . 'js/consent-manager.js', [], time(), false);
            }

        }

        public function ajax_refresh_shortcode_cache() {
            check_ajax_referer( 'gocars_refresh_cache', 'nonce' );
            if ( ! current_user_can( 'manage_options' ) ) {
                wp_send_json_error( array( 'message' => 'Forbidden' ) );
            }
            $post_id = isset( $_POST['post_id'] ) ? (int) $_POST['post_id'] : 0;
            if ( ! $post_id || get_post_type( $post_id ) !== 'gocars_shortcode' ) {
                wp_send_json_error( array( 'message' => 'Invalid shortcode' ) );
            }
            $functions_rel = plugin_dir_path( __FILE__ ) . 'functions.php';
            if ( file_exists( $functions_rel ) ) {
                require_once $functions_rel;
            }
            if ( function_exists( 'gocars_flush_gocars_http_cache' ) ) {
                gocars_flush_gocars_http_cache();
            }
            self::update_fields( $post_id, null );
            wp_send_json_success( array( 'message' => 'Cache refreshed.' ) );
        }

        function admin_enqueue( $hook_suffix = '' ) {

            wp_enqueue_script( 'jquery' );
            wp_enqueue_script( 'jquery-ui-tabs' );
            
            // CSS
            wp_enqueue_style( 'gocars-online-css', plugin_dir_url( __FILE__ ) . 'css/style.css', array(), time(), 'all'); 
            // JS
            wp_enqueue_script( 'gocars-online-admin', plugin_dir_url( __FILE__ ) . 'js/admin.js', array ('jquery'), time(), true);

            global $post;
            if ( ( $hook_suffix === 'post.php' || $hook_suffix === 'post-new.php' ) && $post && $post->post_type === 'gocars_shortcode' ) {
                wp_localize_script(
                    'gocars-online-admin',
                    'gocarsAdminSync',
                    array(
                        'ajax_url' => admin_url( 'admin-ajax.php' ),
                        'nonce'    => wp_create_nonce( 'gocars_refresh_cache' ),
                        'post_id'  => (int) $post->ID,
                        'strings'  => array(
                            'refresh_idle' => __( 'Rebuild cached booking data from the Gocars API (recommended after backend changes).', 'gocars' ),
                            'refresh_working' => __( 'Refreshing…', 'gocars' ),
                            'refresh_done' => __( 'Done. Reload the page if dropdowns look stale.', 'gocars' ),
                            'refresh_fail' => __( 'Could not refresh. Check your domain and API access.', 'gocars' ),
                        ),
                    )
                );
            }

        }


        //-------------------------------------------------------------

        function add_shortcode_assets() {
            $locale = get_locale();
            
            // jQuery-ui CSS
        	wp_enqueue_style( 'jquery-ui-style', '//code.jquery.com/ui/1.13.1/themes/smoothness/jquery-ui.min.css', array(), '1.0.0', 'all');

        	// jQuery-ui JS
        	wp_enqueue_script( 'jquery-ui-js', '//code.jquery.com/ui/1.13.1/jquery-ui.min.js', array (), array (), '1.0', true);

            // Select2 CSS
            wp_enqueue_style( 'select2-css', 'https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css', array(), '1.0.0', 'all');

            // Select2 JS
            wp_enqueue_script( 'select2-js', 'https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js', array (), '1.0', true);

            // Slider CSS
            wp_enqueue_style( 'slider-css', '//cdn.jsdelivr.net/npm/swiper@11.1.1/swiper-bundle.min.css',  array(), '1.0.1', 'all');

            // Slider JS
            wp_enqueue_script( 'slider-js', '//cdn.jsdelivr.net/npm/swiper@11.1.1/swiper-bundle.min.js', array (), '1.1', true);

            // CSS
            wp_enqueue_style( 'mobiscroll-css', plugin_dir_url( __FILE__ ) . 'assets/mobiscroll/mobiscroll.jquery.css', array(), time(), 'all');

            // Timepicker CSS
            wp_enqueue_style( 'timepicker-css', plugin_dir_url( __FILE__ ) . 'assets/timepicker/timepicker.css', array(), time(), 'all');

            // Timepicker JS
        	wp_enqueue_script( 'timepicker-js', plugin_dir_url( __FILE__ ) . 'assets/timepicker/timepicker.js', array (), time(), true);

        	// Enqueue the localized Datepicker script based on the current locale
            if ( $locale == 'gr' || $locale == 'el') {
                // JS Datepicker UI EL
                wp_enqueue_script( 'datepicker-el-js', plugin_dir_url( __FILE__ ) . 'assets/language/datepicker-el.js', array( 'jquery-ui-datepicker' ), time(), true );
                // JS Mobiscroll Locale EL
                wp_enqueue_script( 'mobiscroll-el-js', plugin_dir_url( __FILE__ ) . 'assets/mobiscroll/mobiscroll-el.jquery.js', array (), time(), true);
            } elseif ( $locale == 'de') {
                //JS Datepicker UI DE
                wp_enqueue_script( 'datepicker-de-js', plugin_dir_url( __FILE__ ) . 'assets/language/datepicker-de.js', array( 'jquery-ui-datepicker' ), time(), true );
                // JS Mobiscroll Locale DE
                wp_enqueue_script( 'mobiscroll-de-js', plugin_dir_url( __FILE__ ) . 'assets/mobiscroll/mobiscroll-de.jquery.js', array (), time(), true);
            } elseif ( $locale == 'it') {
                // JS Datepicker UI IT
                wp_enqueue_script( 'datepicker-it-js', plugin_dir_url( __FILE__ ) . 'assets/language/datepicker-it.js', array( 'jquery-ui-datepicker' ), time(), true );
                // JS Mobiscroll Locale IT
                wp_enqueue_script( 'mobiscroll-it-js', plugin_dir_url( __FILE__ ) . 'assets/mobiscroll/mobiscroll-it.jquery.js', array (), time(), true);
            } else {
                // JS Datepicker UI EN
                wp_enqueue_script( 'datepicker-en-js', plugin_dir_url( __FILE__ ) . 'assets/language/datepicker-en.js', array( 'jquery-ui-datepicker' ), time(), true );
                // JS Mobiscroll Locale EN
                wp_enqueue_script( 'mobiscroll-js', plugin_dir_url( __FILE__ ) . 'assets/mobiscroll/mobiscroll.jquery.js', array (), time(), true);
            }

        }

        //-------------------------------------------------------------

        

        function custom_publish_box() {
            global $post;
            
            // Check if this is your custom post type
            if ($post->post_type === 'gocars_shortcode' || $post->post_type === 'gocars_db') {
                ?>
                <style>
                    #minor-publishing,
                    #icl_minor_change_box {
                        display: none;
                    }
                </style>
                <?php
            }
        }


        //-------------------------------------------------------------



        // REGISTER POST TYPES START

        //-------------------------------------------------------------

        function gocars_shortcode_register_post_type() {

            $args = array(
                'public' => true,
                'show_in_menu' => false,
                'hierarchical' => true,
                'supports' => array( 'title'),
                'publicly_queryable' => false,
                'label' => 'Gocars Online',
                'labels' => array(
                    'name' => __( 'Gocars Shortcodes','gocars' ),
                    'menu_name' => __( 'Gocars Online','gocars' ),
                    'singular_name' =>__( 'Gocars Shortcode','gocars' ),
                    'all_items' => __( 'All Gocars Shortcodes', 'gocars' ),
                    'view_item' => __( 'View Shortcode', 'gocars' ),
                    'add_new_item' => __( 'Add New Shortcode', 'gocars' ),
                    'edit_item' => __( 'Edit Shortcode', 'gocars' ),
                    'update_item' => __( 'Update Shortcode', 'gocars' ),
                ),
            );
            register_post_type( 'gocars_shortcode', $args );

        }

        //-------------------------------------------------------------


        // REGISTER POST TYPES ENDS


        function configuration_notice() {

            

        }




        // SHORTCODE FIELDS START


        // Add custom meta box to the single shortcode edit screen
        function gocars_shortcode_meta() {
            add_meta_box(
                'gocars_shortcode_meta',
                'Gocars Online Settings',
                array( $this, 'gocars_shortcode_meta_callback'),
                'gocars_shortcode',
                'normal',
                'high'
            );
        }

        //-------------------------------------------------------------


        // Callback function for the custom meta box
        function gocars_shortcode_meta_callback( $post ) {
            if ( $post && (int) $post->ID > 0 ) {
                echo '<div class="gocars-remote-refresh-toolbar" style="margin: .5rem 0 1rem;order: 1;">';
                echo '<button type="button" class="button button-secondary" id="gocars-refresh-remote-cache">' . esc_html__( 'Refresh data from Gocars API', 'gocars' ) . '</button> ';
                echo '<p class="description" id="gocars-refresh-remote-cache-status">' . esc_html__( 'Uses saved shortcode credentials; avoids loading the edit screen repeatedly against the remote API.', 'gocars' ) . '</p>';
                echo '</div>';
            }
            require_once plugin_dir_path( __FILE__ ) . 'admin/fields/search_form_fields.php';
            
            require_once plugin_dir_path( __FILE__ ) . 'admin/fields/fleet_fields.php';
                    
            require_once plugin_dir_path( __FILE__ ) . 'admin/fields/admin_fields.php';
           

        }


        //-------------------------------------------------------------


        // Save the values of the custom fields when the post is updated
        public function save_gocars_shortcode_meta( $post_id ) {
            
            // Check if the current user is authorized to edit the post
            if ( ! current_user_can( 'manage_options', $post_id ) ) {
                return;
            }

            // Make sure that the correct post type is being saved
            if ( get_post_type( $post_id ) !== 'gocars_shortcode' ) {
                return;
            }
             
            // Save the values of the custom fields
            

            // fleet fields
            if ( isset( $_POST['fleet_number'] ) ) {
                update_post_meta( $post_id, 'fleet_number', sanitize_text_field( $_POST['fleet_number'] ) );
            }
            if ( isset( $_POST['fleet_type'] ) ) {
                update_post_meta( $post_id, 'fleet_type', sanitize_text_field( $_POST['fleet_type'] ) );
            }
            if ( isset( $_POST['vehicle_type'] ) ) {
                update_post_meta( $post_id, 'vehicle_type', sanitize_text_field( $_POST['vehicle_type'] ) );
            }
            if ( isset( $_POST['fleet_sorting'] ) ) {
                update_post_meta( $post_id, 'fleet_sorting', sanitize_text_field( $_POST['fleet_sorting'] ) );
            }
            if ( isset( $_POST['display_selected_vehicles'] ) ) {
                update_post_meta( $post_id, 'display_selected_vehicles', sanitize_text_field( $_POST['display_selected_vehicles'] ) );
            }
            if ( isset( $_POST['selected_vehicles'] ) ) {
                $selected_vehicles = array_map('sanitize_text_field', $_POST['selected_vehicles']);
                $selected_vehicles = implode(',', $selected_vehicles);
                update_post_meta($post_id, 'selected_vehicles', $selected_vehicles);
            }
            if ( isset( $_POST['car_info_display'] ) ) {
                $car_info_display = array_map('sanitize_text_field', $_POST['car_info_display']);
                $car_info_display = implode(',', $car_info_display);
                update_post_meta($post_id, 'car_info_display', $car_info_display);
            }
            if ( isset( $_POST['car_features'] ) ) {
                $car_features = array_map('sanitize_text_field', $_POST['car_features']);
                $car_features = implode(',', $car_features);
                update_post_meta($post_id, 'car_features', $car_features);
            }
            if ( isset( $_POST['fleet_wrap_classes'] ) ) {
                update_post_meta( $post_id, 'fleet_wrap_classes', sanitize_text_field( $_POST['fleet_wrap_classes'] ) );
            }
            if ( isset( $_POST['single_fleet_classes'] ) ) {
                update_post_meta( $post_id, 'single_fleet_classes', sanitize_text_field( $_POST['single_fleet_classes'] ) );
            }
            if ( isset( $_POST['button_text'] ) ) {
                update_post_meta( $post_id, 'button_text', sanitize_text_field( $_POST['button_text'] ) );
            }
            if ( isset( $_POST['price_text'] ) ) {
                update_post_meta( $post_id, 'price_text', sanitize_text_field( $_POST['price_text'] ) );
            }
            if ( isset( $_POST['button_classes'] ) ) {
                update_post_meta( $post_id, 'button_classes', sanitize_text_field( $_POST['button_classes'] ) );
            }
            if ( isset( $_POST['basic_style'] ) ) {
                update_post_meta( $post_id, 'basic_style', sanitize_text_field( $_POST['basic_style'] ) );
            }
            if ( isset( $_POST['display_elements_wrapper'] ) ) {
                update_post_meta( $post_id, 'display_elements_wrapper', sanitize_text_field( $_POST['display_elements_wrapper'] ) );
            }
            if ( isset( $_POST['elements_wrapper_data'] ) ) {
                update_post_meta( $post_id, 'elements_wrapper_data', sanitize_text_field( $_POST['elements_wrapper_data'] ) );
            }

            //search form 
            if ( isset( $_POST['form_display'] ) ) {
                update_post_meta( $post_id, 'form_display', sanitize_text_field( $_POST['form_display'] ) );
            }
            if ( isset( $_POST['vehicle_display'] ) ) {
                update_post_meta( $post_id, 'vehicle_display', sanitize_text_field( $_POST['vehicle_display'] ) );
            }
            if ( isset( $_POST['vehicle_type_border'] ) ) {
                update_post_meta( $post_id, 'vehicle_type_border', sanitize_text_field( $_POST['vehicle_type_border'] ) );
            }
            


            if ( isset( $_POST['header_text_color'] ) ) {
                update_post_meta( $post_id, 'header_text_color', sanitize_text_field( $_POST['header_text_color'] ) );
            }
            if ( isset( $_POST['header_background_color'] ) ) {
                update_post_meta( $post_id, 'header_background_color', sanitize_text_field( $_POST['header_background_color'] ) );
            }
            if ( isset( $_POST['header_text_content'] ) ) {
                update_post_meta( $post_id, 'header_text_content', sanitize_text_field( $_POST['header_text_content'] ) );
            }


            if ( isset( $_POST['body_text_color'] ) ) {
                update_post_meta( $post_id, 'body_text_color', sanitize_text_field( $_POST['body_text_color'] ) );
            }
            if ( isset( $_POST['body_background_color'] ) ) {
                update_post_meta( $post_id, 'body_background_color', sanitize_text_field( $_POST['body_background_color'] ) );
            }
            if ( isset( $_POST['search_text'] ) ) {
                update_post_meta( $post_id, 'search_text', sanitize_text_field( $_POST['search_text'] ) );
            }
            if ( isset( $_POST['show_footer'] ) ) {
                update_post_meta( $post_id, 'show_footer', sanitize_text_field( $_POST['show_footer'] ) );
            }
            if ( isset( $_POST['footer_text'] ) ) {
                update_post_meta( $post_id, 'footer_text', sanitize_text_field( $_POST['footer_text'] ) );
            }



            if ( isset( $_POST['primary_color'] ) ) {
                update_post_meta( $post_id, 'primary_color', sanitize_text_field( $_POST['primary_color'] ) );
            }
            if ( isset( $_POST['primary_text_color'] ) ) {
                update_post_meta( $post_id, 'primary_text_color', sanitize_text_field( $_POST['primary_text_color'] ) );
            }
            if ( isset( $_POST['primary_dark_color'] ) ) {
                update_post_meta( $post_id, 'primary_dark_color', sanitize_text_field( $_POST['primary_dark_color'] ) );
            }
            if ( isset( $_POST['alternative_color'] ) ) {
                update_post_meta( $post_id, 'alternative_color', sanitize_text_field( $_POST['alternative_color'] ) );
            }
            if ( isset( $_POST['alternative_light_color'] ) ) {
                update_post_meta( $post_id, 'alternative_light_color', sanitize_text_field( $_POST['alternative_light_color'] ) );
            }
            if ( isset( $_POST['icons_color'] ) ) {
                update_post_meta( $post_id, 'icons_color', sanitize_text_field( $_POST['icons_color'] ) );
            }
            if ( isset( $_POST['border_color'] ) ) {
                update_post_meta( $post_id, 'border_color', sanitize_text_field( $_POST['border_color'] ) );
            }


            if ( isset( $_POST['timepicker'] ) ) {
                update_post_meta( $post_id, 'timepicker', sanitize_text_field( $_POST['timepicker'] ) );
            }
            if ( isset( $_POST['show_border'] ) ) {
                update_post_meta( $post_id, 'show_border', sanitize_text_field( $_POST['show_border'] ) );
            }
            if ( isset( $_POST['loading_effect'] ) ) {
                update_post_meta( $post_id, 'loading_effect', sanitize_text_field( $_POST['loading_effect'] ) );
            }


            if ( isset( $_POST['display_selected_locations'] ) ) {
                update_post_meta( $post_id, 'display_selected_locations', sanitize_text_field( $_POST['display_selected_locations'] ) );
            }
            if ( isset( $_POST['selected_locations'] ) ) {
                $selected_locations = array_map('sanitize_text_field', $_POST['selected_locations']);
                $selected_locations = implode(',', $selected_locations);
                update_post_meta($post_id, 'selected_locations', $selected_locations);
            }

            if ( isset( $_POST['display_keypoints'] ) ) {
                update_post_meta( $post_id, 'display_keypoints', sanitize_text_field( $_POST['display_keypoints'] ) );
            }
            if ( isset( $_POST['keypoints_color'] ) ) {
                update_post_meta( $post_id, 'keypoints_color', sanitize_text_field( $_POST['keypoints_color'] ) );
            }
            if ( isset( $_POST['keypoints_data'] ) ) {
                update_post_meta( $post_id, 'keypoints_data', sanitize_text_field( $_POST['keypoints_data'] ) );
            }

            // user area
            if ( isset( $_POST['user_area_text_color'] ) ) {
                update_post_meta( $post_id, 'user_area_text_color', sanitize_text_field( $_POST['user_area_text_color'] ) );
            }
            if ( isset( $_POST['user_area_background_color'] ) ) {
                update_post_meta( $post_id, 'user_area_background_color', sanitize_text_field( $_POST['user_area_background_color'] ) );
            }


            // admin fields
            if ( isset( $_POST['shortcode'] ) ) {
                update_post_meta( $post_id, 'shortcode', sanitize_text_field( $_POST['shortcode'] ) );
            }
            if ( isset( $_POST['gocars_display'] ) ) {
                update_post_meta( $post_id, 'gocars_display', sanitize_text_field( $_POST['gocars_display'] ) );
            }
            if ( isset( $_POST['gocars_database'] ) ) {
                update_post_meta( $post_id, 'gocars_database', sanitize_text_field( $_POST['gocars_database'] ) );
            }
            if ( isset( $_POST['online_admin_link'] ) ) {
                update_post_meta( $post_id, 'online_admin_link', sanitize_text_field( $_POST['online_admin_link'] ) );
            } elseif ( isset( $_POST['gocars_database'] ) && !isset( $_POST['online_admin_link'] )) { // gocars database is not being used anymore
                update_post_meta( $post_id, 'online_admin_link', sanitize_text_field( get_post_meta( get_post_meta( $post_id, 'gocars_database', true ), 'online_admin_link', true ) ) );
            }
            if ( isset( $_POST['domain'] ) ) {
                update_post_meta( $post_id, 'domain', sanitize_text_field( $_POST['domain'] ) );
            } elseif ( isset( $_POST['gocars_database'] ) && !isset( $_POST['domain'] )) { // gocars database is not being used anymore
                update_post_meta( $post_id, 'domain', sanitize_text_field( get_post_meta( get_post_meta( $post_id, 'gocars_database', true ), 'domain', true ) ) );
            }            
            if ( isset( $_POST['language_id'] ) ) {
                update_post_meta( $post_id, 'language_id', sanitize_text_field( $_POST['language_id'] ) );
            }

            if ( function_exists( 'gocars_flush_gocars_http_cache' ) ) {
                $functions_rel = plugin_dir_path( __FILE__ ) . 'functions.php';
                if ( file_exists( $functions_rel ) ) {
                    require_once $functions_rel;
                }
                gocars_flush_gocars_http_cache();
            }

            self::update_gocars_functions($post_id);

        }

        //-------------------------------------------------------------

        // SHORTCODE FIELDS ENDS





        // SHORTCODE GENERATOR START



        //-------------------------------------------------------------

        
        function gocars_shortcode_generate() {

            add_shortcode( 'search_form', array( $this, 'gocars_shortcode_generator' ) );
            add_shortcode( 'fleet', array( $this, 'gocars_shortcode_generator' ) );
            add_shortcode( 'terms', array( $this, 'gocars_shortcode_generator' ) );

        }


        //-------------------------------------------------------------
        
        function gocars_shortcode_generator( $atts, $content, $shortcode_tag) {

            // Check domain authorization before displaying shortcode
            $config = GocarsConfig::get_instance();
            if (!function_exists('gocars_domain_is_allowed') || !gocars_domain_is_allowed($config, false)) {
                // Domain not authorized - return empty or error message
                $params = !empty($atts) ? ' id="'.implode(':',$atts).'"' : '';
                return '[' . $shortcode_tag . $params .']';
            }

            // Start output buffering
            ob_start();

            // Declare global variable
            global $post;        

            $default_atts = array(
                'id' => '',
                'number' => '',
                'vehicle' => '',
                'once' => '',
                'category' => '',
                'slider' => '',
            );
            $params = shortcode_atts($default_atts, $atts);

            $shortcode_value = '';
            $shortcode_value .= '[' . $shortcode_tag;

            foreach ($params as $key => $value) {
                if ($value) {
                    $shortcode_value .= ' ' . $key . '="' . $value . '"';
                }
            }
            $shortcode_value .= ']';


            $shortcode_valid = false;
            $args = array(
                'post_type' => 'gocars_shortcode',
                'post_status' => 'publish',
                'posts_per_page' => -1,
            );
            $gocars_query = null;
            $gocars_query = new WP_Query($args);
            
            if ($gocars_query->have_posts()):      
                
                while ($gocars_query->have_posts()) : $gocars_query->the_post();
                    
                    $shortcode = get_post_meta( $post->ID, 'shortcode', true );
                    if ($shortcode_value == $shortcode) {
                        $shortcode_valid = true;
                    }
                    
                endwhile;
                wp_reset_postdata();

            endif;

            if ($shortcode_tag == 'search_form' && $shortcode_valid && file_exists(plugin_dir_path( __FILE__ ) . 'templates/shortcodes/search_form.php')) {
                include plugin_dir_path( __FILE__ ) . 'templates/shortcodes/search_form.php';
            } elseif ($shortcode_tag == 'fleet' && $shortcode_valid && file_exists(plugin_dir_path( __FILE__ ) . 'templates/shortcodes/fleet.php')) {
                include plugin_dir_path( __FILE__ ) . 'templates/shortcodes/fleet.php';
            } elseif ($shortcode_tag == 'terms' && $shortcode_valid && file_exists(plugin_dir_path( __FILE__ ) . 'templates/shortcodes/terms.php')) {
                include plugin_dir_path( __FILE__ ) . 'templates/shortcodes/terms.php';
            } else {
                return $shortcode_value;
            }

           // Get the contents of the output buffer
            $shortcode_content = ob_get_clean();

            // Echo the shortcode content directly
            return $shortcode_content;
            
        }

        //-------------------------------------------------------------


        // SHORTCODE GENERATOR ENDS


         
        


        // WP HEAD SCRIPTS START


        function wp_head_scripts() {
            if (get_option('head_scripts')) {
                echo get_option('head_scripts');
            }
        }

        // WP HEAD SCRIPTS END


        // COOKIE CONSENT HEAD — Google Consent Mode v2 defaults (must run before GTM/gtag)
        function cookie_consent_head() {
            if (get_option('gocars_cookie_banner_enabled', '0') !== '1') return;
            ?>
            <script>
                window.dataLayer = window.dataLayer || [];
                function gtag(){dataLayer.push(arguments);}
                gtag('consent', 'default', {
                    'analytics_storage':     localStorage.getItem('gocarsCookieChoice_analytics')    === 'true' ? 'granted' : 'denied',
                    'ad_storage':            localStorage.getItem('gocarsCookieChoice_advertising')  === 'true' ? 'granted' : 'denied',
                    'ad_user_data':          localStorage.getItem('gocarsCookieChoice_advertising')  === 'true' ? 'granted' : 'denied',
                    'ad_personalization':    localStorage.getItem('gocarsCookieChoice_advertising')  === 'true' ? 'granted' : 'denied',
                    'functionality_storage': localStorage.getItem('gocarsCookieChoice_preferences')  === 'true' ? 'granted' : 'denied',
                    'security_storage':      'granted',
                    'wait_for_update':       500
                });
                gtag('set', 'url_passthrough', true);
                gtag('set', 'ads_data_redaction', true);
            </script>
            <?php
        }
        // END COOKIE CONSENT HEAD


        //WP BODY SCRIPTS START


        function wp_body_scripts() {
            if (get_option('body_scripts')) {
                echo get_option('body_scripts');
            }
        }

        // WP BODY SCRIPTS END

        // WP FOOTER SCRIPTS START


        function wp_footer_scripts() {
            if (get_option('footer_scripts')) {
                echo get_option('footer_scripts');
            }
        }

        // WP FOOTER SCRIPTS END


        // COOKIE CONSENT FOOTER — banner init config
        function cookie_consent_footer() {
            if (get_option('gocars_cookie_banner_enabled', '0') !== '1') return;

            // Build CSS variable overrides from saved appearance options
            $css_var_map = [
                '--primaryColor'              => get_option('gocars_cookie_btn_bg',         '#4F4872'),
                '--buttonTextColor'          => get_option('gocars_cookie_btn_text',       '#FFFFFF'),
                '--primaryColorHover'        => get_option('gocars_cookie_btn_hover_bg',   '#352C45'),
                '--buttonHoverTextColor'     => get_option('gocars_cookie_btn_hover_text', '#FFFFFF'),
                '--cookieIconColor'          => get_option('gocars_cookie_icon_color',     '#4F4872'),
                '--cookieIconBackgroundColor'=> get_option('gocars_cookie_icon_bg',        '#FFFFFF'),
            ];
            $css_vars = array_filter($css_var_map); // remove empty values
            if (!empty($css_vars)):
                echo '<style>#gocars-wrapper{';
                foreach ($css_vars as $var => $value) {
                    echo esc_attr($var) . ':' . esc_attr($value) . ';';
                }
                echo '}</style>';
            endif;

            // All translatable strings — use __() so .po/.mo files can localise them
            $default_banner_desc = '<p>' . __('We use cookies to improve your experience, analyse traffic, and support marketing.', 'gocars') . ' <a href="/cookie-policy" target="_blank" rel="noopener">' . __('Cookie Policy', 'gocars') . '</a></p>';

            $gc_strings = [
                // Cookie type labels
                'necessary_name'             => __('Necessary', 'gocars'),
                'necessary_desc'             => '<p>' . __('Required for the site to function. These cannot be disabled.', 'gocars') . '</p>',
                'preferences_name'           => __('Preferences', 'gocars'),
                'preferences_desc'           => '<p>' . __('Remembers your settings and personalisation choices.', 'gocars') . '</p>',
                'analytics_name'             => __('Statistics', 'gocars'),
                'analytics_desc'             => '<p>' . __('Helps us understand how visitors use the site (e.g. Google Analytics, page views).', 'gocars') . '</p>',
                'advertising_name'           => __('Marketing', 'gocars'),
                'advertising_desc'           => '<p>' . __('Used for ad targeting, conversion tracking, and cross-site campaign measurement.', 'gocars') . '</p>',
                // Banner text (description comes from saved option, falls back to translated default)
                'banner_desc'                => wp_kses_post(get_option('gocars_cookie_banner_description', $default_banner_desc)),
                'accept_all_text'            => __('Accept all', 'gocars'),
                'accept_all_label'           => __('Accept all cookies', 'gocars'),
                'deny_text'                  => __('Deny', 'gocars'),
                'deny_label'                 => __('Deny non-essential cookies', 'gocars'),
                'preferences_btn_text'       => __('Preferences', 'gocars'),
                'preferences_btn_label'      => __('Manage cookie preferences', 'gocars'),
                // Preferences panel
                'preferences_panel_title'    => __('Cookie Preferences', 'gocars'),
                'preferences_panel_desc'     => '<p>' . __('Choose which cookies you allow. Your preferences are saved and can be changed at any time.', 'gocars') . '</p>',
            ];
            ?>
            <script>
                (function() {
                    /* UTM persistence — capture on landing, restore on subsequent pages */
                    var utmKeys = ['utm_source','utm_medium','utm_campaign','utm_term','utm_content','utm_id','gclid','gbraid','wbraid','gad_source','gad_campaignid','aaid','ap','tm'];
                    var params  = new URLSearchParams(window.location.search);
                    var stored  = {};
                    var found   = false;
                    utmKeys.forEach(function(k) {
                        if (params.get(k)) { stored[k] = params.get(k); found = true; }
                    });
                    if (found) {
                        try { sessionStorage.setItem('gc_utm', JSON.stringify(stored)); } catch(e) {}
                    } else {
                        try { stored = JSON.parse(sessionStorage.getItem('gc_utm') || '{}'); } catch(e) {}
                    }
                    if (Object.keys(stored).length) {
                        window.dataLayer = window.dataLayer || [];
                        dataLayer.push(Object.assign({}, stored, { event: 'utm_data' }));
                    }
                    /* gcPushUtm — called from onAccept callbacks to re-associate UTM after consent */
                    window.gcPushUtm = function() {
                        try {
                            var u = JSON.parse(sessionStorage.getItem('gc_utm') || '{}');
                            if (Object.keys(u).length) {
                                window.dataLayer = window.dataLayer || [];
                                dataLayer.push(Object.assign({}, u, { event: 'utm_data' }));
                            }
                        } catch(e) {}
                    };
                })();

                var gcT = <?php echo wp_json_encode($gc_strings); ?>;

                gocarsCookieBannerManager.updateCookieBannerConfig({
                    cookieIcon: { position: 'bottomRight' },
                    position:   { banner: 'bottomRight' },
                    background: { showBackground: true },
                    cookieTypes: [
                        {
                            id: 'necessary',
                            name: gcT.necessary_name,
                            required: true,
                            description: gcT.necessary_desc,
                            onAccept: function() {
                                document.dispatchEvent(new CustomEvent('gc:consent_changed'));
                            }
                        },
                        {
                            id: 'preferences',
                            name: gcT.preferences_name,
                            description: gcT.preferences_desc,
                            onAccept: function() {
                                if (typeof gtag === 'function') { gtag('consent', 'update', { functionality_storage: 'granted' }); }
                                if (typeof gcPushUtm === 'function') { gcPushUtm(); }
                                document.dispatchEvent(new CustomEvent('gc:consent_changed'));
                            },
                            onReject: function() {
                                if (typeof gtag === 'function') { gtag('consent', 'update', { functionality_storage: 'denied' }); }
                                document.dispatchEvent(new CustomEvent('gc:consent_changed'));
                            }
                        },
                        {
                            id: 'analytics',
                            name: gcT.analytics_name,
                            description: gcT.analytics_desc,
                            onAccept: function() {
                                if (typeof gtag === 'function') { gtag('consent', 'update', { analytics_storage: 'granted' }); }
                                window.dataLayer = window.dataLayer || [];
                                dataLayer.push({ event: 'consent_accepted_analytics' });
                                if (typeof gcPushUtm === 'function') { gcPushUtm(); }
                                document.dispatchEvent(new CustomEvent('gc:consent_changed'));
                            },
                            onReject: function() {
                                if (typeof gtag === 'function') { gtag('consent', 'update', { analytics_storage: 'denied' }); }
                                document.dispatchEvent(new CustomEvent('gc:consent_changed'));
                            }
                        },
                        {
                            id: 'advertising',
                            name: gcT.advertising_name,
                            description: gcT.advertising_desc,
                            onAccept: function() {
                                if (typeof gtag === 'function') {
                                    gtag('consent', 'update', {
                                        ad_storage:         'granted',
                                        ad_user_data:       'granted',
                                        ad_personalization: 'granted'
                                    });
                                }
                                window.dataLayer = window.dataLayer || [];
                                dataLayer.push({ event: 'consent_accepted_advertising' });
                                if (typeof gcPushUtm === 'function') { gcPushUtm(); }
                                document.dispatchEvent(new CustomEvent('gc:consent_changed'));
                            },
                            onReject: function() {
                                if (typeof gtag === 'function') {
                                    gtag('consent', 'update', {
                                        ad_storage:         'denied',
                                        ad_user_data:       'denied',
                                        ad_personalization: 'denied'
                                    });
                                }
                                document.dispatchEvent(new CustomEvent('gc:consent_changed'));
                            }
                        }
                    ],
                    text: {
                        banner: {
                            description:                             gcT.banner_desc,
                            acceptAllButtonText:                     gcT.accept_all_text,
                            acceptAllButtonAccessibleLabel:          gcT.accept_all_label,
                            rejectNonEssentialButtonText:            gcT.deny_text,
                            rejectNonEssentialButtonAccessibleLabel: gcT.deny_label,
                            preferencesButtonText:                   gcT.preferences_btn_text,
                            preferencesButtonAccessibleLabel:        gcT.preferences_btn_label
                        },
                        preferences: {
                            title:       gcT.preferences_panel_title,
                            description: gcT.preferences_panel_desc
                        }
                    }
                });
            </script>
            <?php
        }
        // END COOKIE CONSENT FOOTER


        // WP ADVANCED CSS START


        function wp_advanced_css() {
            if (get_option('advanced_css')) {
                echo '<style id="advanced-css" type="text/css">' . get_option('advanced_css') . '</style>';
            }
        }

        // WP ADVANCED CSS END



        // FUNCTIONS START

        function load_functions() {

            // Get the path to the file containing the shortcode content
            $functions = plugin_dir_path( __FILE__ ) . 'functions.php';
        
            // Check if the file exists
            if ( ! file_exists( $functions ) ) {
                return ''; // or throw an error
            }
        
            require_once $functions;
        }

        // FUNCTIONS END


        function redirect_to_homepage() {
            if ( is_singular( array( 'gocars_shortcode', 'gocars_db' ) ) ) {
                wp_redirect(home_url('/'));
                exit;
            }
        }

        function load_style() {
            global $post;
            $keypoints_slider = false;
            $args = array(
                'post_type' => 'gocars_shortcode',
                'posts_per_page' => -1,
                'orderby' => isset($_GET['orderby']) ? $_GET['orderby'] : 'title',
                'order' => isset($_GET['order']) ? $_GET['order'] : 'ASC',
            );
            $listings = new WP_Query( $args );
            if ( $listings->have_posts() ) : 
                while ( $listings->have_posts() ) : $listings->the_post(); 

                    // Get the post ID
                    $post_id = $post->ID;

                    $params = array(
                        'id' => $post_id
                    );

                    // Get the path to the file containing the shortcode content
                    $style = plugin_dir_path( __FILE__ ) . 'assets/style.php';
                    
                    // Check if the file exists
                    if ( ! file_exists( $style ) ) {
                        return ''; // or throw an error
                    }
                
                    include $style;
                 
                endwhile; 
                wp_reset_postdata(); 
            endif;
        }

        public function load_scripts() {
            $shortcode_id = '';
            global $post;
            
            $args = array(
                'post_type' => 'gocars_shortcode',
                'posts_per_page' => -1,
                'orderby' => isset($_GET['orderby']) ? $_GET['orderby'] : 'title',
                'order' => isset($_GET['order']) ? $_GET['order'] : 'ASC',
            );
            $listings = new WP_Query( $args );
            if ( $listings->have_posts() ) : 
                while ( $listings->have_posts() ) : $listings->the_post(); 
                    $lang = 1;
                    $language = 'en';
                    // Get the post ID
                    $post_id = $post->ID;
                    $form_display = get_post_meta( $post_id, 'form_display', true );
                    $language_locale = json_decode(get_post_meta( $post_id, 'language_locale', true ));
                    $label_arr = array();
                    $locale = get_locale();
                    
                    if ( !empty($language_locale)) {
                        $language = defined('ICL_LANGUAGE_CODE') ? ICL_LANGUAGE_CODE : $language;
                        $language = !defined('ICL_LANGUAGE_CODE') && $locale != '' ? substr($locale, 0, 2) : $language;
                        $lang = $language_locale->$language->id;
                        $label_arr = $language_locale->$language->labels;
                    }
                    
                    ?>
                    <div data-shortcode="<?php echo $post_id; ?>" class="options<?php echo ($form_display == 'H' ? ' horizontal' : ' vertical'); ?>">
                        <div class="datepicker-modal<?php echo ($form_display == 'H' ? ' horizontal' : ' vertical'); ?>">
                            <div class="datepicker-mobile-heading">
                                <span class="text regular main-color-dark medium-large"><?php _e($label_arr->select_dates,'gocars'); ?></span>
                                <span class="close-datepicker-btn"></span>
                            </div>
                            <div data-shortcode="<?php echo $post_id; ?>" translate="no" class="mobile-datepicker notranslate"></div>
                        </div>
            
                        <div class="mobile_datepicker_options" style="display: none;">
                            <label for="start-<?php echo $post_id; ?>">
                                <?php _e($label_arr->please_select,'gocars'); ?>
                                <input id="start-<?php echo $post_id; ?>" mbsc-input class="mobile-datepicker" placeholder="<?php _e($label_arr->please_select,'gocars'); ?>" />
                            </label>
                            <label for="end-<?php echo $post_id; ?>">
                                <?php _e($label_arr->please_select,'gocars'); ?>
                                <input id="end-<?php echo $post_id; ?>" mbsc-input class="mobile-datepicker" placeholder="<?php _e($label_arr->please_select,'gocars'); ?>" />
                            </label>
                        </div>
                    </div>
        
                <?php

                    
                endwhile; 
                wp_reset_postdata(); 
            endif;
        
        }
        
        /**
         * Warm one set of remote payloads for a Gocars subdomain (used to dedupe HTTP across many shortcodes in the same cron run).
         *
         * @param int $representative_post_id Any gocars_shortcode post that carries the target domain meta.
         * @return array<string, mixed>|null Payload map or null when the domain/API is unusable.
         */
        public static function build_domain_prefetch( $representative_post_id ) {
            $representative_post_id = (int) $representative_post_id;
            if ( $representative_post_id < 1 ) {
                return null;
            }

            $functions = plugin_dir_path( __FILE__ ) . 'functions.php';
            if ( ! file_exists( $functions ) ) {
                return null;
            }
            require_once $functions;

            $domain_raw = trim( (string) get_post_meta( $representative_post_id, 'domain', true ) );
            $slug_norm  = gocars_normalize_domain_slug( $domain_raw );
            if ( $slug_norm === '' ) {
                return null;
            }

            $option_arr = getGcOptions( $representative_post_id );
            if ( empty( $option_arr ) || ! is_object( $option_arr ) ) {
                return null;
            }

            if ( empty( $option_arr->language_arr ) ) {
                return null;
            }

            $languages_arr = $option_arr->language_arr;

            $locations_by_key     = array();
            $models_raw_by_key = array();

            $first_key = true;
            foreach ( $languages_arr as $key => $value ) {
                if ( ! is_object( $value ) || ! isset( $value->id ) ) {
                    continue;
                }

                $lang_id  = (int) $value->id;
                $iter_key = $key;
                if ( $iter_key === '' && $first_key ) {
                    $iter_key  = 'en';
                    $lang_id   = 1;
                    $first_key = false;
                }

                $locations_by_key[ $iter_key ]     = getGcLocations( $lang_id, $representative_post_id );
                $models_raw_by_key[ $iter_key ] = gocars_fetch_models_payload_for_lang( $domain_raw, $lang_id );
            }

            $models_nl    = gocars_fetch_models_payload_no_lang( $domain_raw );
            $age_data     = getGcAgeGroups( $representative_post_id );
            $vehicle_data = getGcVehicleTypes( $representative_post_id, $option_arr, $models_nl );
            $attempts_dat = getGcAttempts( $representative_post_id, $option_arr );
            $dates_data   = dates_options( $domain_raw );

            return array(
                'slug'                        => $slug_norm,
                'domain_slug_raw'             => $domain_raw,
                'option_arr'                  => $option_arr,
                'locations_by_key'            => $locations_by_key,
                'models_raw_by_key'           => $models_raw_by_key,
                'models_default_lang_payload' => $models_nl,
                'age_data'                    => $age_data,
                'vehicle_data'                => $vehicle_data,
                'attempts_data'               => $attempts_dat,
                'dates_data'                  => $dates_data,
            );
        }

        public static function update_gocars_functions($post_id = null) {
            global $post;
            $args = array(
                'post_type' => 'gocars_shortcode',
                'posts_per_page' => -1,
                'suppress_filters' => true
            );

            if ($post_id == null) {
                require_once plugin_dir_path(__FILE__) . 'functions.php';
                $listings = new WP_Query($args);
                $by_domain = array();
                if ($listings->have_posts()) {
                    while ($listings->have_posts()) {
                        $listings->the_post();
                        $pid = get_the_ID();
                        $dns_trim = trim((string) get_post_meta($pid, 'domain', true));
                        $norm     = gocars_normalize_domain_slug($dns_trim);
                        if ($norm === '') {
                            $norm = '__empty_' . $pid;
                        }
                        if (! isset($by_domain[$norm])) {
                            $by_domain[$norm] = array();
                        }
                        $by_domain[$norm][] = $pid;
                    }
                    wp_reset_postdata();
                }

                foreach ($by_domain as $norm_bucket => $pids) {
                    $prefetch = null;
                    if (strpos((string) $norm_bucket, '__empty_') !== 0 && count($pids) > 0) {
                        $prefetch = self::build_domain_prefetch((int) $pids[0]);
                        if (is_array($prefetch) && isset($prefetch['slug']) && (string) $prefetch['slug'] !== (string) $norm_bucket) {
                            $prefetch = null;
                        }
                    }
                    foreach ($pids as $pid) {
                        self::update_fields((int) $pid, null, $prefetch);
                    }
                }
            } else if ($post_id != null) {
                $post = get_post($post_id);
                setup_postdata($post);
                $prefetch = self::build_domain_prefetch((int) $post_id);
                self::update_fields($post_id, null, $prefetch);
                wp_reset_postdata();
            }
        }

        public static function update_fields($post_id, $updater_website = null, $domain_prefetch = null) {
            // Include required functions
            $lang = 1;
            
            $terms_data = array();
            $locations_data = array();
            $all_vehicles_data = array();
            $vehicles_data = array();
            $vehicles_type_data = array();
            $model_type_data = array();


            $functions = plugin_dir_path(__FILE__) . 'functions.php';
            if (!file_exists($functions)) {
                return ''; // Return or handle the error
            }
            require_once $functions;

            $domain_slug = trim((string) get_post_meta($post_id, 'domain', true));

            $slug_normalized_here = function_exists('gocars_normalize_domain_slug') ? gocars_normalize_domain_slug($domain_slug) : strtolower($domain_slug);
            $use_prefetch         = is_array($domain_prefetch)
                && isset($domain_prefetch['slug'])
                && $slug_normalized_here !== ''
                && $slug_normalized_here === $domain_prefetch['slug'];

            // options --------------------------------
            if ($use_prefetch) {
                $option_arr = gocars_deep_clone_for_sync($domain_prefetch['option_arr']);
            } else {
                $option_arr = getGcOptions($post_id);
            }

            // Check if we can reach the gocars.gr server
            if (empty($option_arr) || !is_object($option_arr)) {
                $domain_name = $_SERVER['HTTP_HOST'] == '' ? site_url('/') : $_SERVER['HTTP_HOST'];
                GocarsOnline::sendToDiscordDiscord($domain_name . ' - Failed to connect to gocars.gr server for shortcode - ' . $post_id);
                return; // Exit without updating settings.json
            }

            $options_data = (object) [
                'o_different_location_preselect' => (isset($option_arr->o_different_location_preselect) && $option_arr->o_different_location_preselect != null) 
                    ? $option_arr->o_different_location_preselect 
                    : '0',
            
                'o_default_age_group' => (isset($option_arr->o_default_age_group) && $option_arr->o_default_age_group != null) 
                    ? $option_arr->o_default_age_group 
                    : '',
            
                'o_default_location' => (isset($option_arr->o_default_location) && $option_arr->o_default_location != null) 
                    ? $option_arr->o_default_location 
                    : '',
            
                'o_timer_type' => (isset($option_arr->o_timer_type) && $option_arr->o_timer_type != null) 
                    ? $option_arr->o_timer_type 
                    : 'timepicker_input',

                'o_timer_step' => (isset($option_arr->o_timer_step) && $option_arr->o_timer_step != null) 
                    ? $option_arr->o_timer_step 
                    : '15',
            
                'o_default_hour' => (isset($option_arr->o_default_hour) && $option_arr->o_default_hour != null) 
                    ? $option_arr->o_default_hour 
                    : '11:00',
            
                'o_location_pricing' => (isset($option_arr->o_location_pricing) && $option_arr->o_location_pricing != null) 
                    ? $option_arr->o_location_pricing 
                    : '0',
            
                'o_sort_type' => (isset($option_arr->o_sort_type) && $option_arr->o_sort_type != null) 
                    ? $option_arr->o_sort_type 
                    : 'price_asc',
            
                'o_allow_website' => (isset($option_arr->o_allow_website) && $option_arr->o_allow_website != null) 
                    ? $option_arr->o_allow_website 
                    : '0',
            
                'o_preselect_default_dates' => (isset($option_arr->o_preselect_default_dates) && $option_arr->o_preselect_default_dates != null) 
                    ? $option_arr->o_preselect_default_dates 
                    : '1',
            
                'o_allow_user_area' => (isset($option_arr->o_allow_user_area) && $option_arr->o_allow_user_area != null) 
                    ? $option_arr->o_allow_user_area 
                    : '0',
            
                'o_translate_website' => (isset($option_arr->o_translate_website) && $option_arr->o_translate_website != null) 
                    ? $option_arr->o_translate_website 
                    : '0',
            
                'o_age_group_visible' => (isset($option_arr->o_age_group_visible) && $option_arr->o_age_group_visible != null) 
                    ? $option_arr->o_age_group_visible 
                    : '1',

                'o_show_vehicle_type' => (isset($option_arr->o_show_vehicle_type) && $option_arr->o_show_vehicle_type != null) 
                    ? $option_arr->o_show_vehicle_type 
                    : '0',

                'o_selected_vehicle_type' => (isset($option_arr->o_selected_vehicle_type) && $option_arr->o_selected_vehicle_type != null) 
                    ? $option_arr->o_selected_vehicle_type 
                    : 'car',
            ];

            update_post_meta($post_id, 'options_data', json_encode($options_data, JSON_UNESCAPED_UNICODE));

            // languages --------------------------------
            $languages = isset($option_arr->i18n) ? $option_arr->i18n : array();
            $languages_arr = isset($option_arr->language_arr) ? $option_arr->language_arr : array();
            $firstKey = true;

            foreach ($languages_arr as $key => $value) {
                $lang_id = $value->id;
                
                if ($key == '' && $firstKey) {
                    $key = 'en' ;
                    $lang_id = 1;
                    $firstKey = false;
                }
                
                $languages_arr->$key->labels = [
                    'start_search' => (isset($languages->$lang_id->start_search) && $languages->$lang_id->start_search != null) 
                        ? __($languages->$lang_id->start_search, 'gocars') 
                        : __('Start Your Reservation!', 'gocars'),
                
                    'pickup_location' => (isset($languages->$lang_id->pickup_location) && $languages->$lang_id->pickup_location != null) 
                        ? __($languages->$lang_id->pickup_location, 'gocars') 
                        : __('Pick-up Location', 'gocars'),
                
                    'dropoff_location' => (isset($languages->$lang_id->dropoff_location) && $languages->$lang_id->dropoff_location != null) 
                        ? __($languages->$lang_id->dropoff_location, 'gocars') 
                        : __('Drop-off Location', 'gocars'),
                
                    'choose_location' => (isset($languages->$lang_id->choose_location) && $languages->$lang_id->choose_location != null) 
                        ? __($languages->$lang_id->choose_location, 'gocars') 
                        : __('Choose Location', 'gocars'),
                
                    'location_placeholder' => (isset($languages->$lang_id->location_placeholder) && $languages->$lang_id->location_placeholder != null) 
                        ? __($languages->$lang_id->location_placeholder, 'gocars') 
                        : __('City, location, area, village or hotel', 'gocars'),
                
                    'different_location' => (isset($languages->$lang_id->different_location) && $languages->$lang_id->different_location != null) 
                        ? __($languages->$lang_id->different_location, 'gocars') 
                        : __('Return vehicle in a different location', 'gocars'),
                
                    'pickup_datetime' => (isset($languages->$lang_id->pickup_datetime) && $languages->$lang_id->pickup_datetime != null) 
                        ? __($languages->$lang_id->pickup_datetime, 'gocars') 
                        : __('Pick-up Date/Time', 'gocars'),
                
                    'pickup_date' => (isset($languages->$lang_id->pickup_date) && $languages->$lang_id->pickup_date != null) 
                        ? __($languages->$lang_id->pickup_date, 'gocars') 
                        : __('Pick-up Date', 'gocars'),
                
                    'dropoff_datetime' => (isset($languages->$lang_id->dropoff_datetime) && $languages->$lang_id->dropoff_datetime != null) 
                        ? __($languages->$lang_id->dropoff_datetime, 'gocars') 
                        : __('Drop-off Date/Time', 'gocars'),
                
                    'dropoff_date' => (isset($languages->$lang_id->dropoff_date) && $languages->$lang_id->dropoff_date != null) 
                        ? __($languages->$lang_id->dropoff_date, 'gocars') 
                        : __('Drop-off Date', 'gocars'),
                
                    'select_dates' => (isset($languages->$lang_id->lblSelectDates) && $languages->$lang_id->lblSelectDates != null) 
                        ? __($languages->$lang_id->lblSelectDates, 'gocars') 
                        : __('Select Dates', 'gocars'),
                
                    'age_group' => (isset($languages->$lang_id->age_group) && $languages->$lang_id->age_group != null) 
                        ? __($languages->$lang_id->age_group, 'gocars') 
                        : __('Age Group', 'gocars'),
                
                    'search' => (isset($languages->$lang_id->search) && $languages->$lang_id->search != null) 
                        ? __($languages->$lang_id->search, 'gocars') 
                        : __('Search', 'gocars'),
                
                    'search_now' => (isset($languages->$lang_id->search_now) && $languages->$lang_id->search_now != null) 
                        ? __($languages->$lang_id->search_now, 'gocars') 
                        : __('Search Now', 'gocars'),
                
                    'search_prices' => (isset($languages->$lang_id->search_prices) && $languages->$lang_id->search_prices != null) 
                        ? __($languages->$lang_id->search_prices, 'gocars') 
                        : __('SEARCH PRICES', 'gocars'),
                
                    'time' => (isset($languages->$lang_id->time) && $languages->$lang_id->time != null) 
                        ? __($languages->$lang_id->time, 'gocars') 
                        : __('Time', 'gocars'), 
                
                    'please_fill' => (isset($languages->$lang_id->please_fill) && $languages->$lang_id->please_fill != null) 
                        ? __($languages->$lang_id->please_fill, 'gocars') 
                        : __('Please fill', 'gocars'),
                
                    'please_select' => (isset($languages->$lang_id->please_select) && $languages->$lang_id->please_select != null) 
                        ? __($languages->$lang_id->please_select, 'gocars') 
                        : __('Please Select', 'gocars'),
                
                    'existing_client' => (isset($languages->$lang_id->existing_client) && $languages->$lang_id->existing_client != null) 
                        ? __($languages->$lang_id->existing_client, 'gocars') 
                        : __('Existing Client', 'gocars'),
                
                    'find_reservation' => (isset($languages->$lang_id->find_reservation) && $languages->$lang_id->find_reservation != null) 
                        ? __($languages->$lang_id->find_reservation, 'gocars') 
                        : __('Find Your Reservation', 'gocars'),
                
                    'price_from' => (isset($languages->$lang_id->price_from) && $languages->$lang_id->price_from != null) 
                        ? __($languages->$lang_id->price_from, 'gocars') 
                        : __('Price From', 'gocars'),
                
                    'book_now' => (isset($languages->$lang_id->book_now) && $languages->$lang_id->book_now != null) 
                        ? __($languages->$lang_id->book_now, 'gocars') 
                        : __('Book Now', 'gocars'),
                
                    'best_price' => (isset($languages->$lang_id->best_price) && $languages->$lang_id->best_price != null) 
                        ? __($languages->$lang_id->best_price, 'gocars') 
                        : __('Best Price', 'gocars'),
                
                    'last_search' => (isset($languages->$lang_id->last_search) && $languages->$lang_id->last_search != null) 
                        ? __($languages->$lang_id->last_search, 'gocars') 
                        : __('Last Search', 'gocars'),

                    'from' => (isset($languages->$lang_id->from) && $languages->$lang_id->from != null) 
                        ? __($languages->$lang_id->from, 'gocars') 
                        : __('from', 'gocars'),
                        
                    'day' => (isset($languages->$lang_id->day) && $languages->$lang_id->day != null) 
                        ? __($languages->$lang_id->day, 'gocars') 
                        : __('day', 'gocars'),    

                    'reservation' => (isset($languages->$lang_id->per_reserreservationvation) && $languages->$lang_id->reservation != null) 
                        ? __($languages->$lang_id->reservation, 'gocars') 
                        : __('reservation', 'gocars'),
                ];
                
                

                $locations_data[$key] = ($use_prefetch && isset($domain_prefetch['locations_by_key'][ $key ]))
                    ? gocars_deep_clone_for_sync($domain_prefetch['locations_by_key'][ $key ])
                    : getGcLocations($lang_id, $post_id); // LOCATIONS

                $terms_cleaned = (isset($languages->$lang_id->o_terms) && $languages->$lang_id->o_terms != null) ? htmlspecialchars($languages->$lang_id->o_terms, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') : __('No Terms', 'gocars');
                $terms_data[$key] = __($terms_cleaned, 'gocars');

                $payload = ($use_prefetch && isset($domain_prefetch['models_raw_by_key'][ $key ]))
                    ? gocars_deep_clone_for_sync($domain_prefetch['models_raw_by_key'][ $key ])
                    : gocars_fetch_models_payload_for_lang( $domain_slug, $lang_id );
                if ( ! is_array( $payload ) ) {
                    $payload = array();
                }
                if ( empty( $payload ) ) {
                    $all_vehicles_data[ $key ] = array();
                    $vehicles_data[ $key ]     = array();
                    $vehicle_std_types         = array( 'car', 'moto', 'atv', 'scooter', 'buggy', 'bicycle' );
                    foreach ( $vehicle_std_types as $type ) {
                        $languages_arr->$key->labels[ $type ] = ( isset( $languages->$lang_id->$type ) && $languages->$lang_id->$type != null )
                            ? __($languages->$lang_id->$type, 'gocars')
                            : __($type, 'gocars');
                        $vehicles_type_data[ $key ][ $type ] = array();
                    }
                    $model_type_data[ $key ] = array();
                    continue;
                }

                gocars_models_apply_descriptions_all( $payload );
                $all_vehicles_data[ $key ] = $payload;
                $vehicles_data[ $key ]     = gocars_models_dedupe_first_per_type_name( $payload );

                $vehicle_std_types = array( 'car', 'moto', 'atv', 'scooter', 'buggy', 'bicycle' );
                foreach ( $vehicle_std_types as $type ) {
                    $languages_arr->$key->labels[ $type ] = ( isset( $languages->$lang_id->$type ) && $languages->$lang_id->$type != null )
                    ? __($languages->$lang_id->$type, 'gocars')
                    : __($type, 'gocars');

                    $vehicles_type_data[ $key ][ $type ] = gocars_models_filter_by_vehicle_type( $payload, $type );
                }

                $model_type_data[ $key ] = gocars_models_group_by_type_name( $payload );
            }
            // languages --------------------------------
            update_post_meta($post_id, 'language_locale', json_encode($languages_arr, JSON_UNESCAPED_UNICODE));

            // terms --------------------------------
            if (!empty($terms_data)) {
                update_post_meta($post_id, 'terms_data', json_encode($terms_data, JSON_UNESCAPED_UNICODE));
            }

            // locations --------------------------------    
            if (!empty($locations_data)) {
                update_post_meta($post_id, 'locations_data', json_encode($locations_data, JSON_UNESCAPED_UNICODE));
            }

            // ages --------------------------------
            if ($use_prefetch && array_key_exists('age_data', $domain_prefetch)) {
                $age_data = gocars_deep_clone_for_sync($domain_prefetch['age_data']);
            } else {
                $age_data = getGcAgeGroups($post_id);
            }
            if (!empty($age_data)) {
                update_post_meta($post_id, 'age_data', json_encode($age_data, JSON_UNESCAPED_UNICODE));
            }

            if ($use_prefetch && array_key_exists('models_default_lang_payload', $domain_prefetch)) {
                $models_default_lang_payload = gocars_deep_clone_for_sync($domain_prefetch['models_default_lang_payload']);
                if ( ! is_array( $models_default_lang_payload ) ) {
                    $models_default_lang_payload = array();
                }
            } else {
                $models_default_lang_payload = gocars_fetch_models_payload_no_lang( $domain_slug );
            }

            // vehicles --------------------------------
            if ($use_prefetch && array_key_exists('vehicle_data', $domain_prefetch)) {
                $vehicle_data = gocars_deep_clone_for_sync($domain_prefetch['vehicle_data']);
            } else {
                $vehicle_data = getGcVehicleTypes( $post_id, $option_arr, $models_default_lang_payload );
            }
            if (!empty($vehicle_data)) {
                update_post_meta($post_id, 'vehicle_data', json_encode($vehicle_data, JSON_UNESCAPED_UNICODE));
            }
            // attempts --------------------------------
            if ($use_prefetch && array_key_exists('attempts_data', $domain_prefetch)) {
                $attempts_data = gocars_deep_clone_for_sync($domain_prefetch['attempts_data']);
            } else {
                $attempts_data = getGcAttempts( $post_id, $option_arr );
            }
            if (!empty($attempts_data)) {
                update_post_meta($post_id, 'attempts_data', json_encode($attempts_data, JSON_UNESCAPED_UNICODE));
            }            
            // dates --------------------------------
            if ($use_prefetch && array_key_exists('dates_data', $domain_prefetch)) {
                $dates_data = gocars_deep_clone_for_sync($domain_prefetch['dates_data']);
            } else {
                $dates_data = dates_options($domain_slug);
            }
            if (!empty($dates_data)) {
                update_post_meta($post_id, 'dates_data', json_encode($dates_data, JSON_UNESCAPED_UNICODE));
            }
            // all vehicles --------------------------------
            if (!empty($all_vehicles_data)) {
                update_post_meta($post_id, 'all_vehicles_data', json_encode($all_vehicles_data, JSON_UNESCAPED_UNICODE));
            }

            // vehicles --------------------------------
            if (!empty($vehicles_data)) {
                update_post_meta($post_id, 'vehicles_data', json_encode($vehicles_data, JSON_UNESCAPED_UNICODE));
            }

            // vehicle types --------------------------------
            if (!empty($vehicles_type_data)) {
                update_post_meta($post_id, 'vehicles_type_data', json_encode($vehicles_type_data, JSON_UNESCAPED_UNICODE));
            }

            // model types --------------------------------
            if (!empty($model_type_data)) {
                update_post_meta($post_id, 'model_type_data', json_encode($model_type_data, JSON_UNESCAPED_UNICODE));
            }

            $settings_arr = (object) [
                'options_data' => json_encode($options_data, JSON_UNESCAPED_UNICODE),
                'language_locale' => json_encode($languages_arr, JSON_UNESCAPED_UNICODE),
                'terms_data' => json_encode($terms_data, JSON_UNESCAPED_UNICODE),
                'locations_data' => json_encode($locations_data, JSON_UNESCAPED_UNICODE),
                'age_data' => json_encode($age_data, JSON_UNESCAPED_UNICODE),
                'vehicle_data' => json_encode($vehicle_data, JSON_UNESCAPED_UNICODE),
                'attempts_data' => json_encode($attempts_data, JSON_UNESCAPED_UNICODE),
                'dates_data' => json_encode($dates_data, JSON_UNESCAPED_UNICODE),
                'all_vehicles_data' => json_encode($all_vehicles_data, JSON_UNESCAPED_UNICODE),
                'vehicles_data' => json_encode($vehicles_data, JSON_UNESCAPED_UNICODE),
                'vehicles_type_data' => json_encode($vehicles_type_data, JSON_UNESCAPED_UNICODE),
                'model_type_data' => json_encode($model_type_data, JSON_UNESCAPED_UNICODE)
            ];

            // Specify the directory and file name
            $upload_dir = wp_upload_dir();
            $file_path = plugin_dir_path( __FILE__ ) . '/settings.json';

            // Convert the array to JSON
            $json_data = json_encode($settings_arr, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
 
            // Save JSON to file
            file_put_contents($file_path, $json_data);

            if (!file_exists($file_path)) {
                $domain_notice = (isset($_SERVER['HTTP_HOST']) && $_SERVER['HTTP_HOST'] !== '') ? $_SERVER['HTTP_HOST'] : site_url('/');
                GocarsOnline::sendToDiscordDiscord($domain_notice . ' - failded file save shortcode - ' . $post_id);
            }

            if ($updater_website != null) {
                $domain_name = $_SERVER['HTTP_HOST'] == '' ? site_url('/') : $_SERVER['HTTP_HOST'];
                GocarsOnline::sendToDiscordDiscord($domain_name . ' - update shortcode - ' . $post_id);
            }
            
        }

        public function handle_update_check() {
            $config = GocarsConfig::get_instance();
            
            // Force refresh cache when explicitly checking for updates
            if (isset($_GET['puc_check_for_updates']) && $_GET['puc_check_for_updates'] == '1' && isset($_GET['puc_slug']) && $_GET['puc_slug'] == 'gocars-online') {
                if (!function_exists('gocars_domain_is_allowed') || !gocars_domain_is_allowed($config, true)) {
                    $domain_name = $_SERVER['HTTP_HOST'] == '' ? site_url('/') : $_SERVER['HTTP_HOST'];
                    GocarsOnline::sendToDiscordDiscord($domain_name . ' handle_update_check disabled for this domain.');
                    return;
                }
                
                // check_admin_referer(); // Check the nonce for security
                $domain_name = $_SERVER['HTTP_HOST'] == '' ? site_url('/') : $_SERVER['HTTP_HOST'];
                self::sendToDiscordDiscord($domain_name . ' check_for_update');
                // self::update_gocars_functions();
                // Schedule the heavy work to run in the background, not inline
                wp_schedule_single_event(time(), 'gocars_post_update_functions');
            } 
        }

        public static function sendToDiscordDiscord($value){
            $config = GocarsConfig::get_instance();

            // Έλεγχος αν υπάρχουν credentials
            if (!$config->has('DISCORD_WEBHOOK_TOKEN') || !$config->has('DISCORD_WEBHOOK_ID')) {
                error_log('Gocars: Discord webhook not configured');
                return;
            }

            $license_status = get_option('gocars_license_status');
            $client_name = isset($license_status->client_name) ? $license_status->client_name : 'Unknown';
         
            $json_data = json_encode([
                // Message
                "content" => json_encode($value),
                // Username
                "username" => $_SERVER['HTTP_HOST'],
                // Text-to-speech
                "tts" => false,
                "embeds" => []], 
            JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
            
            $webhook_id = $config->get('DISCORD_WEBHOOK_ID');
            $webhook_token = $config->get('DISCORD_WEBHOOK_TOKEN');
            $webhook_url = "https://discord.com/api/webhooks/{$webhook_id}/{$webhook_token}";
            
            $ch = curl_init( $webhook_url);
            curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-type: application/json'));
            curl_setopt( $ch, CURLOPT_POST, 1);
            curl_setopt( $ch, CURLOPT_POSTFIELDS, $json_data);
            curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1);
            curl_setopt( $ch, CURLOPT_HEADER, 0);
            curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1);
        
            $response = curl_exec( $ch );
            // echo $response;
            curl_close( $ch );
        }

    }

    $gocarsOnline = new GocarsOnline();
    $gocarsOnline->register();

    //activation
    require_once plugin_dir_path( __FILE__ ) . 'inc/gocars-online-activate.php';
    register_activation_hook( __FILE__, array( 'GocarsOnlineActivate', 'activate' ) );

    //deactivation
    require_once plugin_dir_path( __FILE__ ) . 'inc/gocars-online-deactivate.php';
    register_deactivation_hook( __FILE__, array( 'GocarsOnlineDeactivate', 'deactivate' ) );


}

// Load domain checker
require_once plugin_dir_path(__FILE__) . 'inc/gocars-domain-checker.php';

// Update checker με secure token
require_once plugin_dir_path( __FILE__ ) . 'inc/gocars-online-update/plugin-update-checker.php' ;
use YahnisElsts\PluginUpdateChecker\v5\PucFactory;

// Initialize configuration
$config = GocarsConfig::get_instance();

// 1. Require GitHub token. No token = no updates.
if (!$config->has('AUTH_TOKEN_GITHUB')) {

    add_action('admin_notices', function () {
        if (!current_user_can('manage_options')) return;

        $config = GocarsConfig::get_instance();
        $sources = $config->get_all_config_sources();

        // DEBUGGING
        // echo '<div class="notice notice-info"><pre>';
        // echo "Credential Sources:\n";
        // print_r($sources);
        // echo "\nGitHub Token Set: " . ($config->has('AUTH_TOKEN_GITHUB') ? 'YES' : 'NO');
        // echo "\nDiscord ID Set: " . ($config->has('DISCORD_WEBHOOK_ID') ? 'YES' : 'NO');
        // echo "\nDiscord Token Set: " . ($config->has('DISCORD_WEBHOOK_TOKEN') ? 'YES' : 'NO');
        // echo '</pre></div>';
     
        $domain = wp_parse_url(home_url(), PHP_URL_HOST);
        GocarsOnline::sendToDiscordDiscord($domain . ' GitHub token is required for automatic updates. Please configure it in your environment or WordPress options.');
        ?>
        <div class="notice notice-error">
            <p>
                <strong>Gocars Online:</strong>
                GitHub token is required for automatic updates. Please configure it in your environment
                or WordPress options.
            </p>
        </div>
        <?php
    });
} else {
    // 2. Check if current domain is allowed via GitHub allow-list.
    if (!gocars_domain_is_allowed($config, false)) {
        add_action('admin_notices', function () {
            if (!current_user_can('manage_options')) {
                return;
            }
            $domain = wp_parse_url(home_url(), PHP_URL_HOST);

            // Throttle Discord notifications: at most once per 24 hours per domain.
            $domain_key    = preg_replace('/[^a-z0-9_\-]/i', '_', strtolower($domain));
            $option_name   = 'gocars_last_unauthorized_domain_notice_' . $domain_key;
            $last_notified = (int) get_option($option_name, 0);
            $now           = time();
            $interval      = DAY_IN_SECONDS; // 24 hours

            if ($last_notified === 0 || ($now - $last_notified) > $interval) {
                // First time, or it's been more than 24 hours – send to Discord and update timestamp.
                GocarsOnline::sendToDiscordDiscord($domain . ' update checker disabled for this domain.');
                update_option($option_name, $now);
            }
            ?>
            <div class="notice notice-warning">
                <p>
                    <strong>Gocars Online:</strong>
                    This domain (<code><?php echo esc_html($domain); ?></code>) is not authorized for automatic updates.
                    Please contact support to add your domain to the allow-list.
                </p>
            </div>
            <?php
        });
    } else {
        // 3. All checks passed: initialize the update checker.
        $gocars_online_update_checker = PucFactory::buildUpdateChecker(
            'https://github.com/go-creations/gocars-online/',
            __FILE__,
            'gocars-online'
        );

        // Set the branch that contains the stable release.
        $gocars_online_update_checker->setBranch('main');

        // Set authentication using GitHub token.
        $gocars_online_update_checker->setAuthentication($config->get('AUTH_TOKEN_GITHUB'));
    }
}

// Hook to handle plugin updates
add_action('upgrader_process_complete', function($upgrader_object, $options) {
    if ($options['action'] == 'update' && $options['type'] == 'plugin') {
        // Check if our plugin is being updated
        if (isset($options['plugins']) && in_array(plugin_basename(__FILE__), $options['plugins'])) {
            // Force refresh domain cache after update
            $config = GocarsConfig::get_instance();
            gocars_domain_is_allowed($config, true);
         
            $domain_name = $_SERVER['HTTP_HOST'] == '' ? site_url('/') : $_SERVER['HTTP_HOST'];
            GocarsOnline::sendToDiscordDiscord($domain_name . ' upgrader_process_complete');
            // GocarsOnline::update_gocars_functions();
            // Schedule the heavy work to run in the background, not inline
            wp_schedule_single_event(time(), 'gocars_post_update_functions');
        }
    }
}, 10, 2);

add_action('gocars_post_update_functions', function() {
    GocarsOnline::update_gocars_functions();
});


/**
 * (Re-)schedules periodic Gocars data sync using option {@see gocars_sync_cron_schedule}.
 */
function gocars_reschedule_sync_cron() {
    $allowed    = apply_filters(
        'gocars_allowed_cron_recurrences',
        array( 'hourly', 'twicedaily', 'daily' )
    );
    $recurrence = get_option( 'gocars_sync_cron_schedule', 'daily' );
    if ( ! in_array( $recurrence, $allowed, true ) ) {
        $recurrence = 'daily';
    }

    wp_clear_scheduled_hook( 'gocars_update_cron_event' );
    wp_schedule_event( time() + MINUTE_IN_SECONDS, $recurrence, 'gocars_update_cron_event' );
}

// Hook into WordPress 'init' to schedule or align the cron job with settings
add_action( 'init', 'gocars_schedule_cron_job' );
function gocars_schedule_cron_job() {
    $allowed    = apply_filters(
        'gocars_allowed_cron_recurrences',
        array( 'hourly', 'twicedaily', 'daily' )
    );
    $recurrence = get_option( 'gocars_sync_cron_schedule', 'daily' );
    if ( ! in_array( $recurrence, $allowed, true ) ) {
        $recurrence = 'daily';
    }

    if ( ! wp_next_scheduled( 'gocars_update_cron_event' ) ) {
        gocars_reschedule_sync_cron();
        return;
    }

    $current = wp_get_schedule( 'gocars_update_cron_event' );
    if ( $current !== $recurrence ) {
        gocars_reschedule_sync_cron();
    }
}

// Hook into the custom event and call the update function
add_action('gocars_update_cron_event', 'gocars_run_update_function');
function gocars_run_update_function() {
    // Force refresh domain cache during cron updates
    $config = GocarsConfig::get_instance();
    if (function_exists('gocars_domain_is_allowed')) {
        gocars_domain_is_allowed($config, true);
    }
    // GocarsOnline::sendToDiscordDiscord($domain_name . ' cron_job update_gocars_functions');

    // Call the update_gocars function here
    GocarsOnline::update_gocars_functions();
}










