<?php

// phpcs:disable WordPress.Security.NonceVerification.Missing
// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
// phpcs:disable PluginCheck.CodeAnalysis.Offloading.OffloadedContent
// phpcs:disable PluginCheck.CodeAnalysis.EnqueuedResourceOffloading.OffloadedContent
// phpcs:disable WordPress.WP.EnqueuedResources.NonEnqueuedScript
// phpcs:disable WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet
/**
 * Plugin Name: SahlDesk
 * Description: Advanced ticketing system to centralize customer support with the ultimate WooCommerce helpdesk built directly into your dashboard.
 * License: GPLv2 or later
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 * Version: 1.5.13
 * Author: SahlDesk
 * Author URI: https://sahldesk.com/
 * Text Domain: sahldesk
 */
if ( !defined( 'ABSPATH' ) ) {
    exit;
    // Exit if accessed directly.
}
// FATAL ERROR CATCHER FOR DEBUGGING
if ( !function_exists( 'ts_fatal_error_catcher' ) ) {
    function ts_fatal_error_catcher() {
        $error = error_get_last();
        if ( $error !== null && in_array( $error['type'], array(
            E_ERROR,
            E_CORE_ERROR,
            E_COMPILE_ERROR,
            E_USER_ERROR,
            E_PARSE
        ) ) ) {
            $message = gmdate( 'Y-m-d H:i:s' ) . " FATAL ERROR: " . $error['message'] . " in " . $error['file'] . " on line " . $error['line'] . "\n";
            // 1. Write to uploads directory (guaranteed writable)
            $upload_dir = wp_upload_dir();
            $log_file = $upload_dir['basedir'] . '/ts-fatal-error.txt';
            @file_put_contents( $log_file, $message, FILE_APPEND );
            // 2. Also log to standard PHP error log
            /* phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log */
            error_log( "SAHLDESK DEBUG: " . $message );
            // 3. Save to database option as an ultimate fallback!
            update_option( 'ts_last_fatal_error', $message );
        }
    }

    register_shutdown_function( 'ts_fatal_error_catcher' );
}
if ( !function_exists( 'sahldesk_fs' ) ) {
    // Create a helper function for easy SDK access.
    function sahldesk_fs() {
        global $sahldesk_fs;
        if ( !isset( $sahldesk_fs ) ) {
            // Include Freemius SDK.
            require_once dirname( __FILE__ ) . '/vendor/freemius/start.php';
            $sahldesk_fs = fs_dynamic_init( array(
                'id'               => '23268',
                'slug'             => 'sahldesk',
                'type'             => 'plugin',
                'public_key'       => 'pk_22da665e521f5fdea813737e64420',
                'is_premium'       => false,
                'is_premium'       => false,
                'premium_suffix'   => 'Pro',
                'anonymous_mode'   => false,
                'has_addons'       => false,
                'has_paid_plans'   => true,
                'is_org_compliant' => false,
                'menu'             => array(
                    'slug'    => 'ts_settings_page',
                    'support' => false,
                    'contact' => false,
                    'pricing' => false,
                    'account' => true,
                ),
                'is_live'          => true,
            ) );
        }
        return $sahldesk_fs;
    }

}
if ( !function_exists( 'sahldesk_fs_checkout_locale' ) ) {
    function sahldesk_fs_checkout_locale(  $params  ) {
        $is_ar = strpos( get_locale(), 'ar' ) === 0;
        $params['language'] = ( $is_ar ? 'ar' : 'en' );
        $params['locale'] = ( $is_ar ? 'ar' : 'en' );
        return $params;
    }

}
add_filter( 'fs_checkout/parameters_sahldesk', 'sahldesk_fs_checkout_locale' );
// Dynamically rename the plugin to 'SahlDesk Pro' in WP Admin if the user has a paying license
if ( !function_exists( 'ts_dynamically_rename_plugin_to_pro' ) ) {
    function ts_dynamically_rename_plugin_to_pro(  $all_plugins  ) {
        if ( function_exists( 'sahldesk_fs' ) && sahldesk_fs()->can_use_premium_code() ) {
            $plugin_basename = plugin_basename( __FILE__ );
            if ( isset( $all_plugins[$plugin_basename] ) ) {
                $all_plugins[$plugin_basename]['Name'] = 'SahlDesk Pro';
            }
        }
        return $all_plugins;
    }

}
add_filter( 'all_plugins', 'ts_dynamically_rename_plugin_to_pro' );
// phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
// Inject language into $_GET for the Pricing Page React App and Hosted Checkout redirect URLs
// phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
if ( is_admin() && isset( $_GET['page'] ) ) {
    // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
    if ( strpos( sanitize_text_field( wp_unslash( $_GET['page'] ) ), 'sahldesk' ) !== false || strpos( sanitize_text_field( wp_unslash( $_GET['page'] ) ), 'ts_settings_page' ) !== false ) {
        $is_ar = strpos( get_locale(), 'ar' ) === 0;
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        $_GET['language'] = ( $is_ar ? 'ar' : 'en' );
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        $_GET['locale'] = ( $is_ar ? 'ar' : 'en' );
    }
}
// Force Freemius Checkout Manager to allow custom 'language' and 'locale' params so our filter works
add_action( 'admin_init', function () {
    if ( class_exists( 'FS_Checkout_Manager' ) ) {
        try {
            $checkout_manager = FS_Checkout_Manager::instance();
            $reflection = new ReflectionClass($checkout_manager);
            $property = $reflection->getProperty( '_allowed_custom_params' );
            $property->setAccessible( true );
            $allowed = $property->getValue( $checkout_manager );
            $allowed['language'] = true;
            $allowed['locale'] = true;
            $property->setValue( $checkout_manager, $allowed );
        } catch ( Exception $e ) {
            // Ignore reflection errors if the API changes
        }
    }
} );
// Intercept FS.Checkout and Freemius.pricing.new via property descriptors to force Arabic
// Intercept IFrame creation to force Arabic locale on the Freemius Checkout URL
add_action( 'admin_print_scripts', function () {
    ?>
    <script>
    (function(){
        // 1. Intercept document.createElement
        var origCreateElement = document.createElement;
        document.createElement = function(tagName) {
            var el = origCreateElement.apply(this, arguments);
            if (tagName && tagName.toLowerCase() === 'iframe') {
                // Trap the setAttribute method
                var origSetAttribute = el.setAttribute;
                el.setAttribute = function(name, value) {
                    if (name.toLowerCase() === 'src' && value && typeof value === 'string' && value.indexOf('checkout.freemius.com') !== -1) {
                        if (value.indexOf('language=ar') === -1) {
                            value += (value.indexOf('?') !== -1 ? '&' : '?') + 'language=ar&locale=ar';
                        }
                    }
                    return origSetAttribute.call(this, name, value);
                };

                // Trap the src property assignment
                var origSrcDescriptor = Object.getOwnPropertyDescriptor(HTMLIFrameElement.prototype, 'src');
                if (origSrcDescriptor) {
                    Object.defineProperty(el, 'src', {
                        configurable: true,
                        get: function() {
                            return origSrcDescriptor.get.call(this);
                        },
                        set: function(val) {
                            if (val && typeof val === 'string' && val.indexOf('checkout.freemius.com') !== -1) {
                                if (val.indexOf('language=ar') === -1) {
                                    val += (val.indexOf('?') !== -1 ? '&' : '?') + 'language=ar&locale=ar';
                                }
                            }
                            return origSrcDescriptor.set.call(this, val);
                        }
                    });
                }
            }
            return el;
        };

        // 2. MutationObserver as a fallback
        document.addEventListener('DOMContentLoaded', function() {
            var observer = new MutationObserver(function(mutations) {
                mutations.forEach(function(mutation) {
                    if (mutation.addedNodes) {
                        for (var i = 0; i < mutation.addedNodes.length; i++) {
                            var node = mutation.addedNodes[i];
                            if (node.tagName === 'IFRAME') {
                                if (node.src && node.src.indexOf('checkout.freemius.com') !== -1) {
                                    if (node.src.indexOf('language=ar') === -1) {
                                        node.src = node.src + (node.src.indexOf('?') !== -1 ? '&' : '?') + 'language=ar&locale=ar';
                                    }
                                }
                            }
                        }
                    }
                });
            });
            observer.observe(document.body, { childList: true, subtree: true });
        });
    })();
    </script>
    <?php 
}, 0 );
// Init Freemius.
sahldesk_fs();
// Signal that SDK was initiated.
do_action( 'sahldesk_fs_loaded' );
if ( !defined( 'TS_PLUGIN_VERSION' ) ) {
    define( 'TS_PLUGIN_VERSION', '1.5.13' );
}
// Disable default Freemius pricing page to use our own
add_filter( 'fs_is_pricing_page_visible_sahldesk', '__return_false' );
// Force Freemius to use our SVG logo
add_filter( 'fs_plugin_icon_sahldesk', function ( $icon_path ) {
    return plugin_dir_path( __FILE__ ) . 'assets/logo.svg';
} );
// Helper to safely get plugin page URLs even if slug changes
if ( !function_exists( 'ts_get_page_url' ) ) {
    function ts_get_page_url(  $slug, $title = ''  ) {
        try {
            // 1. Try exact slug
            $page = get_page_by_path( $slug );
            if ( $page ) {
                return get_permalink( $page->ID );
            }
            // 2. Try removing -ar if it's an Arabic slug
            $base_slug = str_replace( '-ar', '', $slug );
            if ( $base_slug !== $slug ) {
                $page = get_page_by_path( $base_slug );
                if ( $page ) {
                    return get_permalink( $page->ID );
                }
            }
            // 3. Try appending -ar if it's an English slug
            if ( strpos( $slug, '-ar' ) === false ) {
                $ar_slug = $slug . '-ar';
                $page = get_page_by_path( $ar_slug );
                if ( $page ) {
                    return get_permalink( $page->ID );
                }
            }
            // 4. Try shortcode search (Most reliable fallback if slug changed)
            global $wpdb;
            if ( $wpdb ) {
                $shortcode = '';
                if ( strpos( $slug, 'dashboard' ) !== false ) {
                    $shortcode = 'ticketing_system_dashboard';
                } elseif ( strpos( $slug, 'login' ) !== false ) {
                    $shortcode = 'ticketing_system_login';
                } elseif ( strpos( $slug, 'create' ) !== false ) {
                    $shortcode = 'ticketing_system_create';
                } elseif ( strpos( $slug, 'view' ) !== false ) {
                    $shortcode = 'ticketing_system_view_ticket';
                } elseif ( strpos( $slug, 'register' ) !== false ) {
                    $shortcode = 'ticketing_system_register';
                } elseif ( strpos( $slug, 'forgot-password' ) !== false ) {
                    $shortcode = 'ticketing_system_forgot_password';
                } elseif ( strpos( $slug, 'reset-password' ) !== false ) {
                    $shortcode = 'ticketing_system_reset_password';
                }
                if ( $shortcode ) {
                    // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared
                    $query = $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_type='page' AND post_status='publish' AND post_content LIKE %s LIMIT 1", '%' . $shortcode . '%' );
                    // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared
                    $post_id = $wpdb->get_var( $query );
                    if ( $post_id ) {
                        return get_permalink( $post_id );
                    }
                }
            }
        } catch ( Exception $e ) {
            // Silently catch any errors to prevent critical crashes
        }
        // 5. Absolute fallback
        return home_url( '/' . $slug . '/' );
    }

}
// --- SAHLDESK LOGGING ---
if ( !function_exists( 'ts_log' ) ) {
    function ts_log(  $message, $level = 'ERROR'  ) {
        $upload_dir = wp_upload_dir();
        $log_dir = $upload_dir['basedir'] . '/sahldesk-logs';
        // Create directory if it doesn't exist
        if ( !file_exists( $log_dir ) ) {
            wp_mkdir_p( $log_dir );
            // Protect directory
            file_put_contents( $log_dir . '/.htaccess', "Order deny,allow\nDeny from all" );
            file_put_contents( $log_dir . '/index.php', "<?php // Silence is golden" );
        }
        $log_file = $log_dir . '/plugin.log';
        $time = current_time( 'mysql' );
        $formatted_message = "[{$time}] [{$level}] " . wp_json_encode( $message, true ) . PHP_EOL;
        // Write to file securely
        @file_put_contents( $log_file, $formatted_message, FILE_APPEND | LOCK_EX );
    }

}
// --- CONFIGURATION ---
$ts_http_host = ( isset( $_SERVER['HTTP_HOST'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) : '' );
// Allow wp-config.php to override the API URL for local testing
if ( defined( 'TS_API_CUSTOM_BASE_URL' ) ) {
    define( 'TS_API_BASE_URL', TS_API_CUSTOM_BASE_URL );
} elseif ( strpos( $ts_http_host, '.local' ) !== false || strpos( $ts_http_host, 'localhost' ) !== false || defined( 'WP_FS__IS_LOCALHOST' ) && WP_FS__IS_LOCALHOST ) {
    // Point local sites directly to the local .NET API we are building!
    define( 'TS_API_BASE_URL', 'https://localhost:7149/api/v1' );
} elseif ( strpos( $ts_http_host, 'staging-wp' ) !== false || strpos( $ts_http_host, 'demo' ) !== false ) {
    define( 'TS_API_BASE_URL', 'https://staging-api.sahldesk.com/api/v1' );
} else {
    // Production API
    define( 'TS_API_BASE_URL', 'https://api.sahldesk.com/api/v1' );
}
// --- FREEMIUS SYNC LOGIC ---
// Added optional arguments to support the Freemius hook requirements
if ( !function_exists( 'ts_sync_license_with_backend' ) ) {
    function ts_sync_license_with_backend(  $user = null, $site = null, $is_first_connection = null  ) {
        // Clear pricing cache so that Sync License also pulls fresh prices from Freemius
        delete_transient( 'ts_fs_plans_cache_v6' );
        ts_log( 'TS_SYNC: Starting sync process...' );
        $license_key = '';
        $admin_email = get_option( 'admin_email' );
        $site_id = '';
        $public_key = '';
        $freemius_license_id = null;
        // If Freemius is active and registered, grab its data
        ts_log( 'Freemius Check - function_exists: ' . (( function_exists( 'sahldesk_fs' ) ? 'YES' : 'NO' )) );
        if ( function_exists( 'sahldesk_fs' ) ) {
            ts_log( 'Freemius Check - is_registered: ' . (( sahldesk_fs()->is_registered() ? 'YES' : 'NO' )) );
            ts_log( 'Freemius Check - is_anonymous: ' . (( sahldesk_fs()->is_anonymous() ? 'YES' : 'NO' )) );
            ts_log( 'Freemius Check - is_pending_activation: ' . (( sahldesk_fs()->is_pending_activation() ? 'YES' : 'NO' )) );
        }
        if ( function_exists( 'sahldesk_fs' ) && sahldesk_fs()->is_registered() ) {
            $fs = sahldesk_fs();
            $license = $fs->_get_license();
            $site = $fs->get_site();
            if ( $site ) {
                $site_id = $site->id;
                $public_key = $site->public_key;
                ts_log( 'Freemius Check - Site ID: ' . $site_id );
            } else {
                ts_log( 'Freemius Check - get_site() returned null!' );
            }
            $fs_user = $fs->get_user();
            $fs_site = $fs->get_site();
            if ( is_object( $license ) ) {
                $license_key = $license->secret_key;
                $freemius_license_id = $license->id;
            }
            if ( $fs_user && !empty( $fs_user->email ) ) {
                $admin_email = $fs_user->email;
            }
            if ( $fs_site ) {
                $site_id = $fs_site->id;
                $public_key = $fs_site->public_key;
            }
        }
        // Updated to point to the correct .NET API endpoint for Freemius activation
        $api_url = TS_API_BASE_URL . '/freemius/activate';
        // Updated payload keys to match the .NET ActivationRequest model
        $body = [
            'LicenseKey' => $license_key,
            'Domain'     => home_url(),
            'Email'      => $admin_email,
            'Plan'       => ( function_exists( 'sahldesk_fs' ) && sahldesk_fs()->can_use_premium_code() ? 'Pro' : 'Free' ),
        ];
        ts_log( 'TS_SYNC: Sending POST request to ' . $api_url . ' with payload: ' . json_encode( $body ) );
        $response = wp_remote_post( $api_url, [
            'headers'     => [
                'Content-Type' => 'application/json',
            ],
            'body'        => json_encode( $body ),
            'timeout'     => 15,
            'data_format' => 'body',
        ] );
        if ( is_wp_error( $response ) ) {
            $error_msg = $response->get_error_message();
            ts_log( 'TS_SYNC: Failed (WP_Error/cURL): ' . $error_msg );
            update_option( 'ts_last_sync_error', 'cURL Error: ' . $error_msg );
            return false;
        }
        $response_code = wp_remote_retrieve_response_code( $response );
        $response_body = wp_remote_retrieve_body( $response );
        ts_log( 'TS_SYNC: Received HTTP ' . $response_code . ' from .NET API. Body: ' . $response_body );
        if ( $response_code == 200 ) {
            $data = json_decode( $response_body, true );
            $api_key = ( isset( $data['apiKey'] ) ? $data['apiKey'] : (( isset( $data['ApiKey'] ) ? $data['ApiKey'] : '' )) );
            if ( !empty( $api_key ) ) {
                update_option( 'ts_tenant_api_key', sanitize_text_field( $api_key ) );
                delete_option( 'ts_last_sync_error' );
                // Clear errors on success
                delete_transient( 'ts_sync_lock' );
                // Unlock syncing
                // Trigger setup wizard if it hasn't been completed yet
                if ( get_option( 'ts_setup_wizard_completed' ) !== 'yes' ) {
                    update_option( 'ts_needs_setup_wizard', 'yes' );
                }
                ts_log( 'TS_SYNC: Success! API Key securely saved.' );
                return true;
            } else {
                ts_log( 'TS_SYNC: Failed. API responded with 200 OK but missing apiKey in JSON payload.' );
            }
        } else {
            update_option( 'ts_last_sync_error', 'HTTP ' . $response_code . ': ' . $response_body );
        }
        return false;
    }

}
if ( !function_exists( 'ts_clear_backend_license' ) ) {
    function ts_clear_backend_license() {
        delete_option( 'ts_tenant_api_key' );
    }

}
// Redirect to setup wizard if needed
add_action( 'admin_init', 'ts_setup_wizard_redirect' );
if ( !function_exists( 'ts_setup_wizard_redirect' ) ) {
    function ts_setup_wizard_redirect() {
        // Only redirect if they need the wizard, are in admin, not doing AJAX, and not already on the wizard page
        if ( get_option( 'ts_needs_setup_wizard' ) === 'yes' && is_admin() && !wp_doing_ajax() ) {
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $page = ( isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '' );
            // Allow Freemius pages to load so they can finish checkout/opt-in without interruption
            if ( $page !== 'ts-setup-wizard' && strpos( $page, 'my-ticketing-system' ) === false && strpos( $page, 'sahldesk' ) === false ) {
                wp_safe_redirect( admin_url( 'admin.php?page=ts-setup-wizard' ) );
                exit;
            }
        }
    }

}
// Hook into Freemius events
if ( function_exists( 'sahldesk_fs' ) ) {
    sahldesk_fs()->add_action( 'after_license_activation', 'ts_sync_license_with_backend' );
    sahldesk_fs()->add_action( 'after_license_change', 'ts_sync_license_with_backend' );
    sahldesk_fs()->add_action( 'after_license_deactivation', 'ts_clear_backend_license' );
    sahldesk_fs()->add_action(
        'after_account_connection',
        'ts_sync_license_with_backend',
        10,
        3
    );
}
// Auto-heal: Attempt sync if API key is missing
add_action( 'init', 'ts_auto_sync_tenant_api_key', 1 );
// Priority 1 ensures it runs before frontend forms
if ( !function_exists( 'ts_auto_sync_tenant_api_key' ) ) {
    function ts_auto_sync_tenant_api_key() {
        $api_key = get_option( 'ts_tenant_api_key' );
        // Auto-heal: If the saved API key is the old invalid format, delete it and force a sync instantly.
        if ( !empty( $api_key ) && strlen( $api_key ) !== 36 && strlen( $api_key ) !== 32 ) {
            delete_option( 'ts_tenant_api_key' );
            ts_sync_license_with_backend();
            return;
        }
        // Only run missing key background sync for admins to prevent frontend slowdowns
        if ( empty( $api_key ) && current_user_can( 'manage_options' ) && !get_transient( 'ts_sync_lock' ) ) {
            set_transient( 'ts_sync_lock', true, 5 * MINUTE_IN_SECONDS );
            // Reduced to 5 mins for easier debugging
            ts_sync_license_with_backend();
        }
    }

}
// --- API REQUEST HELPER ---
if ( !function_exists( 'ts_api_request' ) ) {
    function ts_api_request(  $endpoint, $method = 'GET', $body = null  ) {
        $api_key = get_option( 'ts_tenant_api_key' );
        if ( empty( $api_key ) ) {
            return false;
            // Not authenticated
        }
        // Endpoint is appended to the base URL
        $url = TS_API_BASE_URL . $endpoint;
        $args = [
            'method'      => strtoupper( $method ),
            'headers'     => [
                'Content-Type' => 'application/json',
                'X-Api-Key'    => $api_key,
            ],
            'timeout'     => 15,
            'data_format' => 'body',
        ];
        if ( $body !== null ) {
            $args['body'] = json_encode( $body );
        }
        $response = wp_remote_request( $url, $args );
        if ( is_wp_error( $response ) ) {
            ts_log( 'SahlDesk API Error: ' . $response->get_error_message() );
            return false;
        }
        return json_decode( wp_remote_retrieve_body( $response ), true );
    }

}
// --- AGENT SYNC LOGIC ---
if ( !function_exists( 'ts_sync_new_agent' ) ) {
    function ts_sync_new_agent(  $user_id  ) {
        $user = get_userdata( $user_id );
        if ( $user && in_array( 'sahldesk_agent', (array) $user->roles ) ) {
            $body = [
                'email'        => $user->user_email,
                'display_name' => $user->display_name,
            ];
            ts_api_request( '/plugin/agents', 'POST', $body );
        }
    }

}
add_action( 'user_register', 'ts_sync_new_agent' );
if ( !function_exists( 'ts_sync_deleted_agent' ) ) {
    function ts_sync_deleted_agent(  $user_id  ) {
        $user = get_userdata( $user_id );
        if ( $user && in_array( 'sahldesk_agent', (array) $user->roles ) ) {
            ts_api_request( '/plugin/agents?email=' . urlencode( $user->user_email ), 'DELETE' );
        }
    }

}
add_action( 'deleted_user', 'ts_sync_deleted_agent' );
// --- LICENSE MANAGER LOGIC (MOVED UP) ---
// We define the function immediately so we can use it to set the constant
// --- NEW LICENSE LOGIC WITH FREEMIUS ---
if ( !function_exists( 'ts_check_license_status' ) ) {
    function ts_check_license_status() {
        // 1. Check if Freemius is active and valid
        if ( function_exists( 'sahldesk_fs' ) && sahldesk_fs()->can_use_premium_code() ) {
            return 'Pro';
            // Freemius says they paid!
        }
        return 'Free';
    }

}
// DEFINE THE CONSTANT NOW
if ( !defined( 'TS_IS_PRO' ) ) {
    $current_plan = ts_check_license_status();
    define( 'TS_IS_PRO', $current_plan === 'Pro' );
}
// Freemium Flag: Set to 'true' to see Pro features (User Mgt, Canned Responses)
//if (!defined('TS_IS_PRO')) {define('TS_IS_PRO', true); }
// 1. CONDITIONAL SESSION START
// Handle Magic Link Login early so redirects work
// Old init hook removed
// add_action('init', 'ts_handle_magic_link_login');
if ( !function_exists( 'ts_handle_magic_link_login' ) ) {
    function ts_handle_magic_link_login() {
        // Step 1: Catch the magic token and display a loading screen immediately.
        // We use JS to trigger the actual processing so the browser renders the loading screen while waiting.
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_GET['magic_token'] ) ) {
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $magic_token = sanitize_text_field( wp_unslash( $_GET['magic_token'] ) );
            $process_url = add_query_arg( 'process_magic_token', $magic_token );
            $process_url = remove_query_arg( 'magic_token', $process_url );
            echo '<!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>' . ts_t( 'Authenticating...' ) . '</title>
            <style>
                body { margin: 0; padding: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; background: #f8fafc; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; color: #1e293b; }
                .ts-spinner { width: 50px; height: 50px; border: 4px solid #e2e8f0; border-top-color: #3b82f6; border-radius: 50%; animation: ts-spin 1s linear infinite; margin-bottom: 25px; }
                @keyframes ts-spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
                h2 { font-size: 22px; font-weight: 600; margin: 0 0 10px 0; }
                p { font-size: 15px; color: #64748b; margin: 0; }
            </style>
        </head>
        <body>
            <div class="ts-spinner"></div>
            <h2>' . ts_t( 'Authenticating your secure link...' ) . '</h2>
            <p>' . ts_t( 'Please wait a moment while we verify your access.' ) . '</p>
            <script>
                // Instantly navigate to the processing URL. The browser will keep this loading screen visible!
                window.location.replace("' . esc_js( $process_url ) . '");
            </script>
        </body>
        </html>';
            exit;
        }
        // Step 2: Actually process the token and set the session
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_GET['process_magic_token'] ) ) {
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $magic_token = sanitize_text_field( wp_unslash( $_GET['process_magic_token'] ) );
            $api_url = TS_API_BASE_URL . '/users/magic-login';
            $api_key = get_option( 'ts_tenant_api_key', '' );
            $domain = get_option( 'ts_tenant_domain', '' );
            $response = wp_remote_post( $api_url, [
                'headers'     => [
                    'Content-Type'    => 'application/json',
                    'X-Api-Key'       => $api_key,
                    'X-Client-Domain' => $domain,
                ],
                'body'        => json_encode( [
                    'Token' => $magic_token,
                ] ),
                'data_format' => 'body',
                'timeout'     => 15,
            ] );
            if ( !is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) == 200 ) {
                $body = json_decode( wp_remote_retrieve_body( $response ), true );
                if ( isset( $body['token'] ) ) {
                    if ( !session_id() ) {
                        session_start();
                    }
                    $_SESSION['ts_auth_token'] = $body['token'];
                    $_SESSION['ts_user_role'] = $body['role'];
                    $_SESSION['ts_user_name'] = $body['name'];
                    session_write_close();
                    // Set cookies to survive edge caching stripping PHPSESSID
                    setcookie(
                        'wordpress_logged_in_ts_auth_token',
                        $body['token'],
                        time() + 86400 * 7,
                        COOKIEPATH,
                        COOKIE_DOMAIN,
                        is_ssl(),
                        true
                    );
                    setcookie(
                        'wordpress_logged_in_ts_user_role',
                        $body['role'],
                        time() + 86400 * 7,
                        COOKIEPATH,
                        COOKIE_DOMAIN,
                        is_ssl(),
                        true
                    );
                    if ( isset( $body['name'] ) ) {
                        setcookie(
                            'wordpress_logged_in_ts_user_name',
                            $body['name'],
                            time() + 86400 * 7,
                            COOKIEPATH,
                            COOKIE_DOMAIN,
                            is_ssl(),
                            true
                        );
                    }
                }
            } else {
                $error_msg = ( is_wp_error( $response ) ? $response->get_error_message() : wp_remote_retrieve_body( $response ) );
                /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
                wp_die( "Magic Link API Error: " . wp_remote_retrieve_response_code( $response ) . " - " . $error_msg );
            }
            // Clean the URL by redirecting without the token
            $clean_url = remove_query_arg( ['magic_token', 'process_magic_token'] );
            $clean_url = add_query_arg( 'ts_fresh', time(), $clean_url );
            // Output JS redirect on 200 OK to ensure cookies are saved in strict mobile webviews
            echo '<!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>' . ts_t( 'Redirecting...' ) . '</title>
            <style>
                body { margin: 0; padding: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; background: #f8fafc; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; color: #1e293b; }
                .ts-spinner { width: 50px; height: 50px; border: 4px solid #e2e8f0; border-top-color: #10b981; border-radius: 50%; animation: ts-spin 1s linear infinite; margin-bottom: 25px; }
                @keyframes ts-spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
                h2 { font-size: 22px; font-weight: 600; margin: 0 0 10px 0; }
                p { font-size: 15px; color: #64748b; margin: 0; }
            </style>
        </head>
        <body>
            <div class="ts-spinner"></div>
            <h2>' . ts_t( 'Success! Redirecting...' ) . '</h2>
            <script>
                window.location.replace("' . esc_js( $clean_url ) . '");
            </script>
        </body>
        </html>';
            exit;
        }
    }

}
// =================================================================
if ( !function_exists( 'ts_start_session' ) ) {
    function ts_start_session() {
        $needs_session = false;
        // Check for SahlDesk admin pages
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( is_admin() && isset( $_GET['page'] ) && strpos( sanitize_text_field( wp_unslash( $_GET['page'] ) ), 'ts_' ) === 0 ) {
            $needs_session = true;
        }
        // Check for specific SahlDesk actions/submissions
        $sahldesk_actions = [
            'submit_login',
            'submit_registration',
            'submit_ticket',
            'submit_comment',
            'submit_manage_ticket',
            'submit_forgot_password',
            'submit_reset_password',
            'submit_change_role',
            'ts_deactivate_license',
            'ts_save_settings',
            'ts_retry_sync',
            'submit_add_sub_status',
            'submit_update_sub_status',
            'submit_delete_sub_status',
            'submit_add_canned',
            'submit_delete_canned',
            'submit_add_category',
            'submit_update_category',
            'submit_archive_category',
            'submit_restore_category',
            'submit_delete_category'
        ];
        foreach ( $sahldesk_actions as $action ) {
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            if ( isset( $_POST[$action] ) || isset( $_GET['action'] ) && sanitize_text_field( wp_unslash( $_GET['action'] ) ) == $action || isset( $_GET['ts_action'] ) && sanitize_text_field( wp_unslash( $_GET['ts_action'] ) ) == $action ) {
                $needs_session = true;
                break;
            }
        }
        // Also start if magic token is present (auto-login link) or logout action
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_GET['magic_token'] ) || isset( $_GET['action'] ) && sanitize_text_field( wp_unslash( $_GET['action'] ) ) == 'ts_logout' ) {
            $needs_session = true;
        }
        // Always resume the session if the user already has a session cookie
        if ( isset( $_COOKIE[session_name()] ) || isset( $_COOKIE['wordpress_logged_in_ts_auth_token'] ) ) {
            $needs_session = true;
        }
        if ( $needs_session && !session_id() ) {
            session_start();
        }
        // Restore from cookie if session is missing (due to cache dropping PHPSESSID)
        if ( isset( $_COOKIE['wordpress_logged_in_ts_auth_token'] ) && !isset( $_SESSION['ts_auth_token'] ) ) {
            $_SESSION['ts_auth_token'] = sanitize_text_field( wp_unslash( $_COOKIE['wordpress_logged_in_ts_auth_token'] ) );
            if ( isset( $_COOKIE['wordpress_logged_in_ts_user_role'] ) ) {
                $_SESSION['ts_user_role'] = sanitize_text_field( wp_unslash( $_COOKIE['wordpress_logged_in_ts_user_role'] ) );
            }
            if ( isset( $_COOKIE['wordpress_logged_in_ts_user_name'] ) ) {
                $_SESSION['ts_user_name'] = sanitize_text_field( wp_unslash( $_COOKIE['wordpress_logged_in_ts_user_name'] ) );
            }
        }
    }

}
add_action( 'init', 'ts_start_session' );
// Start session if page contains SahlDesk shortcode
if ( !function_exists( 'ts_maybe_start_session_for_shortcodes' ) ) {
    if ( !function_exists( 'ts_maybe_start_session_for_shortcodes' ) ) {
        function ts_maybe_start_session_for_shortcodes() {
            global $post;
            if ( !is_a( $post, 'WP_Post' ) ) {
                return;
            }
            $ts_shortcodes = [
                'ticketing_system_register',
                'ticketing_system_login',
                'ticketing_system_dashboard',
                'ticketing_system_create',
                'ticketing_system_view_ticket',
                'ticketing_system_forgot_password',
                'ticketing_system_reset_password',
                'sahldesk',
                'sahldesk_portal',
                'sahldesk_widget'
            ];
            foreach ( $ts_shortcodes as $tag ) {
                if ( has_shortcode( $post->post_content, $tag ) ) {
                    if ( !session_id() ) {
                        session_start();
                    }
                    break;
                }
            }
        }

    }
}
add_action( 'template_redirect', 'ts_maybe_start_session_for_shortcodes' );
// --- FUNCTION TO LOAD SCRIPT ---
if ( !function_exists( 'ts_load_scripts' ) ) {
    function ts_load_scripts() {
        // Only load our script if 'ticket_id' is present (on the View Ticket page)
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_GET['ticket_id'] ) ) {
            wp_enqueue_script(
                'ts-ticket-scripts',
                plugin_dir_url( __FILE__ ) . 'assets/ts-scripts.js',
                array(),
                TS_PLUGIN_VERSION,
                true
            );
        }
        // Enqueue Widget CSS and JS
        wp_enqueue_style(
            'ts-widget-css',
            plugin_dir_url( __FILE__ ) . 'assets/widget.css',
            array(),
            TS_PLUGIN_VERSION
        );
        wp_enqueue_script(
            'ts-widget-js',
            plugin_dir_url( __FILE__ ) . 'assets/widget.js',
            array(),
            TS_PLUGIN_VERSION,
            true
        );
        // Localize widget JS
        wp_localize_script( 'ts-widget-js', 'tsWidgetData', array(
            'apiBase'      => TS_API_BASE_URL,
            'apiKey'       => get_option( "ts_tenant_api_key" ),
            'clientDomain' => home_url(),
            'apiLanguage'  => ts_get_api_language(),
            'i18n'         => array(
                'fillEmailIssue' => ts_t( "Please fill in Email and Issue." ),
                'fileTooLarge'   => ts_t( "File must be less than 5MB" ),
                'sendMessage'    => ts_t( "Send Message" ),
            ),
        ) );
        // Enqueue Magic Link JS (we can enqueue it generally, it will just define a function)
        wp_enqueue_script(
            'ts-magic-link-js',
            plugin_dir_url( __FILE__ ) . 'assets/magic-link.js',
            array(),
            TS_PLUGIN_VERSION,
            true
        );
        wp_localize_script( 'ts-magic-link-js', 'tsMagicLinkData', array(
            'ajaxUrl' => admin_url( 'admin-ajax.php' ),
            'i18n'    => array(
                'authenticating' => esc_js( ts_t( 'Authenticating your secure link...' ) ),
                'pleaseWait'     => esc_js( ts_t( 'Please wait a moment while we verify your access.' ) ),
            ),
        ) );
    }

}
add_action( 'wp_enqueue_scripts', 'ts_load_scripts' );
if ( !function_exists( 'ts_load_admin_styles' ) ) {
    function ts_load_admin_styles() {
        wp_enqueue_style(
            'ts-admin-style',
            plugin_dir_url( __FILE__ ) . 'assets/admin_style.css',
            array(),
            TS_PLUGIN_VERSION
        );
        wp_enqueue_script(
            'ts-chart-js',
            plugin_dir_url( __FILE__ ) . 'assets/chart.js',
            array(),
            TS_PLUGIN_VERSION,
            true
        );
        wp_enqueue_script(
            'ts-admin-js',
            plugin_dir_url( __FILE__ ) . 'assets/admin.js',
            array('ts-chart-js'),
            TS_PLUGIN_VERSION,
            true
        );
        // We need to fetch the tokens for admin.js localization
        $token = "";
        if ( isset( $_SESSION['ts_auth_token'] ) ) {
            $token = sanitize_text_field( wp_unslash( $_SESSION['ts_auth_token'] ) );
        } elseif ( isset( $_COOKIE['wordpress_logged_in_ts_auth_token'] ) ) {
            $token = sanitize_text_field( wp_unslash( $_COOKIE['wordpress_logged_in_ts_auth_token'] ) );
        }
        global $is_arabic;
        // Assuming this is defined or we can check language
        if ( !isset( $is_arabic ) ) {
            $is_arabic = ts_get_api_language() == 'ar';
        }
        wp_localize_script( 'ts-admin-js', 'tsAdminData', array(
            'isArabic'   => $is_arabic,
            'apiBaseUrl' => TS_API_BASE_URL,
            'token'      => $token,
            'apiKey'     => get_option( 'ts_tenant_api_key' ),
        ) );
    }

}
add_action( 'admin_enqueue_scripts', 'ts_load_admin_styles' );
// --- SETTINGS PAGE & OPTION MANAGEMENT ---
// =================================================================
if ( !function_exists( 'ts_register_settings_init' ) ) {
    function ts_register_settings_init() {
        register_setting( 'ts_plugin_options', 'ts_tenant_api_key', array(
            'sanitize_callback' => 'sanitize_text_field',
        ) );
        register_setting( 'ts_plugin_options', 'ts_language', array(
            'sanitize_callback' => 'sanitize_text_field',
        ) );
        // <--- NEW
    }

}
add_action( 'admin_init', 'ts_register_settings_init' );
if ( !function_exists( 'ts_register_all_admin_menus' ) ) {
    function ts_register_all_admin_menus() {
        // 1. Main Sahldesk Menu
        add_menu_page(
            ts_t( 'Ticketing System' ),
            'SahlDesk',
            'manage_options',
            'ts_settings_page',
            'ts_render_settings_page',
            'dashicons-tickets',
            26
        );
        // 2. Settings Sub-menu
        add_submenu_page(
            'ts_settings_page',
            ts_t( 'API Settings' ),
            ts_t( 'Settings' ),
            'manage_options',
            'ts_settings_page',
            'ts_render_settings_page'
        );
        // 3. Pro Features (Visible to all, locked for free)
        $pro_icon = ( defined( 'TS_IS_PRO' ) && TS_IS_PRO ? '' : '<span class="dashicons dashicons-lock" style="font-size:14px; margin-top:2px;"></span> ' );
        // User Management
        add_submenu_page(
            'ts_settings_page',
            ts_t( 'User Role Management' ),
            $pro_icon . ts_t( 'User Roles' ),
            'manage_options',
            'ts_user_roles_page',
            'ts_render_user_management_page'
        );
        // Reports & Analytics
        add_submenu_page(
            'ts_settings_page',
            ts_t( 'Reports & Analytics' ),
            $pro_icon . ts_t( 'Reports' ),
            'manage_options',
            'ts_reports_page',
            'ts_render_reports_page'
        );
        // Canned Responses
        add_submenu_page(
            'ts_settings_page',
            ts_t( 'Canned Responses' ),
            '<span style="white-space: nowrap; letter-spacing: -0.2px;">' . $pro_icon . ts_t( 'Canned Responses' ) . '</span>',
            'manage_options',
            'ts_canned_responses',
            'ts_render_canned_responses_page'
        );
        // Sub-Statuses (New)
        add_submenu_page(
            'ts_settings_page',
            ts_t( 'Ticket Sub-Statuses' ),
            $pro_icon . ts_t( 'Sub-Statuses' ),
            'manage_options',
            'ts_sub_statuses_page',
            'ts_render_sub_statuses_page'
        );
        // Categories (New) - Available in Free (up to 3) and Pro (unlimited)
        add_submenu_page(
            'ts_settings_page',
            ts_t( 'Ticket Categories' ),
            ts_t( 'Categories' ),
            'manage_options',
            'ts_categories_page',
            'ts_render_categories_page'
        );
        if ( !defined( 'TS_IS_PRO' ) || !TS_IS_PRO ) {
            add_submenu_page(
                'ts_settings_page',
                ts_t( 'Upgrade to Pro' ),
                ts_t( 'Upgrade' ),
                'manage_options',
                'ts-custom-upgrade',
                'ts_render_custom_upgrade_page'
            );
        } else {
            // Register hidden page so Freemius checkout redirects don't crash with "Sorry, you are not allowed..."
            add_submenu_page(
                null,
                ts_t( 'Upgrade to Pro' ),
                ts_t( 'Upgrade' ),
                'manage_options',
                'ts-custom-upgrade',
                'ts_render_custom_upgrade_page'
            );
        }
        // Hidden Setup Wizard Page
        add_submenu_page(
            null,
            ts_t( 'SahlDesk Setup' ),
            ts_t( 'Setup Wizard' ),
            'manage_options',
            'ts-setup-wizard',
            'ts_render_setup_wizard_page'
        );
    }

}
add_action( 'admin_menu', 'ts_register_all_admin_menus' );
if ( !function_exists( 'ts_style_freemius_pricing_page' ) ) {
    function ts_style_freemius_pricing_page(  $hook  ) {
        if ( strpos( $hook, 'my-ticketing-system-pricing' ) !== false ) {
            $custom_css = "\n\n            /* Style Freemius Pricing to look modern */\n\n            #fs_pricing_wrapper {\n\n                font-family: 'Inter', 'Segoe UI', Roboto, sans-serif !important;\n\n                max-width: 900px;\n\n                margin: 40px auto;\n\n            }\n\n            .fs-plan {\n\n                border-radius: 12px !important;\n\n                border: 1px solid #e2e8f0 !important;\n\n                box-shadow: 0 4px 6px -1px rgba(0,0,0,0.05) !important;\n\n            }\n\n            .fs-plan.fs-featured {\n\n                border: 2px solid #2563eb !important;\n\n                box-shadow: 0 10px 30px -5px rgba(37,99,235,0.15) !important;\n\n            }\n\n            .fs-features li {\n\n                text-align: left !important;\n\n                padding-left: 10px;\n\n            }\n\n            /* Hide the upgrade button on the free plan if desired */\n\n            .fs-plan-free .fs-upgrade-button {\n\n                display: none !important;\n\n            }\n\n        ";
            wp_add_inline_style( 'fs_common', $custom_css );
        }
    }

}
// ==========================================
// CUSTOM UPGRADE PAGE
// ==========================================
if ( !function_exists( 'ts_render_setup_wizard_page' ) ) {
    function ts_render_setup_wizard_page() {
        $current_user = wp_get_current_user();
        $admin_email = $current_user->user_email;
        $raw_url = str_replace( ['http://', 'https://', 'www.'], '', site_url() );
        $url_parts = explode( '.', $raw_url );
        $default_company_name = ucfirst( $url_parts[0] );
        ?>

    <style>

        body.admin-color-fresh { background: #f8fafc; }

        #adminmenumain, #wpadminbar, #wpfooter { display: none !important; }

        #wpcontent { margin-left: 0 !important; padding: 0 !important; }

        .ts-wizard-container {

            font-family: 'Inter', 'Segoe UI', sans-serif;

            max-width: 500px;

            margin: 80px auto;

            background: white;

            border-radius: 16px;

            box-shadow: 0 20px 40px -10px rgba(0,0,0,0.1);

            overflow: hidden;

        }

        .ts-wizard-header {

            background: linear-gradient(135deg, #2563eb, #1d4ed8);

            padding: 30px;

            text-align: center;

            color: white;

        }

        .ts-wizard-header h2 {

            margin: 0; font-size: 24px; color: white; font-weight: 700;

        }

        .ts-wizard-body {

            padding: 40px;

        }

        .ts-wizard-body label {

            display: block; font-weight: 600; margin-bottom: 8px; color: #1e293b;

        }

        .ts-wizard-body input[type="text"], .ts-wizard-body input[type="password"] {

            width: 100%; padding: 12px; border: 1px solid #cbd5e1; border-radius: 8px; margin-bottom: 20px; font-size: 15px;

        }

        .ts-wizard-body input:focus {

            border-color: #2563eb; box-shadow: 0 0 0 3px rgba(37,99,235,0.1); outline: none;

        }

        .ts-wizard-footer {

            padding: 20px 40px; background: #f8fafc; border-top: 1px solid #e2e8f0; text-align: right; display: flex; justify-content: space-between; align-items: center;

        }

        .ts-btn-primary {

            background: #2563eb; color: white; border: none; padding: 12px 24px; border-radius: 8px; font-size: 15px; font-weight: 600; cursor: pointer; transition: background 0.2s;

        }

        .ts-btn-primary:hover { background: #1d4ed8; }

        .ts-btn-skip {

            color: #64748b; text-decoration: none; font-size: 14px; font-weight: 500;

        }

        .ts-btn-skip:hover { color: #0f172a; }

    </style>

    <div class="ts-wizard-container">

        <div class="ts-wizard-header">

            <h2><?php 
        echo esc_html( ts_t( 'Welcome to SahlDesk!' ) );
        ?></h2>

            <p style="margin: 10px 0 0 0; opacity: 0.9;"><?php 
        echo esc_html( ts_t( "Let's finish setting up your account." ) );
        ?></p>

        </div>

        <div class="ts-wizard-body">

            <div id="ts-wizard-error" style="display:none; color: #dc2626; background: #fee2e2; padding: 12px; border-radius: 8px; margin-bottom: 20px; font-size: 14px; border: 1px solid #fecaca;"></div>

            

            <label><?php 
        echo esc_html( ts_t( 'Helpdesk Name' ) );
        ?></label>

            <input type="text" id="ts_company_name" value="<?php 
        echo esc_attr( $default_company_name );
        ?>" placeholder="<?php 
        echo esc_attr( ts_t( 'e.g. My Store Support' ) );
        ?>">

            

            <div style="background: #f1f5f9; padding: 10px 15px; border-radius: 6px; margin: -5px 0 20px 0; border: 1px solid #e2e8f0;">

                <p style="margin: 0; font-size: 13px; color: #475569;">

                    <svg style="width: 14px; height: 14px; vertical-align: middle; margin-right: 5px; color: #2563eb;" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path></svg>

                    <?php 
        echo esc_html( ts_t( 'Your Support Email:' ) );
        ?> <strong id="ts_email_preview" style="color: #0f172a;"></strong>

                </p>

                <p style="margin: 4px 0 0 23px; font-size: 11px; color: #64748b;"><?php 
        echo esc_html( ts_t( 'Customers will email this address, and it will automatically create tickets in your dashboard.' ) );
        ?></p>

            </div>

            

            <label><?php 
        echo esc_html( ts_t( 'Admin Password' ) );
        ?> <span style="font-weight:400; color:#64748b; font-size:13px;"><?php 
        echo esc_html( ts_t( '(For standalone portal access)' ) );
        ?></span></label>

            <input type="password" id="ts_admin_password" placeholder="<?php 
        echo esc_attr( ts_t( 'Choose a secure password' ) );
        ?>">

            

            <label><?php 
        echo esc_html( ts_t( 'Admin Email' ) );
        ?> <span style="font-weight:400; color:#64748b; font-size:13px;"><?php 
        echo esc_html( ts_t( '(This will be your primary login email)' ) );
        ?></span></label>
            <input type="email" id="ts_admin_email" value="<?php 
        echo esc_attr( $admin_email );
        ?>" placeholder="name@example.com">

        </div>

        <div class="ts-wizard-footer" style="justify-content: center;">

            <button class="ts-btn-primary" onclick="tsCompleteWizard(false)" id="ts_wizard_btn"><?php 
        echo esc_html( ts_t( 'Complete Setup' ) );
        ?></button>

        </div>

    </div>

    

    <script>

    function updateEmailPreview() {

        var name = document.getElementById('ts_company_name').value;

        var clean = name.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();

        if (!clean) clean = 'support';

        document.getElementById('ts_email_preview').innerText = clean + '@sahldesk.com';

    }

    document.addEventListener('DOMContentLoaded', function() {

        var input = document.getElementById('ts_company_name');

        if (input) {

            input.addEventListener('input', updateEmailPreview);

            updateEmailPreview();

        }

    });



    function tsCompleteWizard(skip) {

        var btn = document.getElementById('ts_wizard_btn');

        var errBox = document.getElementById('ts-wizard-error');

        btn.innerText = '<?php 
        /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
        echo esc_js( ts_t( 'Saving...' ) );
        ?>';

        btn.disabled = true;

        errBox.style.display = 'none';

        

        var companyName = document.getElementById('ts_company_name').value;
        var adminEmail = document.getElementById('ts_admin_email').value;
        var password = document.getElementById('ts_admin_password').value;

        

        if (!skip && password.length < 6) {

            errBox.innerText = '<?php 
        /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
        echo esc_js( ts_t( 'Please enter a password with at least 6 characters.' ) );
        ?>';

            errBox.style.display = 'block';

            btn.innerText = '<?php 
        /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
        echo esc_js( ts_t( 'Complete Setup' ) );
        ?>';

            btn.disabled = false;

            return;

        }



        jQuery.post(ajaxurl, {
            action: 'ts_complete_wizard',
            security: '<?php 
        echo esc_attr( wp_create_nonce( "ts_wizard_nonce" ) );
        ?>',
            skip: skip ? 1 : 0,
            company_name: companyName,
            admin_email: adminEmail,
            password: password
        }, function(response) {

            if (response.success) {

                window.location.href = '<?php 
        echo esc_url( admin_url( "admin.php?page=ts_settings_page" ) );
        ?>';

            } else {

                errBox.innerText = response.data.message || 'An error occurred.';

                errBox.style.display = 'block';

                btn.innerText = '<?php 
        /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
        echo esc_js( ts_t( 'Complete Setup' ) );
        ?>';

                btn.disabled = false;

            }

        });

    }

    </script>

    <?php 
    }

}
add_action( 'wp_ajax_ts_complete_wizard', 'ts_ajax_complete_wizard' );
if ( !function_exists( 'ts_ajax_complete_wizard' ) ) {
    function ts_ajax_complete_wizard() {
        check_ajax_referer( 'ts_wizard_nonce', 'security' );
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        $skip = isset( $_POST['skip'] ) && sanitize_text_field( wp_unslash( $_POST['skip'] ) ) == 1;
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        $company_name = sanitize_text_field( wp_unslash( $_POST['company_name'] ) );
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        $admin_email = sanitize_email( sanitize_text_field( wp_unslash( $_POST['admin_email'] ) ) );
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        $password = ( $skip ? '' : sanitize_text_field( wp_unslash( $_POST['password'] ) ) );
        // Do not aggressively sanitize password as it might contain special chars
        $api_key = get_option( 'ts_tenant_api_key' );
        if ( empty( $api_key ) ) {
            if ( $skip ) {
                update_option( 'ts_setup_wizard_completed', 'yes' );
                delete_option( 'ts_needs_setup_wizard' );
                wp_send_json_success();
            }
            wp_send_json_error( [
                'message' => 'API Key not found. Please reconnect Freemius.',
            ] );
        }
        $api_url = TS_API_BASE_URL . '/plugin/complete-setup';
        $response = wp_remote_post( $api_url, [
            'headers'     => [
                'Content-Type' => 'application/json',
                'X-Api-Key'    => $api_key,
            ],
            'body'        => json_encode( [
                'CompanyName'   => $company_name,
                'AdminEmail'    => $admin_email,
                'AdminPassword' => $password,
            ] ),
            'data_format' => 'body',
            'timeout'     => 15,
        ] );
        if ( is_wp_error( $response ) ) {
            wp_send_json_error( [
                'message' => 'Failed to connect to SahlDesk API.',
            ] );
        }
        $status_code = wp_remote_retrieve_response_code( $response );
        if ( $status_code == 200 ) {
            update_option( 'ts_setup_wizard_completed', 'yes' );
            delete_option( 'ts_needs_setup_wizard' );
            wp_send_json_success();
        } else {
            $body = wp_remote_retrieve_body( $response );
            $data = json_decode( $body, true );
            wp_send_json_error( [
                'message' => ( isset( $data['message'] ) ? ts_t( $data['message'] ) : 'API Error ' . $status_code ),
            ] );
        }
    }

}
if ( !function_exists( 'ts_render_settings_page' ) ) {
    function ts_render_settings_page() {
        // HANDLE LOG DOWNLOAD
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_GET['download_sahldesk_logs'] ) ) {
            $upload_dir = wp_upload_dir();
            $log_file = $upload_dir['basedir'] . '/sahldesk-logs/plugin.log';
            if ( file_exists( $log_file ) ) {
                header( 'Content-Description: File Transfer' );
                header( 'Content-Type: application/octet-stream' );
                header( 'Content-Disposition: attachment; filename="sahldesk_plugin.log"' );
                header( 'Expires: 0' );
                header( 'Cache-Control: must-revalidate' );
                header( 'Pragma: public' );
                // Output log file content
                /* phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_readfile */
                readfile( $log_file );
                // Append Freemius Debug Info to the downloaded log
                echo "\n\n======================================================\n";
                echo "FREEMIUS DEBUG INFO\n";
                echo "======================================================\n";
                if ( function_exists( 'sahldesk_fs' ) ) {
                    $fs = sahldesk_fs();
                    /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
                    echo "Freemius Registered Locally: " . (( $fs->is_registered() ? 'Yes' : 'No' )) . "\n";
                    /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
                    echo "Is Pending Activation: " . (( $fs->is_pending_activation() ? 'Yes' : 'No' )) . "\n";
                    /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
                    echo "Is Anonymous (Skipped): " . (( $fs->is_anonymous() ? 'Yes' : 'No' )) . "\n";
                    /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
                    echo "Has User Object: " . (( is_object( $fs->get_user() ) ? 'Yes' : 'No' )) . "\n";
                    $api_error = get_transient( 'fs_api_last_error' );
                    if ( $api_error ) {
                        echo esc_html( "Last API Error: " . wp_json_encode( $api_error, true ) . "\n" );
                    }
                    if ( $fs->is_registered() && $fs->get_site() ) {
                        echo "Freemius Site ID: " . esc_html( $fs->get_site()->id ) . "\n";
                    }
                } else {
                    echo "sahldesk_fs() is not defined.\n";
                }
                exit;
            } else {
                // we can't show a notice here because it's before output, we'll just ignore or redirect
                wp_safe_redirect( admin_url( 'admin.php?page=ts_settings_page&log_not_found=1' ) );
                exit;
            }
        }
        // 1. HANDLE DEACTIVATION
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_POST['ts_deactivate_license'] ) ) {
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            if ( !isset( $_POST['ts_nonce'] ) || !wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['ts_nonce'] ) ), 'ts_deactivate_action' ) ) {
                echo '<div class="notice notice-error"><p>Security check failed.</p></div>';
            } else {
                $api_key = get_option( 'ts_tenant_api_key' );
                // Call API to UNLOCK the domain
                wp_remote_post( TS_API_BASE_URL . '/companies/deactivate', [
                    'headers'     => [
                        'X-Api-Key' => $api_key,
                    ],
                    'data_format' => 'body',
                ] );
                // Remove key from WordPress
                delete_option( 'ts_tenant_api_key' );
                $api_key = '';
                echo '<div class="notice notice-success"><p>License deactivated. You can now use this key on another site.</p></div>';
            }
        } else {
            $api_key = get_option( 'ts_tenant_api_key' );
        }
        // 1.5 HANDLE SETTINGS UPDATE (Widget Toggle)
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_POST['ts_save_settings'] ) ) {
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            if ( !isset( $_POST['ts_settings_nonce'] ) || !wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['ts_settings_nonce'] ) ), 'ts_update_settings_action' ) ) {
                echo '<div class="notice notice-error"><p>Security check failed.</p></div>';
            } else {
                // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
                $allow_guest = ( isset( $_POST['ts_allow_guest'] ) ? true : false );
                // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
                $widget_color = ( isset( $_POST['ts_widget_color'] ) ? sanitize_hex_color( sanitize_text_field( wp_unslash( $_POST['ts_widget_color'] ) ) ) : '#0056b3' );
                update_option( 'ts_widget_color', $widget_color );
                // Send to API
                $response = wp_remote_post( TS_API_BASE_URL . '/companies/settings', [
                    'headers'     => [
                        'Content-Type' => 'application/json',
                        'X-Api-Key'    => $api_key,
                    ],
                    'body'        => json_encode( [
                        'allowGuestTickets' => $allow_guest,
                    ] ),
                    'data_format' => 'body',
                ] );
                if ( !is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) == 200 ) {
                    update_option( 'ts_allow_guest_tickets', $allow_guest );
                    // Clear common WP caches so the widget color updates immediately on the frontend
                    if ( function_exists( 'wp_cache_clear_cache' ) ) {
                        wp_cache_clear_cache();
                    }
                    // WP Super Cache
                    if ( function_exists( 'rocket_clean_domain' ) ) {
                        rocket_clean_domain();
                    }
                    // WP Rocket
                    if ( class_exists( 'LiteSpeed_Cache_API' ) && method_exists( 'LiteSpeed_Cache_API', 'purge_all' ) ) {
                        LiteSpeed_Cache_API::purge_all();
                    }
                    // LiteSpeed
                    if ( function_exists( 'w3tc_flush_all' ) ) {
                        w3tc_flush_all();
                    }
                    // W3TC
                    if ( function_exists( 'sg_cachepress_purge_cache' ) ) {
                        sg_cachepress_purge_cache();
                    }
                    // SiteGround Optimizer
                    echo '<div class="notice notice-success"><p>Settings updated. Cache cleared.</p></div>';
                } else {
                    $code = wp_remote_retrieve_response_code( $response );
                    $msg = ( is_wp_error( $response ) ? $response->get_error_message() : wp_remote_retrieve_body( $response ) );
                    echo '<div class="notice notice-error"><p>Failed to update settings on server. Code: ' . esc_html( $code ) . ' Response: ' . esc_html( substr( $msg, 0, 200 ) ) . '</p></div>';
                }
            }
        }
        $company_info = null;
        // 2. CONNECT TO API (WITH DOMAIN LOCK)
        if ( !empty( $api_key ) ) {
            $response = wp_remote_get( TS_API_BASE_URL . '/companies/info', [
                'headers'     => [
                    'X-Api-Key'         => $api_key,
                    'X-Client-Domain'   => home_url(),
                    'X-Client-Language' => ts_get_api_language(),
                ],
                'data_format' => 'body',
            ] );
            if ( !is_wp_error( $response ) ) {
                $code = wp_remote_retrieve_response_code( $response );
                if ( $code == 200 ) {
                    $company_info = json_decode( wp_remote_retrieve_body( $response ), true );
                    // Update setting immediately on settings page load
                    if ( isset( $company_info['allowGuestTickets'] ) ) {
                        update_option( 'ts_allow_guest_tickets', $company_info['allowGuestTickets'] );
                    }
                } elseif ( $code == 403 ) {
                    $body = json_decode( wp_remote_retrieve_body( $response ), true );
                    $msg = ( isset( $body['message'] ) ? $body['message'] : 'License violation.' );
                    echo '<div class="notice notice-error"><p><strong>License Error:</strong> ' . esc_html( $msg ) . '</p></div>';
                    delete_option( 'ts_tenant_api_key' );
                    $api_key = '';
                }
            }
            // 3. CHECK FOR REMOTE DOWNGRADE (New Logic)
            if ( !empty( $api_key ) ) {
                $status_response = wp_remote_get( TS_API_BASE_URL . '/freemius/status', [
                    'headers'     => [
                        'X-Api-Key' => $api_key,
                    ],
                    'data_format' => 'body',
                    'timeout'     => 5,
                ] );
                if ( !is_wp_error( $status_response ) && wp_remote_retrieve_response_code( $status_response ) == 200 ) {
                    $status_data = json_decode( wp_remote_retrieve_body( $status_response ), true );
                    $remote_plan = ( isset( $status_data['plan'] ) ? $status_data['plan'] : 'Free' );
                    if ( defined( 'TS_IS_PRO' ) && TS_IS_PRO && strtolower( $remote_plan ) === 'free' ) {
                        if ( ts_sync_license_with_backend() ) {
                            echo '<div class="notice notice-success"><p><strong>License Synced:</strong> Your plan status has been automatically updated on the server.</p></div>';
                        } else {
                            echo '<div class="notice notice-warning"><p><strong>Plan Mismatch:</strong> Your plan appears to be <strong>Free</strong> on the server (possibly due to expiration), but your local license is active. Automatic sync failed. Please click <strong>Sync License</strong> below.</p></div>';
                        }
                    }
                }
            }
        }
        ?>

    <div class="wrap ts-wrap">

        <h1 style="display: none;"><?php 
        echo esc_html( ts_t( 'SahlDesk Settings' ) );
        ?></h1>

        

        <?php 
        if ( empty( $api_key ) ) {
            ?>

            

            <?php 
            $sync_err = get_option( 'ts_last_sync_error' );
            if ( $sync_err ) {
                // Check if it's an IIS HTML error page
                if ( strpos( $sync_err, '<!DOCTYPE html' ) !== false || strpos( $sync_err, '<html' ) !== false ) {
                    $sync_err = "Server Error (HTML page returned instead of JSON). This usually means the API endpoint URL was incorrect or not deployed.";
                }
                echo '<div class="notice notice-error" style="border-left-color: #dc3232;"><p><strong>Background Auto-Sync Failed:</strong> ' . esc_html( $sync_err ) . '<br><br><em>Debug Info: The plugin is trying to contact <strong>' . esc_html( TS_API_BASE_URL ) . '</strong>. If this is pointing to production (api.sahldesk.com) but you are testing locally, you need to add <code>define(\'TS_API_CUSTOM_BASE_URL\', \'https://localhost:7149/api/v1\');</code> to your wp-config.php.</em></p></div>';
            }
            ?>

            

            <?php 
            $fs = ( function_exists( 'sahldesk_fs' ) ? sahldesk_fs() : null );
            ?>

            <?php 
            if ( $fs && ($fs->is_registered() || $fs->is_pending_activation()) ) {
                ?>

                <div style="background: #fff; padding: 20px; border: 1px solid #ccd0d4; border-left: 4px solid #0073aa; margin-top: 20px;">

                    <h2 style="margin-top:0;"><?php 
                echo esc_html( ts_t( 'License Managed via Freemius' ) );
                ?></h2>

                    <?php 
                if ( $fs->is_pending_activation() ) {
                    ?>

                        <p style="color: #d63638;"><strong><?php 
                    echo esc_html( ts_t( 'Pending Email Verification:' ) );
                    ?></strong> Please check your email and click the confirmation link from Freemius to fully activate your account.</p>

                    <?php 
                }
                ?>

                    <p><?php 
                echo esc_html( ts_t( 'Your account is connected to Freemius. The plugin is attempting to retrieve your SahlDesk API Key automatically from your backend.' ) );
                ?></p>

                    <form method="post">

                        <input type="hidden" name="ts_retry_sync" value="1">

                        <?php 
                submit_button(
                    ts_t( 'Retry Sync' ),
                    'secondary',
                    'submit',
                    false
                );
                ?>

                    </form>

                </div>

                <?php 
                // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
                if ( isset( $_POST['ts_retry_sync'] ) ) {
                    delete_transient( 'ts_sync_lock' );
                    // Clear lock to force immediate retry
                    if ( ts_sync_license_with_backend() ) {
                        echo '<div class="notice notice-success inline"><p>Sync successful! Reloading...</p></div>';
                        echo '<script>setTimeout(function(){ window.location.reload(); }, 1000);</script>';
                    } else {
                        $error_msg = get_option( 'ts_last_sync_error', 'Unknown Error' );
                        if ( strpos( $error_msg, '<!DOCTYPE html' ) !== false || strpos( $error_msg, '<html' ) !== false ) {
                            $error_msg = "Server Error (HTML page returned). The API endpoint URL (" . TS_API_BASE_URL . ") is incorrect or not deployed.";
                        }
                        echo '<div class="notice notice-error inline"><p>Sync failed! <strong>Server response:</strong> ' . esc_html( $error_msg ) . '</p></div>';
                    }
                }
                ?>

            <?php 
            } else {
                ?>

                <form method="post" action="options.php">

                    <?php 
                settings_fields( 'ts_plugin_options' );
                do_settings_sections( 'ts_plugin_options' );
                ?>

                    <table class="form-table">

                        <tr valign="top">

                            <th scope="row"><?php 
                echo esc_html( ts_t( 'Enter API Key' ) );
                ?></th>

                            <td>

                                <input type="text" name="ts_tenant_api_key" value="" style="width: 400px;" placeholder="Paste your key here..." />

                                <p class="description"><?php 
                echo esc_html( ts_t( 'Please enter your API Key to activate the plugin.' ) );
                ?></p>

                            </td>

                        </tr>

                    </table>

                    <?php 
                submit_button( ts_t( 'Activate License' ) );
                ?>

                </form>

            <?php 
            }
            ?>



        <?php 
        } else {
            ?>

            <style>

                .ts-settings-wrap { max-width: 900px; margin-top: 20px; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; }

                

                /* Header Banner */

                .ts-header-banner { background: linear-gradient(135deg, <?php 
            echo esc_attr( get_option( 'ts_widget_color', '#0056b3' ) );
            ?> 0%, #003d82 100%); color: white; padding: 30px 40px; border-radius: 12px; margin-bottom: 25px; display: flex; align-items: center; gap: 20px; box-shadow: 0 8px 20px rgba(0, 86, 179, 0.15); }

                .ts-header-banner h1 { color: white; margin: 0; font-size: 28px; font-weight: 600; text-shadow: 0 1px 2px rgba(0,0,0,0.2); line-height: 1.2; }

                .ts-header-banner p { margin: 5px 0 0; font-size: 15px; opacity: 0.9; }

                .ts-header-icon { font-size: 48px; width: 48px; height: 48px; opacity: 0.9; }

                

                /* Grid Layout */

                .ts-cards-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 24px; }

                

                /* Cards */

                .ts-card { background: #fff; border: 1px solid #e2e4e7; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.03); transition: box-shadow 0.3s ease, transform 0.2s ease; display: flex; flex-direction: column; overflow: hidden; }

                .ts-card:hover { box-shadow: 0 6px 16px rgba(0,0,0,0.06); transform: translateY(-2px); }

                .ts-card-header { padding: 20px 24px; border-bottom: 1px solid #f0f0f1; display: flex; justify-content: space-between; align-items: center; background: #fafafa; }

                .ts-card-title { margin: 0; font-size: 17px; font-weight: 600; color: #1d2327; display: flex; align-items: center; gap: 8px; }

                .ts-card-title .dashicons { color: <?php 
            echo esc_attr( get_option( 'ts_widget_color', '#0056b3' ) );
            ?>; }

                .ts-status-badge { background: #d1fae5; color: #065f46; padding: 5px 12px; border-radius: 20px; font-size: 12px; font-weight: 600; display: inline-flex; align-items: center; gap: 4px; border: 1px solid #a7f3d0; box-shadow: 0 1px 2px rgba(0,0,0,0.05); }

                .ts-card-body { padding: 24px; flex-grow: 1; }

                

                /* List Rows */

                .ts-info-row { display: flex; justify-content: space-between; padding: 14px 0; border-bottom: 1px dashed #e2e4e7; font-size: 14px; }

                .ts-info-row:first-child { padding-top: 0; }

                .ts-info-row:last-child { border-bottom: none; padding-bottom: 0; }

                .ts-info-label { color: #646970; }

                .ts-info-value { font-weight: 600; color: #2c3338; }

                

                /* Actions Area */

                .ts-actions-row { margin-top: auto; padding: 16px 24px; border-top: 1px solid #f0f0f1; display: flex; gap: 10px; align-items: center; background: #fafafa; }

                

                /* Forms inside Cards */

                .ts-form-group { margin-bottom: 20px; }

                .ts-form-label { display: block; font-weight: 600; margin-bottom: 8px; color: #1d2327; font-size: 14px; }

                .ts-checkbox-label { display: flex; align-items: center; gap: 8px; font-size: 14px; color: #2c3338; cursor: pointer; }

                .ts-color-picker-wrap { display: flex; align-items: center; gap: 15px; }

                .ts-color-input { height: 44px; width: 64px; padding: 0; cursor: pointer; border: 2px solid #e2e4e7; border-radius: 6px; }

            </style>



            <div class="ts-settings-wrap">

        <?php 
            /* phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash */
            if ( isset( $_GET['log_not_found'] ) ) {
                ?>
            <div class="notice notice-error is-dismissible"><p><?php 
                echo esc_html( ts_t( 'No logs found. The plugin.log file does not exist yet.' ) );
                ?></p></div>
        <?php 
            }
            ?>

                

                <div class="ts-header-banner">



                    <span class="dashicons dashicons-tickets ts-header-icon"></span>

                    <div>

                        <h1><?php 
            echo esc_html( ts_t( 'SahlDesk Core Setup' ) );
            ?></h1>

                        <p><?php 
            echo esc_html( ts_t( 'Manage your remote ticketing API connection, widget settings, and license syncing.' ) );
            ?></p>

                    </div>

                </div>



                <div class="ts-cards-grid">

                    

                    <!-- License Info Card -->

                    <div class="ts-card">

                        <div class="ts-card-header">

                            <h2 class="ts-card-title"><span class="dashicons dashicons-admin-network"></span> <?php 
            echo esc_html( ts_t( 'API Connection' ) );
            ?></h2>

                            <span class="ts-status-badge"><span class="dashicons dashicons-yes" style="font-size:14px;width:14px;height:14px;"></span> Active</span>

                        </div>

                        <div class="ts-card-body">

                            <div class="ts-info-row">

                                <span class="ts-info-label"><?php 
            echo esc_html( ts_t( 'Company Name' ) );
            ?></span>

                                <span class="ts-info-value"><?php 
            echo esc_html( $company_info['name'] ?? 'Unknown' );
            ?></span>

                            </div>

                            <div class="ts-info-row">

                                <span class="ts-info-label"><?php 
            echo esc_html( ts_t( 'License Key' ) );
            ?></span>

                                <span class="ts-info-value"><code style="background: #f0f0f1; padding: 3px 6px; border-radius: 4px;"><?php 
            echo esc_html( substr( $api_key, 0, 10 ) . '****************' );
            ?></code></span>

                            </div>

                            <div class="ts-info-row">

                                <span class="ts-info-label"><?php 
            echo esc_html( ts_t( 'Support Email' ) );
            ?></span>

                                <span class="ts-info-value"><a href="mailto:<?php 
            echo esc_attr( $company_info['supportEmail'] ?? '' );
            ?>" style="text-decoration:none; color:<?php 
            echo esc_attr( get_option( 'ts_widget_color', '#0056b3' ) );
            ?>;"><strong><?php 
            echo esc_html( $company_info['supportEmail'] ?? 'Not set' );
            ?></strong></a></span>

                            </div>

                            <div class="ts-info-row">

                                <span class="ts-info-label"><?php 
            echo esc_html( ts_t( 'Current Plan' ) );
            ?></span>

                                <span class="ts-info-value"><?php 
            echo esc_html( ( defined( 'TS_IS_PRO' ) && TS_IS_PRO ? 'SahlDesk Pro' : 'Free Tier' ) );
            ?></span>

                            </div>

                        </div>

                        <div class="ts-actions-row" style="justify-content: space-between;">
                            <div>
                                <?php 
            if ( function_exists( 'sahldesk_fs' ) ) {
                ?>
                                <form method="post" style="display:inline-block; margin:0;">
                                    <input type="hidden" name="ts_manual_sync" value="1">
                                    <?php 
                submit_button(
                    ts_t( 'Sync License' ),
                    'secondary',
                    'submit',
                    false
                );
                ?>
                                </form>

                                <?php 
                // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
                if ( isset( $_POST['ts_manual_sync'] ) ) {
                    if ( ts_sync_license_with_backend() ) {
                        echo '<span style="color: #065f46; font-weight: 600; margin-left: 10px; font-size: 13px;">Sync successful! Reloading...</span>';
                        echo '<script>setTimeout(function(){ window.location.reload(); }, 1500);</script>';
                    } else {
                        $sync_err = get_option( 'ts_last_sync_error', 'Unknown Error' );
                        echo '<span style="color: #dc3232; font-weight: 600; margin-left: 10px; font-size: 13px;">Sync failed: ' . esc_html( $sync_err ) . '</span>';
                    }
                }
                ?>
                                <?php 
            }
            ?>
                            </div>
                        </div>

                    </div>

                    

                    <!-- Widget Settings Card -->

                    <div class="ts-card">

                        <div class="ts-card-header">

                            <h2 class="ts-card-title"><span class="dashicons dashicons-admin-appearance"></span> <?php 
            echo esc_html( ts_t( 'Widget Settings' ) );
            ?></h2>

                        </div>

                        <div class="ts-card-body">

                            <form method="post" action="">

                                <?php 
            wp_nonce_field( 'ts_update_settings_action', 'ts_settings_nonce' );
            ?>

                                

                                <div class="ts-form-group">

                                    <label class="ts-checkbox-label">

                                        <input type="checkbox" name="ts_allow_guest" value="1" <?php 
            checked( get_option( 'ts_allow_guest_tickets' ), true );
            ?>> <?php 
            echo esc_html( ts_t( 'Enable floating guest support widget on frontend' ) );
            ?> </label>

                                </div>

                                

                                <div class="ts-form-group">

                                    <label class="ts-form-label"><?php 
            echo esc_html( ts_t( 'Widget Theme Color' ) );
            ?></label>

                                    <div class="ts-color-picker-wrap">

                                        <input type="color" name="ts_widget_color" class="ts-color-input" value="<?php 
            echo esc_attr( get_option( 'ts_widget_color', '#0056b3' ) );
            ?>">

                                        <span style="font-size: 13px; color: #646970;"><?php 
            echo esc_html( ts_t( 'Select the primary brand color for the floating widget.' ) );
            ?></span>

                                    </div>

                                </div>

                                

                                <div style="margin-top: 30px;">

                                    <?php 
            submit_button(
                ts_t( 'Save Settings' ),
                'primary',
                'ts_save_settings',
                false
            );
            ?>

                                </div>

                            </form>

                        </div>

                    </div>



                    <!-- Debug Card -->
                    <div class="ts-card">
                        <div class="ts-card-header">
                            <h2 class="ts-card-title"><span class="dashicons dashicons-admin-tools"></span> <?php 
            echo esc_html( ts_t( 'Diagnostics & Debugging' ) );
            ?></h2>
                        </div>
                        <div class="ts-card-body">
                            <p style="font-size: 14px; color: #646970; margin-top: 0; margin-bottom: 20px;">
                                <?php 
            echo esc_html( ts_t( 'If you are experiencing issues, you can download the internal plugin logs to share with support.' ) );
            ?>
                            </p>
                            <a href="<?php 
            echo esc_url( admin_url( 'admin.php?page=ts_settings_page&download_sahldesk_logs=1' ) );
            ?>" class="button button-secondary" style="display: inline-flex; align-items: center; justify-content: center; padding: 5px 15px; height: 35px; border-radius: 4px;">
                                <span class="dashicons dashicons-download" style="margin: 0 5px !important; margin-top: 0 !important; vertical-align: middle !important; display: inline-flex; align-items: center; justify-content: center;"></span> <span style="line-height: 1; display: inline-flex; align-items: center;"><?php 
            echo esc_html( ts_t( 'Download Logs' ) );
            ?></span>
                            </a>
                        </div>

</div>

                </div> <!-- End Grid -->

                <!-- Danger Zone -->

                <?php 
            if ( !function_exists( 'sahldesk_fs' ) || !sahldesk_fs()->is_registered() ) {
                ?>

                    <div style="margin-top: 35px; border-top: 1px solid #e2e4e7; padding-top: 20px;">

                        <form method="post" onsubmit="return confirm('<?php 
                /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
                echo esc_js( ts_t( 'Are you sure? This will disconnect your ticketing system from the API and stop all ticket creation on this site.' ) );
                ?>');">
                            <?php 
                wp_nonce_field( 'ts_deactivate_action', 'ts_nonce' );
                ?>

                            <button type="submit" name="ts_deactivate_license" class="button" style="display: inline-flex; align-items: center; justify-content: center; padding: 5px 15px; height: 35px; border-radius: 4px; color: #b32d2e; border-color: #b32d2e; background: #fff;">
                                <span class="dashicons dashicons-warning" style="margin: 0 5px !important; margin-top: 0 !important; vertical-align: middle !important; display: inline-flex; align-items: center; justify-content: center;"></span> <span style="line-height: 1; display: inline-flex; align-items: center;"><?php 
                echo esc_html( ts_t( 'Deactivate License (Move to another site)' ) );
                ?></span>
                            </button>

                        </form>

                    </div>

                <?php 
            }
            ?>



            </div>

        <?php 
        }
        ?>

    

        </div>



    <?php 
    }

}
// 2. REGISTRATION SHORTCODE & HANDLER
// =================================================================
if ( !function_exists( 'display_registration_form' ) ) {
    function display_registration_form() {
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_GET['registration'] ) && sanitize_text_field( wp_unslash( $_GET['registration'] ) ) == 'success' ) {
            return '<h3>Thank you for registering!</h3><p>You may now log in.</p>';
        }
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_GET['registration'] ) && sanitize_text_field( wp_unslash( $_GET['registration'] ) ) == 'failed' ) {
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $api_err_raw = ( isset( $_GET['api_err'] ) ? urldecode( sanitize_text_field( wp_unslash( $_GET['api_err'] ) ) ) : '' );
            // Custom nicely formatted message if the user is already registered
            if ( strpos( $api_err_raw, 'already exists' ) !== false ) {
                return '<div style="padding:20px; background:#e7f5ff; color:' . esc_attr( get_option( 'ts_widget_color', '#0056b3' ) ) . '; border:1px solid #b8daff; border-radius:8px; margin-bottom:20px; text-align:center; font-family:-apple-system, BlinkMacSystemFont, sans-serif;">

                        <h3 style="margin-top:0; color:' . esc_attr( get_option( 'ts_widget_color', '#0056b3' ) ) . ';">' . ts_t( 'You are already registered!' ) . '</h3>

                        <p style="font-size:15px; margin-bottom:15px;">' . ts_t( 'An account with this email already exists in our system. Please log in to access your dashboard.' ) . '</p>

                        <a href="' . remove_query_arg( ['registration', 'api_err'] ) . '" style="display:inline-block; background:' . esc_attr( get_option( 'ts_widget_color', '#0056b3' ) ) . '; color:#fff; padding:10px 20px; border-radius:6px; text-decoration:none; font-weight:600;">' . ts_t( 'Log In Now' ) . '</a>

                    </div>';
            }
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $err = ( isset( $_GET['api_err'] ) ? '<br><br><strong>Server Response:</strong> ' . esc_html( $api_err_raw ) : '' );
            return '<div style="padding:15px; background:#fff5f5; color:#c53030; border:1px solid #fc8181; border-radius:6px; margin-bottom:20px; text-align:center;"><h3>' . ts_t( 'Registration Failed.' ) . '</h3><p>' . ts_t( 'The email might already be in use or check your API Key settings.' ) . $err . '</p></div>';
        }
        ob_start();
        ?>

    <form action="" method="post">

        <?php 
        wp_nonce_field( 'ts_register_action' );
        ?>

        <p><label for="ts_name"><?php 
        echo esc_html( ts_t( 'Name' ) );
        ?></label><br><input type="text" id="ts_name" name="ts_name" required oninvalid="this.setCustomValidity('<?php 
        echo esc_js( ts_t( 'Please fill out this field.' ) );
        ?>')" oninput="this.setCustomValidity('')" style="width:100%"></p>

        <p><label for="ts_email"><?php 
        echo esc_html( ts_t( 'Email' ) );
        ?></label><br><input type="email" id="ts_email" name="ts_email" required oninvalid="this.setCustomValidity('<?php 
        echo esc_js( ts_t( 'Please fill out this field.' ) );
        ?>')" oninput="this.setCustomValidity('')" style="width:100%"></p>

        <p><label for="ts_phone"><?php 
        echo esc_html( ts_t( 'Phone Number' ) );
        ?></label><br><input type="tel" id="ts_phone" name="ts_phone" style="width:100%"></p>

        <p><label for="ts_password"><?php 
        echo esc_html( ts_t( 'Password' ) );
        ?></label><br><input type="password" id="ts_password" name="ts_password" required oninvalid="this.setCustomValidity('<?php 
        echo esc_js( ts_t( 'Please fill out this field.' ) );
        ?>')" oninput="this.setCustomValidity('')" style="width:100%"></p>

        <p><input type="submit" name="submit_registration" value="<?php 
        echo esc_html( ts_t( 'Register' ) );
        ?>"></p>

    </form>

    <?php 
        return ob_get_clean();
    }

}
add_shortcode( 'ticketing_system_register', 'display_registration_form' );
if ( !function_exists( 'handle_registration_submission' ) ) {
    function handle_registration_submission() {
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_POST['submit_registration'] ) ) {
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            if ( !isset( $_POST['_wpnonce'] ) || !wp_verify_nonce( sanitize_text_field( wp_unslash( ( isset( $_POST['_wpnonce'] ) ? $_POST['_wpnonce'] : '' ) ) ), 'ts_register_action' ) ) {
                wp_die( 'Security check failed.' );
            }
            $api_key = get_option( 'ts_tenant_api_key' );
            if ( empty( $api_key ) ) {
                wp_die( 'Error: API Key is missing. Check settings.' );
            }
            $api_url = TS_API_BASE_URL . '/auth/register';
            // Sanitize and Unslash
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $name = sanitize_text_field( wp_unslash( $_POST['ts_name'] ) );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $email = sanitize_email( wp_unslash( ( isset( $_POST['ts_email'] ) ? $_POST['ts_email'] : '' ) ) );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $password = wp_unslash( $_POST['ts_password'] );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $phone = ( isset( $_POST['ts_phone'] ) ? sanitize_text_field( wp_unslash( $_POST['ts_phone'] ) ) : '' );
            $body = [
                'name'        => $name,
                'email'       => $email,
                'password'    => $password,
                'phoneNumber' => $phone,
                'language'    => ts_get_api_language(),
            ];
            $args = [
                'method'      => 'POST',
                'headers'     => [
                    'Content-Type' => 'application/json',
                    'X-Api-Key'    => $api_key,
                ],
                'body'        => json_encode( $body ),
                'data_format' => 'body',
            ];
            $response = wp_remote_post( $api_url, $args );
            $current_page_url = remove_query_arg( 'registration' );
            if ( is_wp_error( $response ) ) {
                $err_msg = urlencode( 'cURL Error: ' . $response->get_error_message() );
                wp_safe_redirect( add_query_arg( [
                    'registration' => 'failed',
                    'api_err'      => $err_msg,
                ], $current_page_url ) );
                exit;
            }
            $response_code = wp_remote_retrieve_response_code( $response );
            if ( $response_code == 200 ) {
                wp_safe_redirect( add_query_arg( 'registration', 'success', $current_page_url ) );
                exit;
            } else {
                $res_body = wp_remote_retrieve_body( $response );
                $err_msg = urlencode( 'HTTP ' . $response_code . ' - ' . substr( $res_body, 0, 200 ) );
                wp_safe_redirect( add_query_arg( [
                    'registration' => 'failed',
                    'api_err'      => $err_msg,
                ], $current_page_url ) );
                exit;
            }
            exit;
        }
    }

}
add_action( 'init', 'handle_registration_submission' );
// =================================================================
// 3. LOGIN SHORTCODE & HANDLER (REDESIGNED)
// =================================================================
// 3. LOGIN SHORTCODE & HANDLER (REFINED "ALREADY LOGGED IN" STATE)
// =================================================================
if ( !function_exists( 'display_login_form' ) ) {
    function display_login_form() {
        // --- STATE 1: ALREADY LOGGED IN ---
        if ( isset( $_SESSION['ts_auth_token'] ) ) {
            $user_name = ( isset( $_SESSION['ts_user_name'] ) ? sanitize_text_field( wp_unslash( $_SESSION['ts_user_name'] ) ) : 'User' );
            $lang = get_locale();
            $dash_url = ( strpos( $lang, 'ar' ) === 0 ? ts_get_page_url( 'support-dashboard-ar', 'Support Dashboard AR' ) : ts_get_page_url( 'support-dashboard', 'Support Dashboard' ) );
            return '<div style="max-width:400px; margin:50px auto; background:#fff; padding:40px; border-radius:12px; box-shadow:0 10px 25px rgba(0,0,0,0.05); text-align:center; border:1px solid #f0f0f1; font-family:-apple-system, BlinkMacSystemFont, sans-serif;">

            

            <div style="width:80px; height:80px; background:#e7f5ff; color:' . esc_attr( get_option( 'ts_widget_color', '#0056b3' ) ) . '; border-radius:50%; display:flex; align-items:center; justify-content:center; margin:0 auto 20px auto; font-size:35px;">

                👤

            </div>



            <h2 style="margin:0 0 10px 0; color:#333; font-size:22px;">' . ts_t( 'Welcome back' ) . ', ' . esc_html( $user_name ) . '!</h2>

            <p style="color:#666; margin-bottom:30px; line-height:1.5;">' . ts_t( 'You are currently signed in to your account.' ) . '</p>

            

            <a href="' . esc_url( $dash_url ) . '" class="button button-primary" style="display:block; width:100%; text-align:center; padding:12px 0; font-size:16px; margin-bottom:15px; background-color:' . esc_attr( get_option( 'ts_widget_color', '#0056b3' ) ) . '; border:none; color:#fff; text-decoration:none; border-radius:6px; font-weight:600;">

                ' . ts_t( 'Go to Dashboard' ) . '

            </a>

            

            <a href="?action=ts_logout" style="color:#dc3545; font-size:14px; text-decoration:none; font-weight:500;">

                ' . ts_t( 'Logout' ) . '

            </a>

        </div>';
        }
        // --- STATE 2: SHOW LOGIN FORM ---
        // Check for error messages
        $error_msg = '';
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_GET['login'] ) && sanitize_text_field( wp_unslash( $_GET['login'] ) ) == 'failed' ) {
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $api_err = ( isset( $_GET['api_err'] ) ? urldecode( sanitize_text_field( wp_unslash( $_GET['api_err'] ) ) ) : '' );
            $main_msg = ts_t( 'Invalid email or password.' );
            if ( strpos( $api_err, 'HTTP 50' ) !== false || strpos( $api_err, 'HTTP 404' ) !== false || strpos( $api_err, 'cURL Error' ) !== false ) {
                $main_msg = ts_t( 'Connection to the server failed.' );
            }
            $error_msg = '<div style="padding:12px; background:#fff5f5; color:#c53030; border:1px solid #fc8181; border-radius:4px; margin-bottom:20px; font-size:13px; text-align:center;">
            ' . $main_msg . '
        </div>';
        }
        ob_start();
        ?>

    <style>

        .ts-auth-container { max-width: 400px; margin: 40px auto; background: #ffffff; padding: 40px; border-radius: 12px; box-shadow: 0 10px 30px -5px rgba(0, 0, 0, 0.1); border: 1px solid #e2e8f0; font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; color: #0f172a; }

        .ts-form-group { margin-bottom: 20px; }

        .ts-form-label { display: block; margin-bottom: 8px; font-weight: 600; color: #2c3e50; font-size: 14px; }

        .ts-form-input { width: 100%; padding: 12px 15px; border: 1px solid #dfe1e5; border-radius: 6px; font-size: 15px; box-sizing: border-box; transition: all 0.2s; }

        .ts-form-input:focus { border-color: <?php 
        echo esc_attr( get_option( 'ts_widget_color', '#0056b3' ) );
        ?>; outline: none; box-shadow: 0 0 0 3px rgba(0, 86, 179, 0.1); }

        .ts-submit-btn { width: 100%; padding: 12px; background: linear-gradient(135deg, #0ea5e9, #2563eb); color: white; border: none; border-radius: 8px; font-size: 16px; font-weight: 600; cursor: pointer; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); box-shadow: 0 4px 12px rgba(37, 99, 235, 0.2), 0 2px 4px rgba(37, 99, 235, 0.1); letter-spacing: 0.3px; }

        .ts-submit-btn:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(37, 99, 235, 0.3), 0 3px 6px rgba(37, 99, 235, 0.15); filter: brightness(1.05); }
        .ts-submit-btn:active { transform: translateY(0); box-shadow: 0 2px 4px rgba(37, 99, 235, 0.2); }

        .ts-auth-footer { margin-top: 20px; text-align: center; font-size: 13px; color: #666; }

        .ts-auth-footer a { color: <?php 
        echo esc_attr( get_option( 'ts_widget_color', '#0056b3' ) );
        ?>; text-decoration: none; font-weight: 500; }

        .ts-auth-footer a:hover { text-decoration: underline; }

    </style>



    <div class="ts-auth-container">

        <h2 style="text-align:center; margin-top:0; margin-bottom:30px; color:#333;"><?php 
        echo esc_html( ts_t( 'Login' ) );
        ?></h2>

        

        <?php 
        echo wp_kses_post( $error_msg );
        ?>



        <form action="" method="post">

            <?php 
        wp_nonce_field( 'ts_login_action' );
        ?>

            

            <div class="ts-form-group">

                <label class="ts-form-label" for="ts_email"><?php 
        echo esc_html( ts_t( 'Email' ) );
        ?></label>

                <input type="email" id="ts_email" name="ts_email" class="ts-form-input" required oninvalid="this.setCustomValidity('<?php 
        /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
        echo esc_js( ts_t( 'Please fill out this field.' ) );
        ?>')" oninput="this.setCustomValidity('')" placeholder="name@company.com">

            </div>

            

            <div class="ts-form-group">

                <div style="display:flex; justify-content:space-between;">

                    <label class="ts-form-label" for="ts_password"><?php 
        echo esc_html( ts_t( 'Password' ) );
        ?></label>

                    <a href="<?php 
        echo esc_url( ( strpos( get_locale(), 'ar' ) === 0 ? ts_get_page_url( 'forgot-password-ar', 'Forgot Password AR' ) : ts_get_page_url( 'forgot-password', 'Forgot Password' ) ) );
        ?>" style="font-size:12px; color:<?php 
        echo esc_attr( get_option( 'ts_widget_color', '#0056b3' ) );
        ?>; text-decoration:none;"><?php 
        echo esc_html( ts_t( 'Forgot?' ) );
        ?></a>

                </div>

                <input type="password" id="ts_password" name="ts_password" class="ts-form-input" required oninvalid="this.setCustomValidity('<?php 
        /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
        echo esc_js( ts_t( 'Please fill out this field.' ) );
        ?>')" oninput="this.setCustomValidity('')" placeholder="••••••••">

            </div>

            

            <button type="submit" name="submit_login" class="ts-submit-btn"><?php 
        echo esc_html( ts_t( 'Sign In' ) );
        ?></button>

        </form>



        <div class="ts-auth-footer">

            <?php 
        echo esc_html( ts_t( "Don't have an account?" ) );
        ?> <a href="<?php 
        echo esc_url( ( strpos( get_locale(), 'ar' ) === 0 ? ts_get_page_url( 'register-ar', 'Register AR' ) : ts_get_page_url( 'register', 'Register' ) ) );
        ?>"><?php 
        echo esc_html( ts_t( 'Register' ) );
        ?></a>

        </div>

        <?php 
        echo wp_kses_post( ts_render_footer() );
        ?>

    </div>

    <?php 
        return ob_get_clean();
    }

}
add_shortcode( 'ticketing_system_login', 'display_login_form' );
if ( !function_exists( 'handle_login_submission' ) ) {
    function handle_login_submission() {
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_POST['submit_login'] ) ) {
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            if ( !isset( $_POST['_wpnonce'] ) || !wp_verify_nonce( sanitize_text_field( wp_unslash( ( isset( $_POST['_wpnonce'] ) ? $_POST['_wpnonce'] : '' ) ) ), 'ts_login_action' ) ) {
                wp_die( 'Security check failed.' );
            }
            $api_key = get_option( 'ts_tenant_api_key' );
            if ( empty( $api_key ) ) {
                wp_die( 'Error: API Key is missing. Check settings.' );
            }
            $api_url = TS_API_BASE_URL . '/auth/login';
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $email = sanitize_email( wp_unslash( ( isset( $_POST['ts_email'] ) ? $_POST['ts_email'] : '' ) ) );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $password = wp_unslash( $_POST['ts_password'] );
            $args = [
                'method'      => 'POST',
                'headers'     => [
                    'Content-Type' => 'application/json',
                    'X-Api-Key'    => $api_key,
                ],
                'body'        => json_encode( [
                    'email'    => $email,
                    'password' => $password,
                ] ),
                'data_format' => 'body',
                'timeout'     => 15,
            ];
            $response = wp_remote_post( $api_url, $args );
            $current_page_url = remove_query_arg( 'login' );
            if ( is_wp_error( $response ) ) {
                $err_msg = urlencode( 'cURL Error: ' . $response->get_error_message() );
                wp_safe_redirect( add_query_arg( [
                    'login'   => 'failed',
                    'api_err' => $err_msg,
                ], $current_page_url ) );
                exit;
            }
            $response_code = wp_remote_retrieve_response_code( $response );
            if ( $response_code == 200 ) {
                $response_body = json_decode( wp_remote_retrieve_body( $response ), true );
                if ( isset( $response_body['token'] ) && isset( $response_body['role'] ) ) {
                    if ( !session_id() ) {
                        session_start();
                    }
                    $_SESSION['ts_auth_token'] = $response_body['token'];
                    $_SESSION['ts_user_role'] = $response_body['role'];
                    $_SESSION['ts_user_name'] = $response_body['name'];
                    session_write_close();
                    $lang = get_locale();
                    $dash_url = ( strpos( $lang, 'ar' ) === 0 ? ts_get_page_url( 'support-dashboard-ar', 'Support Dashboard AR' ) : ts_get_page_url( 'support-dashboard', 'Support Dashboard' ) );
                    wp_safe_redirect( $dash_url );
                    exit;
                }
            }
            $res_body = wp_remote_retrieve_body( $response );
            $details = ( empty( $res_body ) ? 'Server returned empty response.' : substr( $res_body, 0, 200 ) );
            if ( $response_code == 503 ) {
                $details = 'Service Unavailable (The API is down, starting up, or unreachable).';
            } elseif ( $response_code == 404 ) {
                $details = 'API endpoint not found.';
            }
            $err_msg = urlencode( 'HTTP ' . $response_code . ' - ' . $details );
            wp_safe_redirect( add_query_arg( [
                'login'   => 'failed',
                'api_err' => $err_msg,
            ], $current_page_url ) );
            exit;
        }
    }

}
add_action( 'init', 'handle_login_submission' );
// =================================================================
// SINGLE SIGN-ON (SSO) HELPER
// =================================================================
if ( !function_exists( 'ts_try_sso_login' ) ) {
    function ts_try_sso_login() {
        // Only attempt SSO if they are logged into WP but NOT yet logged into SahlDesk
        if ( !is_user_logged_in() || isset( $_SESSION['ts_auth_token'] ) ) {
            return;
        }
        $api_key = get_option( 'ts_tenant_api_key' );
        if ( empty( $api_key ) ) {
            return;
        }
        $wp_user = wp_get_current_user();
        $api_url = TS_API_BASE_URL . '/users/sso';
        $body = [
            'Email' => $wp_user->user_email,
            'Name'  => ( !empty( $wp_user->display_name ) ? $wp_user->display_name : $wp_user->user_login ),
        ];
        $args = [
            'method'      => 'POST',
            'headers'     => [
                'Content-Type' => 'application/json',
                'X-Api-Key'    => $api_key,
            ],
            'body'        => json_encode( $body ),
            'data_format' => 'body',
            'timeout'     => 15,
        ];
        $response = wp_remote_post( $api_url, $args );
        if ( !is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) == 200 ) {
            $response_body = json_decode( wp_remote_retrieve_body( $response ), true );
            if ( isset( $response_body['token'] ) && isset( $response_body['role'] ) ) {
                if ( !session_id() ) {
                    session_start();
                }
                $_SESSION['ts_auth_token'] = $response_body['token'];
                $_SESSION['ts_user_role'] = $response_body['role'];
                $_SESSION['ts_user_name'] = $response_body['name'];
                session_write_close();
            }
        }
    }

}
// 4. DASHBOARD SHORTCODE (WITH FILTER & EXPORT)
// =================================================================
if ( !function_exists( 'display_ticket_dashboard' ) ) {
    function display_ticket_dashboard() {
        ts_try_sso_login();
        // Attempt SSO if WP user is logged in
        // 1. AUTH CHECK
        if ( !isset( $_SESSION['ts_auth_token'] ) ) {
            $lang = get_locale();
            $login_slug = ( strpos( $lang, 'ar' ) === 0 ? 'support-login-ar' : 'support-login' );
            $login_title = ( strpos( $lang, 'ar' ) === 0 ? 'Support Login AR' : 'Support Login' );
            $login_url = ts_get_page_url( $login_slug, $login_title );
            $admin_msg = ( current_user_can( 'manage_options' ) ? '<p style="color:#d6336c; font-size:12px; margin-top:15px;"><em>Admin Note: WordPress WP-Admin sessions are separate from the Ticketing System SaaS. To view this, log in via the customer form.</em></p>' : '' );
            return '<div class="ts-login-prompt" style="text-align:center; padding:40px; background:#f9f9f9; border-radius:8px;">

            <h3>' . ts_t( 'Access Denied' ) . '</h3>

            <p>' . ts_t( 'Please Log In to view your tickets.' ) . '</p>

            <a href="' . esc_url( $login_url ) . '" class="button button-primary">' . ts_t( 'Login Now' ) . '</a>' . $admin_msg . '

        </div>';
        }
        $token = sanitize_text_field( wp_unslash( $_SESSION['ts_auth_token'] ) );
        $user_role = ( isset( $_SESSION['ts_user_role'] ) ? sanitize_text_field( wp_unslash( $_SESSION['ts_user_role'] ) ) : 'Customer' );
        $user_name = ( isset( $_SESSION['ts_user_name'] ) ? sanitize_text_field( wp_unslash( $_SESSION['ts_user_name'] ) ) : 'User' );
        $api_key = get_option( 'ts_tenant_api_key' );
        $api_url = TS_API_BASE_URL . '/tickets';
        // 2. FETCH TICKETS
        $args = [
            'method'      => 'GET',
            'headers'     => [
                'Authorization' => 'Bearer ' . $token,
                'X-Api-Key'     => $api_key,
            ],
            'data_format' => 'body',
        ];
        $response = wp_remote_get( $api_url, $args );
        if ( is_wp_error( $response ) ) {
            return '<div class="notice notice-error"><p>' . ts_t( 'Error' ) . ': ' . esc_html( $response->get_error_message() ) . '</p></div>';
        }
        $code = wp_remote_retrieve_response_code( $response );
        if ( $code == 401 || $code == 403 ) {
            if ( !session_id() ) {
                session_start();
            }
            unset($_SESSION['ts_auth_token']);
            unset($_SESSION['ts_user_role']);
            unset($_SESSION['ts_user_name']);
            session_write_close();
            $lang = get_locale();
            $login_slug = ( strpos( $lang, 'ar' ) === 0 ? 'support-login-ar' : 'support-login' );
            $login_title = ( strpos( $lang, 'ar' ) === 0 ? 'Support Login AR' : 'Support Login' );
            $login_url = ts_get_page_url( $login_slug, $login_title );
            return '<div class="ts-login-prompt" style="text-align:center; padding:40px; background:#fff3f3; border-radius:8px; border:1px solid #ffcaca;">

            <h3 style="color:#d63638; margin-top:0;">' . ts_t( 'Session Expired' ) . '</h3>

            <p>' . ts_t( 'Your security token has expired. Please log in again to continue.' ) . '</p>

            <a href="' . esc_url( $login_url ) . '" class="button button-primary">' . ts_t( 'Login Now' ) . '</a>

        </div>';
        }
        $body_text = wp_remote_retrieve_body( $response );
        $tickets = json_decode( $body_text, true );
        if ( !is_array( $tickets ) ) {
            if ( $code != 200 && $code != 204 ) {
                return '<div class="notice notice-error"><p><strong>' . ts_t( 'API Error' ) . ' (' . esc_html( $code ) . '):</strong> ' . esc_html( substr( $body_text, 0, 250 ) ) . '</p></div>';
            }
            $tickets = [];
        }
        // --- FETCH CATEGORIES FOR COLORS ---
        $cat_response = wp_remote_get( TS_API_BASE_URL . '/categories', [
            'headers'     => [
                'Authorization' => 'Bearer ' . $token,
                'X-Api-Key'     => $api_key,
            ],
            'data_format' => 'body',
        ] );
        $categories = ( !is_wp_error( $cat_response ) && wp_remote_retrieve_response_code( $cat_response ) == 200 ? json_decode( wp_remote_retrieve_body( $cat_response ), true ) : [] );
        $category_colors = [];
        foreach ( $categories as $cat ) {
            if ( isset( $cat['name'] ) ) {
                $category_colors[$cat['name']] = ( isset( $cat['color'] ) ? $cat['color'] : '#6c757d' );
            }
        }
        // Sort by Date (Newest First)
        usort( $tickets, function ( $a, $b ) {
            $t1 = ( isset( $a['createdDate'] ) ? strtotime( $a['createdDate'] ) : 0 );
            $t2 = ( isset( $b['createdDate'] ) ? strtotime( $b['createdDate'] ) : 0 );
            return $t2 - $t1;
        } );
        ob_start();
        ?>

    <style>

        /* MODERN DASHBOARD STYLES */

        @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');

        

        .ts-dashboard-wrapper { font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; max-width: 1200px; margin: 0 auto; color: #0f172a; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }

        

        .ts-dash-header { display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: 25px; padding-bottom: 20px; border-bottom: 1px solid #e2e8f0; flex-wrap: wrap; gap: 15px; }

        .ts-dash-title h2 { margin: 0; font-size: 28px; font-weight: 700; color: #0f172a; letter-spacing: -0.5px; }

        .ts-dash-title span { font-size: 15px; color: #475569; font-weight: 400; display: block; margin-top: 4px; }

        

        .ts-actions { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; } 

        

        /* Search and Filter Inputs */

        .ts-controls-row { display: flex; gap: 12px; margin-bottom: 20px; flex-wrap: wrap; align-items: center; }

        .ts-search-input, .ts-filter-select { box-sizing: border-box; padding: 10px 14px; line-height: 1.5; min-height: 44px; border: 1px solid #cbd5e1; border-radius: 8px; font-size: 14px; color: #334155; outline: none; transition: all 0.2s ease; background-color: #fff; box-shadow: 0 1px 2px rgba(0,0,0,0.03); vertical-align: middle; }

        
        /* RTL support for filter select dropdowns */
        body:not(.rtl) .ts-filter-select { padding-right: 30px; }
        body.rtl .ts-filter-select { padding-left: 30px; padding-right: 14px; background-position: left 10px center; }
        .ts-search-input:focus, .ts-filter-select:focus { border-color: #3b82f6; box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15); }

        .ts-search-input { width: 320px; max-width: 100%; }



        .ts-btn-new { background: linear-gradient(135deg, #0ea5e9, #2563eb); color: white !important; text-decoration: none; padding: 10px 20px; border-radius: 8px; font-weight: 600; font-size: 14px; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); display: inline-flex; align-items: center; gap: 8px; box-shadow: 0 4px 12px rgba(37, 99, 235, 0.2), 0 2px 4px rgba(37, 99, 235, 0.1); border: none; letter-spacing: 0.3px; }

        .ts-btn-new:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(37, 99, 235, 0.3), 0 3px 6px rgba(37, 99, 235, 0.15); filter: brightness(1.05); }
        .ts-btn-new:active { transform: translateY(0); box-shadow: 0 2px 4px rgba(37, 99, 235, 0.2); }



        .ts-btn-export { background-color: #fff; color: #334155 !important; text-decoration: none; padding: 10px 16px; border-radius: 8px; font-weight: 600; font-size: 14px; transition: all 0.2s ease; display: inline-flex; align-items: center; gap: 8px; cursor: pointer; border: 1px solid #cbd5e1; box-shadow: 0 1px 2px rgba(0,0,0,0.03); }

        .ts-btn-export:hover { background-color: #f8fafc; border-color: #94a3b8; }



        .ts-table-card { background: #fff; border: 1px solid #e2e8f0; border-radius: 12px; overflow: hidden; box-shadow: 0 10px 30px -5px rgba(0, 0, 0, 0.1); }

        .ts-table-scroll { overflow-x: auto; }

        

        .ts-ticket-table { width: 100%; border-collapse: separate; border-spacing: 0; min-width: 900px; }

        .ts-ticket-table th { background: #f8fafc; color: #475569; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; padding: 16px 20px; text-align: left; border-bottom: 1px solid #e2e8f0; }

        .ts-ticket-table td { padding: 18px 20px; border-bottom: 1px solid #f1f5f9; color: #1e293b; font-size: 14px; vertical-align: middle; transition: background 0.2s ease; }

        .ts-ticket-table tr:last-child td { border-bottom: none; }

        .ts-ticket-row:hover td { background-color: #f0f9ff; cursor: pointer; }



        /* COLUMNS */

        .col-id { width: 8%; font-weight: 700; color: #334155; }

        .col-subject { width: 40%; }

        .col-customer { width: 15%; }

        .col-agent { width: 15%; }

        .col-status { width: 12%; }

        .col-created { width: 10%; color: #475569; font-size: 13px; font-weight: 500; white-space: nowrap; }



        .ts-ticket-title { font-weight: 700; color: #0f172a; text-decoration: none; font-size: 16px; margin-bottom: 6px; display: block; }

        .ts-ticket-row:hover .ts-ticket-title { color: #2563eb; }



        .ts-meta-text { color: #64748b; font-size: 13px; font-weight: 500; display: flex; align-items: center; gap: 8px; }

        

        .ts-status-badge { display: inline-flex; align-items: center; padding: 4px 12px; border-radius: 20px; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.3px; }

        .ts-cat-badge { display: inline-block; padding: 2px 8px; border-radius: 6px; font-size: 11px; font-weight: 600; color: #fff; }

        

        .status-open { background: #dcfce7; color: #166534; border: 1px solid #bbf7d0; }

        .status-closed { background: #f1f5f9; color: #475569; border: 1px solid #e2e8f0; }

        .status-progress { background: #dbeafe; color: #1e40af; border: 1px solid #bfdbfe; }

        .status-pending { background: #fef08a; color: #92400e; border: 1px solid #fde047; }

        

        .ts-avatar { width: 28px; height: 28px; border-radius: 50%; background: #e2e8f0; display: inline-flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 600; color: #475569; margin-right: 8px; vertical-align: middle; }



        .ts-empty-state { text-align: center; padding: 80px 20px; }

        .ts-empty-icon { max-width: 150px; margin: 0 auto 20px auto; opacity: 0.8; }

        .ts-empty-state h3 { font-size: 20px; color: #0f172a; margin-bottom: 8px; font-weight: 600; }

        .ts-empty-state p { color: #64748b; font-size: 15px; max-width: 400px; margin: 0 auto; }



        /* Responsive Mobile Cards */

        @media (max-width: 768px) {

            .ts-dashboard-wrapper { box-sizing: border-box; overflow-x: hidden; }

            .ts-dash-header { flex-direction: column; align-items: flex-start; }

            .ts-actions { width: 100%; justify-content: flex-start; margin-top: 10px; }

            .ts-controls-row { flex-direction: column; align-items: stretch; }

            .ts-search-input { width: 100%; max-width: none; }

            

            .ts-table-scroll { overflow-x: visible; width: 100%; }

            .ts-ticket-table, .ts-ticket-table tbody, .ts-ticket-table tr, .ts-ticket-table td { display: block; width: 100%; min-width: 0 !important; box-sizing: border-box; }

            .ts-ticket-table thead { display: none; }

            

            .ts-ticket-row { position: relative; border-bottom: 1px solid #e2e8f0; padding: 16px; background: #fff; margin-bottom: 12px; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.08); border: 1px solid #e2e8f0; transition: transform 0.2s; box-sizing: border-box; }

            .ts-ticket-row:hover { transform: translateY(-2px); box-shadow: 0 8px 24px rgba(0,0,0,0.12); }

            .ts-ticket-row td { padding: 4px 0; border: none; }

            

            .col-id { font-size: 13px; margin-bottom: 8px; display: block; width: 100%; color: #94a3b8; }

            .col-status { position: absolute; top: 16px; right: 16px; display: block; width: auto; text-align: right; margin: 0; padding: 0 !important; }

            .col-subject { margin-bottom: 12px; width: 100%; padding-right: 60px !important; } /* Space so long titles dont hit the badge */

            .col-customer, .col-agent { display: block; width: 100%; font-size: 13px; color: #64748b; margin-bottom: 4px; }

            .col-created { display: block; width: 100%; margin-top: 12px; font-size: 12px; border-top: 1px dashed #e2e8f0; padding-top: 12px !important; }

            

            .ts-table-card { background: transparent; border: none; box-shadow: none; padding: 0; }

        }

    </style>



    <div class="ts-dashboard-wrapper">

        

        <div class="ts-dash-header">

            <div class="ts-dash-title">

                <h2><?php 
        echo esc_html( ( $user_role == 'Agent' || $user_role == 'Admin' ? ts_t( 'Support Dashboard' ) : ts_t( 'My Tickets' ) ) );
        ?></h2>

                <span><?php 
        echo esc_html( ts_t( 'Welcome back' ) );
        ?>, <strong><?php 
        echo esc_html( $user_name );
        ?></strong>. <?php 
        echo esc_html( ts_t( 'Here is what needs your attention.' ) );
        ?></span>

            </div>

            

            <div class="ts-actions">

                <button onclick="tsExportToExcel()" class="ts-btn-export">

                    <svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path></svg>

                    <?php 
        echo esc_html( ts_t( 'Export' ) );
        ?>

                </button>

                <a href="<?php 
        /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
        echo ( strpos( get_locale(), 'ar' ) === 0 ? ts_get_page_url( 'create-ticket-ar', 'Create Ticket AR' ) : ts_get_page_url( 'create-ticket', 'Create Ticket' ) );
        ?>" class="ts-btn-new">

                    <svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4"></path></svg>

                    <?php 
        echo esc_html( ts_t( 'New Ticket' ) );
        ?>

                </a>

            </div>

        </div>



        <div class="ts-controls-row">

            <input type="text" id="ts-search-input" class="ts-search-input" placeholder="<?php 
        echo esc_html( ts_t( 'Search tickets by subject or ID...' ) );
        ?>" onkeyup="tsFilterTickets()">

            <select id="ts-status-filter" class="ts-filter-select" onchange="tsFilterTickets()">

                <option value="all"><?php 
        echo esc_html( ts_t( 'All Statuses' ) );
        ?></option>

                <option value="open" selected><?php 
        echo esc_html( ts_t( 'Open' ) );
        ?></option>

                <option value="in progress"><?php 
        echo esc_html( ts_t( 'In Progress' ) );
        ?></option>

                <option value="pending"><?php 
        echo esc_html( ts_t( 'Pending' ) );
        ?></option>

                <option value="closed"><?php 
        echo esc_html( ts_t( 'Closed' ) );
        ?></option>

            </select>

            <?php 
        if ( $user_role === 'Agent' || $user_role === 'Admin' ) {
            ?>

            <select id="ts-assignee-filter" class="ts-filter-select" onchange="tsFilterTickets()">

                <option value="all"><?php 
            echo esc_html( ts_t( 'All Tickets' ) );
            ?></option>

                <option value="assigned_to_me"><?php 
            echo esc_html( ts_t( 'Assigned to Me' ) );
            ?></option>

                <option value="unassigned"><?php 
            echo esc_html( ts_t( 'Unassigned' ) );
            ?></option>

            </select>

            <?php 
        }
        ?>

        </div>



        <div class="ts-table-card">

            <?php 
        if ( empty( $tickets ) ) {
            ?>

                <div class="ts-empty-state">

                    <!-- Modern Empty State SVG -->

                    <svg class="ts-empty-icon" viewBox="0 0 24 24" fill="none" stroke="#cbd5e1" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">

                        <path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"></path>

                        <polyline points="3.27 6.96 12 12.01 20.73 6.96"></polyline>

                        <line x1="12" y1="22.08" x2="12" y2="12"></line>

                    </svg>

                    <h3><?php 
            echo esc_html( ts_t( 'No tickets found' ) );
            ?></h3>

                    <p><?php 
            echo esc_html( ts_t( 'You are all caught up! When you have tickets, they will appear beautifully here.' ) );
            ?></p>

                </div>

            <?php 
        } else {
            ?>

                <div class="ts-table-scroll">

                    <table class="ts-ticket-table" id="tsTicketsTable">

                        <thead>

                            <tr>

                                <th class="col-id"><?php 
            echo esc_html( ts_t( 'ID' ) );
            ?></th>

                                <th class="col-subject"><?php 
            echo esc_html( ts_t( 'Subject' ) );
            ?></th>

                                <?php 
            if ( $user_role === 'Agent' || $user_role === 'Admin' ) {
                ?>

                                    <th class="col-customer"><?php 
                echo esc_html( ts_t( 'Customer' ) );
                ?></th>

                                <?php 
            }
            ?>

                                <th class="col-agent"><?php 
            echo esc_html( ts_t( 'Assigned To' ) );
            ?></th>

                                <th class="col-status"><?php 
            echo esc_html( ts_t( 'Status' ) );
            ?></th>

                                <th class="col-created"><?php 
            echo esc_html( ts_t( 'Created' ) );
            ?></th>

                            </tr>

                        </thead>

                        <tbody>

                            <?php 
            foreach ( $tickets as $ticket ) {
                // DATE LOGIC
                $created_raw = ( isset( $ticket['createdDate'] ) ? $ticket['createdDate'] : '' );
                if ( !empty( $created_raw ) && !(substr( $created_raw, -1 ) === 'Z') ) {
                    $created_raw .= 'Z';
                }
                $closed_raw = ( isset( $ticket['closedDate'] ) ? $ticket['closedDate'] : '' );
                if ( !empty( $closed_raw ) && !(substr( $closed_raw, -1 ) === 'Z') ) {
                    $closed_raw .= 'Z';
                }
                // STATUS LOGIC
                $raw_status = ( isset( $ticket['status'] ) ? $ticket['status'] : 'Open' );
                $s = strtolower( $raw_status );
                // Used for filtering
                $badge_class = 'status-closed';
                if ( $s === 'open' ) {
                    $badge_class = 'status-open';
                }
                if ( $s === 'in progress' ) {
                    $badge_class = 'status-progress';
                }
                if ( $s === 'pending' ) {
                    $badge_class = 'status-pending';
                }
                // CUSTOMER LOGIC
                $cust_name = 'User';
                if ( isset( $ticket['customer']['name'] ) ) {
                    $cust_name = $ticket['customer']['name'];
                } elseif ( isset( $ticket['customerName'] ) ) {
                    $cust_name = $ticket['customerName'];
                } elseif ( !empty( $ticket['guestEmail'] ) ) {
                    $cust_name = $ticket['guestEmail'];
                }
                // AGENT LOGIC
                $agent_name = 'Unassigned';
                if ( isset( $ticket['agent']['name'] ) ) {
                    $agent_name = $ticket['agent']['name'];
                } elseif ( isset( $ticket['agentName'] ) ) {
                    $agent_name = $ticket['agentName'];
                }
                $agent_initial = substr( $agent_name, 0, 1 );
                ?>

                            

                            <tr class="ts-ticket-row" data-status="<?php 
                echo esc_attr( $s );
                ?>" data-agent="<?php 
                echo esc_attr( $agent_name );
                ?>" data-search="<?php 
                echo esc_attr( strtolower( $ticket['id'] . ' ' . $ticket['title'] ) );
                ?>" onclick="window.location='<?php 
                echo esc_url( add_query_arg( 'ticket_id', $ticket['id'], ts_get_page_url( 'view-ticket', 'View Ticket' ) ) );
                ?>';">

                                <td class="col-id">#<?php 
                echo esc_html( $ticket['id'] );
                ?></td>

                                

                                <td class="col-subject">

                                    <span class="ts-ticket-title"><?php 
                echo esc_html( $ticket['title'] );
                ?></span>

                                    <div class="ts-meta-text">

                                        <?php 
                $cat_name = $ticket['category'];
                $cat_color = ( isset( $category_colors[$cat_name] ) ? $category_colors[$cat_name] : '#64748b' );
                ?>

                                        <span class="ts-cat-badge" style="background-color:<?php 
                echo esc_attr( $cat_color );
                ?>;"><?php 
                echo esc_html( ts_t( $cat_name ) );
                ?></span>

                                        <span>&bull; <?php 
                echo esc_html( $ticket['priority'] );
                ?></span>

                                        <?php 
                if ( !empty( $ticket['referenceId'] ) ) {
                    ?>

                                            <span style="color:#7c3aed;">&bull; <?php 
                    echo esc_html( ts_t( 'Order' ) . ' #' . esc_html( $ticket['referenceId'] ) );
                    ?></span>

                                        <?php 
                }
                ?>

                                    </div>

                                </td>



                                <?php 
                if ( $user_role === 'Agent' || $user_role === 'Admin' ) {
                    ?>

                                    <td class="col-customer">

                                        <div style="font-weight:500; color:#0f172a;"><?php 
                    echo esc_html( $cust_name );
                    ?></div>

                                    </td>

                                <?php 
                }
                ?>



                                <td class="col-agent">

                                    <?php 
                if ( $agent_name !== 'Unassigned' ) {
                    ?>

                                        <div title="<?php 
                    echo esc_attr( $agent_name );
                    ?>" style="white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">

                                            <span class="ts-avatar"><?php 
                    echo esc_html( $agent_initial );
                    ?></span> <?php 
                    echo esc_html( $agent_name );
                    ?>

                                        </div>

                                    <?php 
                } else {
                    ?>

                                        <span style="color:#94a3b8; font-style:italic; font-size:13px;"><?php 
                    echo esc_html( ts_t( 'Unassigned' ) );
                    ?></span>

                                    <?php 
                }
                ?>

                                </td>



                                <td class="col-status">

                                    <span class="ts-status-badge <?php 
                echo esc_attr( $badge_class );
                ?>">

                                        <?php 
                echo esc_html( ts_t( $ticket['status'] ) );
                ?>

                                    </span>

                                    <?php 
                if ( !empty( $ticket['subStatus'] ) && is_array( $ticket['subStatus'] ) ) {
                    ?>

                                        <div style="margin-top:6px;"><span class="ts-cat-badge" style="background-color:<?php 
                    echo esc_attr( $ticket['subStatus']['color'] );
                    ?>; font-size:10px; padding:3px 8px;"><?php 
                    echo esc_html( ts_t( $ticket['subStatus']['name'] ) );
                    ?></span></div>

                                    <?php 
                }
                ?>

                                </td>

                                

                                <td class="col-created">

                                    <div class="ts-local-time" data-utc="<?php 
                echo esc_attr( $created_raw );
                ?>"></div>

                                    <?php 
                if ( $raw_status === 'Closed' && !empty( $closed_raw ) ) {
                    ?>

                                        <div style="margin-top:4px; color:#10b981; font-size:11px;">

                                            <?php 
                    echo esc_html( ts_t( 'Closed: ' ) );
                    ?><span class="ts-local-time" data-utc="<?php 
                    echo esc_attr( $closed_raw );
                    ?>"></span>

                                        </div>

                                    <?php 
                }
                ?>

                                </td>

                            </tr>

                            <?php 
            }
            ?>

                            

                            <tr id="ts-no-results-row" style="display:none;">

                                <td colspan="<?php 
            echo esc_html( ( $user_role === 'Agent' || $user_role === 'Admin' ? '6' : '5' ) );
            ?>" style="text-align:center; padding:40px; color:#64748b;">

                                    <?php 
            echo esc_html( ts_t( 'No tickets match your search or filter.' ) );
            ?>

                                </td>

                            </tr>

                        </tbody>

                    </table>

                    <script>

                        document.addEventListener('DOMContentLoaded', function() {

                            document.querySelectorAll('.ts-local-time').forEach(function(el) {

                                var utcDate = el.getAttribute('data-utc');

                                if (utcDate) {

                                    var date = new Date(utcDate);

                                    if (!isNaN(date.getTime())) {

                                        el.textContent = date.toLocaleString(undefined, { month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: '2-digit' });

                                    }

                                }

                            });

                        });

                    </script>

                </div>

            <?php 
        }
        ?>

        </div>

        <?php 
        echo wp_kses_post( ts_render_footer() );
        ?>

    </div>



    <script>

    // 1. FILTER & SEARCH FUNCTION

    function tsFilterTickets() {

        var statusFilter = document.getElementById('ts-status-filter').value.toLowerCase();

        

        var assigneeFilterEl = document.getElementById('ts-assignee-filter');

        var assigneeFilter = assigneeFilterEl ? assigneeFilterEl.value : 'all';

        var currentUserName = <?php 
        /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
        echo wp_json_encode( $user_name );
        ?>;

        

        var searchInput = document.getElementById('ts-search-input');

        var searchQuery = searchInput ? searchInput.value.toLowerCase() : '';

        

        var rows = document.querySelectorAll('.ts-ticket-row');

        var visibleCount = 0;



        rows.forEach(function(row) {

            var status = row.getAttribute('data-status');

            var searchData = row.getAttribute('data-search');

            var agentName = row.getAttribute('data-agent');

            

            var matchesStatus = (statusFilter === 'all' || status === statusFilter);

            var matchesSearch = (searchQuery === '' || searchData.includes(searchQuery));

            

            var matchesAssignee = true;

            if (assigneeFilter === 'assigned_to_me') {

                matchesAssignee = (agentName === currentUserName);

            } else if (assigneeFilter === 'unassigned') {

                matchesAssignee = (agentName === 'Unassigned');

            }



            if (matchesStatus && matchesSearch && matchesAssignee) {

                row.style.display = ''; // Show

                visibleCount++;

            } else {

                row.style.display = 'none'; // Hide

            }

        });



        // Toggle "No Results" message

        var noResRow = document.getElementById('ts-no-results-row');

        if (noResRow) {

            noResRow.style.display = (visibleCount === 0) ? '' : 'none';

        }

    }

    

    // Auto-run filter on load so closed tickets are hidden immediately

    tsFilterTickets();



    // 2. EXPORT FUNCTION

    function tsExportToExcel() {

        var table = document.getElementById("tsTicketsTable");

        if(!table) return;



        var rows = table.querySelectorAll("tr");

        var csvContent = [];

        

        for (var i = 0; i < rows.length; i++) {

            // Skip the "No results" row and hidden rows

            if (rows[i].id === "ts-no-results-row" || rows[i].style.display === "none") continue;



            var row = [], cols = rows[i].querySelectorAll("td, th");

            for (var j = 0; j < cols.length; j++) {

                var text = cols[j].innerText.replace(/(\r\n|\n|\r)/gm, " ").replace(/\s+/g, " ").trim();

                row.push('"' + text + '"'); 

            }

            if(row.length > 0) csvContent.push(row.join(","));

        }



        var csvContentString = csvContent.join("\n");
        // Use Uint8Array for proper UTF-8 BOM, ensuring Excel opens Arabic text correctly
        var csvFile = new Blob([new Uint8Array([0xEF, 0xBB, 0xBF]), csvContentString], {type: "text/csv;charset=utf-8;"});

        var downloadLink = document.createElement("a");
        downloadLink.download = "Support_Tickets_" + new Date().toISOString().slice(0,10) + ".csv";
        downloadLink.href = window.URL.createObjectURL(csvFile);

        downloadLink.style.display = "none";

        document.body.appendChild(downloadLink);

        downloadLink.click();

    }

    </script>

    <?php 
        return ob_get_clean();
    }

}
add_shortcode( 'ticketing_system_dashboard', 'display_ticket_dashboard' );
// 5. CREATE TICKET SHORTCODE (FIXED TRANSLATIONS)
// =================================================================
if ( !function_exists( 'display_create_ticket_form' ) ) {
    function display_create_ticket_form() {
        ts_try_sso_login();
        // Attempt SSO if WP user is logged in
        if ( !isset( $_SESSION['ts_auth_token'] ) ) {
            $lang = get_locale();
            $login_slug = ( strpos( $lang, 'ar' ) === 0 ? 'support-login-ar' : 'support-login' );
            $login_title = ( strpos( $lang, 'ar' ) === 0 ? 'Support Login AR' : 'Support Login' );
            $login_url = ts_get_page_url( $login_slug, $login_title );
            $admin_msg = ( current_user_can( 'manage_options' ) ? '<p style="color:#d6336c; font-size:12px; margin-top:15px;"><em>Admin Note: WordPress WP-Admin sessions are separate from the Ticketing System SaaS. To view this, log in via the customer form.</em></p>' : '' );
            return '<div style="text-align:center; padding:50px; background:#f9f9f9; border-radius:8px;"><h3>' . ts_t( 'Please Log In' ) . '</h3><a href="' . esc_url( $login_url ) . '" class="button button-primary">' . ts_t( 'Login Now' ) . '</a>' . $admin_msg . '</div>';
        }
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_GET['ticket_creation'] ) && sanitize_text_field( wp_unslash( $_GET['ticket_creation'] ) ) == 'success' ) {
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $tid = ( isset( $_GET['tid'] ) ? intval( sanitize_text_field( wp_unslash( $_GET['tid'] ) ) ) : 0 );
            $id_text = ( $tid > 0 ? ' #' . $tid : '' );
            $lang = get_locale();
            $dash_url = ( strpos( $lang, 'ar' ) === 0 ? ts_get_page_url( 'support-dashboard-ar', 'Support Dashboard AR' ) : ts_get_page_url( 'support-dashboard', 'Support Dashboard' ) );
            return '<div class="notice notice-success" style="padding:15px; background:#d4edda; color:#155724; border:1px solid #c3e6cb; border-radius:5px; margin-bottom:20px;"><strong>' . ts_t( 'Ticket Created' ) . $id_text . '!</strong> ' . ts_t( 'A confirmation email has been sent.' ) . ' <a href="' . esc_url( $dash_url ) . '" style="text-decoration:underline; font-weight:bold;">' . ts_t( 'View dashboard' ) . '</a>.</div>';
        }
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        $order_id = ( isset( $_GET['order_id'] ) ? intval( sanitize_text_field( wp_unslash( $_GET['order_id'] ) ) ) : 0 );
        // --- SMART UX: PREVENT DUPLICATE RMA TICKETS ---
        if ( $order_id ) {
            $api_key = get_option( 'ts_tenant_api_key' );
            $token = sanitize_text_field( wp_unslash( $_SESSION['ts_auth_token'] ) );
            $tickets_response = wp_remote_get( TS_API_BASE_URL . '/tickets', [
                'headers'     => [
                    'Authorization' => 'Bearer ' . $token,
                    'X-Api-Key'     => $api_key,
                ],
                'data_format' => 'body',
            ] );
            if ( !is_wp_error( $tickets_response ) && wp_remote_retrieve_response_code( $tickets_response ) == 200 ) {
                $tickets = json_decode( wp_remote_retrieve_body( $tickets_response ), true );
                if ( is_array( $tickets ) ) {
                    foreach ( $tickets as $t ) {
                        if ( isset( $t['referenceId'] ) && $t['referenceId'] == $order_id && strtolower( $t['status'] ) !== 'closed' ) {
                            $lang = get_locale();
                            $view_slug = ( strpos( $lang, 'ar' ) === 0 ? 'view-ticket-ar' : 'view-ticket' );
                            $view_title = ( strpos( $lang, 'ar' ) === 0 ? 'View Ticket AR' : 'View Ticket' );
                            $view_url = add_query_arg( 'ticket_id', $t['id'], ts_get_page_url( $view_slug, $view_title ) );
                            return '<div style="max-width:600px; margin:40px auto; text-align:center; padding:40px; background:#fff; border-radius:12px; box-shadow: 0 10px 25px rgba(0,0,0,0.05); border:1px solid #f0f0f1; font-family:-apple-system, BlinkMacSystemFont, sans-serif;">

                            <div style="font-size:40px; margin-bottom:15px;">📦</div>

                            <h3 style="margin-top:0; color:#333;">' . ts_t( 'Return Request Already Exists' ) . '</h3>

                            <p style="color:#666; margin-bottom:25px;">' . ts_t( 'You already have an active return request for this order.' ) . '</p>

                            <a href="' . esc_url( $view_url ) . '" style="background-color:' . esc_attr( get_option( 'ts_widget_color', '#0056b3' ) ) . '; color:white; padding:12px 24px; border-radius:6px; text-decoration:none; font-weight:600;">' . ts_t( 'View Ticket' ) . ' #' . $t['id'] . '</a>

                        </div>';
                        }
                    }
                }
            }
        }
        ob_start();
        ?>

    

    <?php 
        $subject_val = ( $order_id ? ts_t( 'Return Request for Order' ) . ' #' . $order_id : '' );
        ?>

    <style>

        .ts-form-container { max-width: 600px; margin: 40px auto; background: #ffffff; padding: 40px; border-radius: 12px; box-shadow: 0 10px 30px -5px rgba(0, 0, 0, 0.1); border: 1px solid #e2e8f0; font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; color: #0f172a; }

        .ts-form-header { text-align: center; margin-bottom: 30px; }

        .ts-form-header h2 { font-size: 24px; color: #333; margin: 0 0 10px 0; font-weight: 700; }

        .ts-form-header p { color: #666; font-size: 14px; margin: 0; }

        .ts-form-group { margin-bottom: 20px; }

        .ts-form-label { display: block; margin-bottom: 8px; font-weight: 600; color: #2c3e50; font-size: 14px; }

        .ts-form-input, .ts-form-select, .ts-form-textarea { width: 100%; padding: 12px 15px; border: 1px solid #dfe1e5; border-radius: 6px; font-size: 15px; color: #333; background-color: #fff; box-sizing: border-box; }

        .ts-form-input:focus, .ts-form-select:focus, .ts-form-textarea:focus { border-color: <?php 
        echo esc_attr( get_option( 'ts_widget_color', '#0056b3' ) );
        ?>; outline: none; box-shadow: 0 0 0 3px rgba(0, 86, 179, 0.1); }

        .ts-form-textarea { min-height: 120px; resize: vertical; font-family: inherit; }

        .ts-submit-btn { width: 100%; padding: 14px; background: linear-gradient(135deg, #0ea5e9, #2563eb); color: white; border: none; border-radius: 8px; font-size: 16px; font-weight: 600; cursor: pointer; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); box-shadow: 0 4px 12px rgba(37, 99, 235, 0.2), 0 2px 4px rgba(37, 99, 235, 0.1); letter-spacing: 0.3px; margin-top: 10px; }

        .ts-submit-btn:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(37, 99, 235, 0.3), 0 3px 6px rgba(37, 99, 235, 0.15); filter: brightness(1.05); }
        .ts-submit-btn:active { transform: translateY(0); box-shadow: 0 2px 4px rgba(37, 99, 235, 0.2); }



        /* CUSTOM FILE UPLOAD STYLES */

        .ts-file-wrapper { position: relative; overflow: hidden; display: inline-block; width: 100%; }

        .ts-file-input { position: absolute; left: 0; top: 0; opacity: 0; width: 100%; height: 100%; cursor: pointer; }

        .ts-file-custom { display: flex; align-items: center; justify-content: space-between; padding: 10px 15px; background: #f8f9fa; border: 1px dashed #dfe1e5; border-radius: 6px; color: #666; font-size: 14px; cursor: pointer; transition: all 0.2s; }

        .ts-file-custom:hover { background: #eef1f6; border-color: <?php 
        echo esc_attr( get_option( 'ts_widget_color', '#0056b3' ) );
        ?>; }

        .ts-file-btn { background: #e2e6ea; color: #333; padding: 5px 10px; border-radius: 4px; font-weight: 600; font-size: 12px; }



        /* 1. Fix the Select Dropdown (Size & Spacing) */

        body select.ts-form-select {

            -webkit-appearance: none !important;

            -moz-appearance: none !important;

            appearance: none !important;



            height: auto !important;

            min-height: 48px !important; /* Forces enough height so text doesn't cut off */

            padding: 10px 35px 10px 15px !important;

            

            line-height: 1.5 !important;

            background-color: #fff !important; 

            

            /* Add our own clean arrow (SVG) */

            background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23555' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e") !important;

            background-repeat: no-repeat !important;

            background-size: 16px !important;

            background-position: right 15px center !important;

        }

        

        /* ARABIC (RTL): Put arrow on the LEFT */

        body.rtl select.ts-form-select {

            background-position: left 15px center !important;

            padding: 10px 15px 10px 35px !important;

        }



    </style>



    <div class="ts-form-container">

        <div class="ts-form-header">

            <h2><?php 
        echo esc_html( ts_t( 'Create a New Ticket' ) );
        ?></h2>

            <p><?php 
        echo esc_html( ts_t( 'Please describe your issue in detail' ) );
        ?></p>

        </div>



        <form action="" method="post" enctype="multipart/form-data">

            <?php 
        wp_nonce_field( 'ts_create_ticket_action' );
        ?>

            <?php 
        if ( $order_id ) {
            ?>

                <input type="hidden" name="ts_reference_id" value="<?php 
            echo esc_attr( $order_id );
            ?>">

                <input type="hidden" name="ts_channel" value="RMA">

            <?php 
        } else {
            ?>

                <input type="hidden" name="ts_channel" value="Portal">

            <?php 
        }
        ?>

            

            <div class="ts-form-group">

                <label class="ts-form-label" for="ts_title"><?php 
        echo esc_html( ts_t( 'Subject' ) );
        ?></label>

                <input type="text" id="ts_title" name="ts_title" class="ts-form-input" placeholder="<?php 
        echo esc_html( ts_t( 'e.g., Cannot access my account' ) );
        ?>" value="<?php 
        echo esc_attr( $subject_val );
        ?>" maxlength="200" required oninvalid="this.setCustomValidity('<?php 
        echo esc_js( ts_t( 'Please fill out this field.' ) );
        ?>')" oninput="this.setCustomValidity('')">

            </div>

            

            <div style="display:flex; gap: 20px;">

                <div class="ts-form-group" style="flex:1;">

                    <label class="ts-form-label" for="ts_category"><?php 
        echo esc_html( ts_t( 'Category' ) );
        ?></label>

                    <select id="ts_category" name="ts_category" class="ts-form-select">

                        <?php 
        // Fetch Categories dynamically
        $api_key = get_option( 'ts_tenant_api_key' );
        $token = ( isset( $_SESSION['ts_auth_token'] ) ? sanitize_text_field( wp_unslash( $_SESSION['ts_auth_token'] ) ) : '' );
        $cat_response = wp_remote_get( TS_API_BASE_URL . '/categories', [
            'headers'     => [
                'Authorization' => 'Bearer ' . $token,
                'X-Api-Key'     => $api_key,
            ],
            'data_format' => 'body',
        ] );
        $categories = ( !is_wp_error( $cat_response ) && wp_remote_retrieve_response_code( $cat_response ) == 200 ? json_decode( wp_remote_retrieve_body( $cat_response ), true ) : [] );
        $archived_cats = get_option( 'ts_archived_categories', [] );
        if ( empty( $categories ) ) {
            echo '<option value="General">General</option>';
            if ( $order_id ) {
                echo '<option value="RMA / Return" selected>RMA / Return</option>';
            }
        } else {
            $has_rma = false;
            foreach ( $categories as $cat ) {
                if ( isset( $cat['name'] ) && $cat['name'] == 'RMA / Return' ) {
                    $has_rma = true;
                }
            }
            if ( !$has_rma && $order_id ) {
                $categories[] = [
                    'name' => 'RMA / Return',
                ];
            }
            foreach ( $categories as $cat ) {
                if ( isset( $cat['id'] ) && in_array( $cat['id'], $archived_cats ) ) {
                    continue;
                }
                $selected = ( $order_id && isset( $cat['name'] ) && $cat['name'] == 'RMA / Return' ? 'selected' : '' );
                echo '<option value="' . esc_attr( $cat['name'] ) . '" ' . esc_attr( $selected ) . '>' . esc_html( ts_t( $cat['name'] ) ) . '</option>';
            }
        }
        ?>

                    </select>

                </div>



                <div class="ts-form-group" style="flex:1;">

                    <label class="ts-form-label" for="ts_priority"><?php 
        echo esc_html( ts_t( 'Priority' ) );
        ?></label>

                    <select id="ts_priority" name="ts_priority" class="ts-form-select">

                        <option value="Low"><?php 
        echo esc_html( ts_t( 'Low' ) );
        ?></option>

                        <option value="Medium" selected><?php 
        echo esc_html( ts_t( 'Medium' ) );
        ?></option>

                        <option value="High"><?php 
        echo esc_html( ts_t( 'High' ) );
        ?></option>

                    </select>

                </div>

            </div>

            

            <div class="ts-form-group">

                <label class="ts-form-label" for="ts_description"><?php 
        echo esc_html( ts_t( 'Description' ) );
        ?></label>

                <textarea id="ts_description" name="ts_description" class="ts-form-textarea" placeholder="<?php 
        echo esc_html( ts_t( 'Type your message here...' ) );
        ?>" maxlength="10000" required></textarea>

            </div>

            

            <div class="ts-form-group">

                <label class="ts-form-label"><?php 
        echo esc_html( ts_t( 'Attachment (Optional)' ) );
        ?></label>

                

                <div class="ts-file-wrapper">

                    <input type="file" id="ts_attachment" name="ts_attachment" class="ts-file-input" accept=".jpg,.jpeg,.png,.pdf,.doc,.docx,.xls,.xlsx,.zip,.txt" onchange="document.getElementById('file-name').textContent = this.files[0].name; tsValidateFile(this);">

                    <div class="ts-file-custom">

                        <span id="file-name"><?php 
        echo esc_html( ts_t( 'No file selected' ) );
        ?></span>

                        <span class="ts-file-btn"><?php 
        echo esc_html( ts_t( 'Select File' ) );
        ?></span>

                    </div>

                </div>

                <div style="margin-top:5px; font-size:12px; color:#888;"><?php 
        echo esc_html( ts_t( 'Max 5MB' ) );
        ?></div>

            </div>

            

            <button type="submit" name="submit_ticket" class="ts-submit-btn">

                <?php 
        echo esc_html( ts_t( 'Create Ticket' ) );
        ?>

            </button>

            <?php 
        echo wp_kses_post( ts_render_footer() );
        ?>

        </form>

    </div>
    
    <script>
    document.addEventListener("DOMContentLoaded", function() {
        var titleInput = document.getElementById("ts_title");
        var descInput = document.getElementById("ts_description");
        
        var titleMsg = "<?php 
        echo esc_html( addslashes( ts_t( 'Please enter a subject for your ticket.' ) ) );
        ?>";
        var descMsg = "<?php 
        echo esc_html( addslashes( ts_t( 'Please enter a description for your ticket.' ) ) );
        ?>";
        
        if (titleInput) {
            titleInput.addEventListener("invalid", function(e) {
                if (this.value.trim() === "") {
                    this.setCustomValidity(titleMsg);
                }
            });
            titleInput.addEventListener("input", function(e) {
                this.setCustomValidity("");
            });
        }
        
        if (descInput) {
            descInput.addEventListener("invalid", function(e) {
                if (this.value.trim() === "") {
                    this.setCustomValidity(descMsg);
                }
            });
            descInput.addEventListener("input", function(e) {
                this.setCustomValidity("");
            });
        }
    });
    </script>

    <?php 
        return ob_get_clean();
    }

}
add_shortcode( 'ticketing_system_create', 'display_create_ticket_form' );
if ( !function_exists( 'handle_create_ticket_submission' ) ) {
    function handle_create_ticket_submission() {
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_POST['submit_ticket'] ) && isset( $_SESSION['ts_auth_token'] ) ) {
            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.Security.EscapeOutput.UnsafePrintingFunction, WordPress.Security.NonceVerification
            if ( !isset( $_POST['_wpnonce'] ) || !wp_verify_nonce( sanitize_text_field( wp_unslash( ( isset( $_POST['_wpnonce'] ) ? $_POST['_wpnonce'] : '' ) ) ), 'ts_create_ticket_action' ) ) {
                wp_die( 'Security check failed.' );
            }
            $api_key = get_option( 'ts_tenant_api_key' );
            $token = sanitize_text_field( wp_unslash( $_SESSION['ts_auth_token'] ) );
            $api_url = TS_API_BASE_URL . '/tickets';
            // Fetch Categories for Dropdown
            $cat_response = wp_remote_get( TS_API_BASE_URL . '/categories', [
                'headers'     => [
                    'Authorization' => 'Bearer ' . $token,
                    'X-Api-Key'     => $api_key,
                ],
                'data_format' => 'body',
            ] );
            $categories = ( !is_wp_error( $cat_response ) && wp_remote_retrieve_response_code( $cat_response ) == 200 ? json_decode( wp_remote_retrieve_body( $cat_response ), true ) : [] );
            // Fallback if no categories exist
            if ( empty( $categories ) ) {
                $categories = [
                    [
                        'name' => 'General',
                    ],
                    [
                        'name' => 'Technical',
                    ],
                    [
                        'name' => 'Billing',
                    ],
                    [
                        'name' => 'Sales',
                    ]
                ];
            }
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $title = ( isset( $_POST['ts_title'] ) ? sanitize_text_field( wp_unslash( $_POST['ts_title'] ) ) : '' );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $description = ( isset( $_POST['ts_description'] ) ? sanitize_textarea_field( wp_unslash( $_POST['ts_description'] ) ) : '' );
            if ( empty( trim( $title ) ) ) {
                wp_die( esc_html( ts_t( 'Please enter a subject for your ticket.' ) ) );
            }
            if ( empty( trim( $description ) ) ) {
                wp_die( esc_html( ts_t( 'Please enter a description for your ticket.' ) ) );
            }
            $fields = [
                'Title'       => $title,
                'Description' => $description,
                'Priority'    => sanitize_text_field( wp_unslash( ( isset( $_POST['ts_priority'] ) ? $_POST['ts_priority'] : '' ) ) ),
                'Category'    => sanitize_text_field( wp_unslash( ( isset( $_POST['ts_category'] ) ? $_POST['ts_category'] : '' ) ) ),
                'Channel'     => ( isset( $_POST['ts_channel'] ) ? sanitize_text_field( wp_unslash( $_POST['ts_channel'] ) ) : 'System' ),
                'language'    => ts_get_api_language(),
            ];
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            if ( isset( $_POST['ts_reference_id'] ) ) {
                // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
                $fields['ReferenceId'] = sanitize_text_field( wp_unslash( $_POST['ts_reference_id'] ) );
            }
            // Use our helper to send the file + fields
            $result = ts_send_api_request_with_file(
                $api_url,
                $fields,
                'ts_attachment',
                $token,
                $api_key
            );
            if ( $result['code'] == 201 ) {
                $resp_data = json_decode( $result['body'], true );
                $new_id = ( isset( $resp_data['id'] ) ? $resp_data['id'] : 0 );
                wp_safe_redirect( add_query_arg( [
                    'ticket_creation' => 'success',
                    'tid'             => $new_id,
                ], remove_query_arg( 'ticket_creation' ) ) );
                exit;
            } elseif ( $result['code'] == 401 || $result['code'] == 403 ) {
                unset($_SESSION['ts_auth_token']);
                setcookie(
                    'wordpress_logged_in_ts_auth_token',
                    '',
                    time() - 3600,
                    COOKIEPATH,
                    COOKIE_DOMAIN
                );
                /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
                wp_die( '<script>window.location.reload();</script>' );
            } else {
                $resp_data = json_decode( $result['body'], true );
                if ( is_array( $resp_data ) && isset( $resp_data['message'] ) ) {
                    wp_die( esc_html( $resp_data['message'] ) );
                }
                wp_die( esc_html( 'Error creating ticket (Code: ' . $result['code'] . '). Response: ' . $result['body'] ) );
            }
        }
    }

}
add_action( 'init', 'handle_create_ticket_submission' );
// 6. VIEW SINGLE TICKET (FINAL TRANSLATION FIXES)
// =================================================================
if ( !function_exists( 'display_single_ticket_view' ) ) {
    function display_single_ticket_view(  $atts  ) {
        ts_try_sso_login();
        // Attempt SSO if WP user is logged in (but skips if session is already set by magic token)
        // --- SMART UX: Require Login & Remember Current Page ---
        if ( !isset( $_SESSION['ts_auth_token'] ) ) {
            $current_uri = ( isset( $_SERVER['REQUEST_URI'] ) ? urlencode( sanitize_text_field( wp_unslash( ( isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '' ) ) ) ) : '' );
            $lang = get_locale();
            $login_url = ( strpos( $lang, 'ar' ) === 0 ? ts_get_page_url( 'support-login-ar', 'Support Login AR' ) : ts_get_page_url( 'support-login', 'Support Login' ) );
            $login_url = add_query_arg( 'redirect_to', $current_uri, $login_url );
            $admin_msg = ( current_user_can( 'manage_options' ) ? '<p style="color:#d6336c; font-size:12px; margin-top:15px;"><em>Admin Note: WordPress WP-Admin sessions are separate from the Ticketing System SaaS. To view this, log in via the customer form.</em></p>' : '' );
            return '<div style="text-align:center; padding:50px; background:#f9f9f9; border-radius:8px;"><h3>' . ts_t( 'Please Log In' ) . '</h3><p>' . ts_t( 'You need to log in to view your tickets.' ) . '</p><a href="' . esc_url( $login_url ) . '" class="button button-primary">' . ts_t( 'Login Now' ) . '</a>' . $admin_msg . '</div>';
        }
        // ... (Keep existing fetch logic at the top) ...
        // 1. GET TICKET
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        $ticket_id = ( isset( $_GET['ticket_id'] ) ? intval( sanitize_text_field( wp_unslash( $_GET['ticket_id'] ) ) ) : 0 );
        if ( $ticket_id === 0 ) {
            return '<div class="wrap"><div class="notice notice-error"><p>' . ts_t( 'Invalid Ticket ID' ) . '</p></div></div>';
        }
        $ticket = ts_get_ticket_from_api( $ticket_id );
        if ( isset( $ticket['error'] ) ) {
            return '<div class="wrap"><div class="notice notice-error"><p>' . ts_t( 'Error loading ticket: ' ) . esc_html( $ticket['error'] ) . '</p></div></div>';
        }
        if ( !$ticket ) {
            return '<div class="wrap"><div class="notice notice-error"><p>' . ts_t( 'Error loading ticket.' ) . '</p></div></div>';
        }
        $cust_data = ( isset( $ticket['customer'] ) ? $ticket['customer'] : [] );
        $raw_name = ( isset( $cust_data['name'] ) ? $cust_data['name'] : (( isset( $ticket['customerName'] ) ? $ticket['customerName'] : '' )) );
        $raw_email = ( isset( $cust_data['email'] ) ? $cust_data['email'] : (( isset( $ticket['customerEmail'] ) ? $ticket['customerEmail'] : (( isset( $ticket['guestEmail'] ) ? $ticket['guestEmail'] : '' )) )) );
        $raw_phone = ( isset( $cust_data['phoneNumber'] ) ? $cust_data['phoneNumber'] : (( isset( $ticket['guestPhoneNumber'] ) ? $ticket['guestPhoneNumber'] : '' )) );
        $display_name = ( !empty( $raw_name ) ? $raw_name : (( !empty( $raw_email ) ? $raw_email : 'Unknown' )) );
        $agent_data = ( isset( $ticket['agent'] ) ? $ticket['agent'] : [] );
        $agent_name = ( isset( $agent_data['name'] ) ? $agent_data['name'] : (( isset( $ticket['agentName'] ) ? $ticket['agentName'] : ts_t( 'Unassigned' ) )) );
        $comments = ( isset( $ticket['comments'] ) ? $ticket['comments'] : [] );
        $user_role = ts_get_user_role();
        $agents = [];
        $canned_responses = [];
        $is_pro = defined( 'TS_IS_PRO' ) && TS_IS_PRO;
        $token = sanitize_text_field( wp_unslash( $_SESSION['ts_auth_token'] ) );
        if ( $user_role === 'Agent' || $user_role === 'Admin' ) {
            $api_key = get_option( 'ts_tenant_api_key' );
            $agents = ts_get_agents_from_api( $token, $api_key );
            if ( $is_pro ) {
                $canned_responses = ts_get_canned_responses_from_api( $token, $api_key );
            }
        }
        // Fetch Sub-Statuses
        $sub_response = wp_remote_get( TS_API_BASE_URL . '/ticketsubstatuses', [
            'headers'     => [
                'Authorization' => 'Bearer ' . $token,
                'X-Api-Key'     => get_option( 'ts_tenant_api_key' ),
            ],
            'data_format' => 'body',
        ] );
        $sub_statuses = ( !is_wp_error( $sub_response ) && wp_remote_retrieve_response_code( $sub_response ) == 200 ? json_decode( wp_remote_retrieve_body( $sub_response ), true ) : [] );
        // Fetch Categories for Color Mapping
        $cat_response = wp_remote_get( TS_API_BASE_URL . '/categories', [
            'headers'     => [
                'Authorization' => 'Bearer ' . $token,
                'X-Api-Key'     => get_option( 'ts_tenant_api_key' ),
            ],
            'data_format' => 'body',
        ] );
        $all_cats = ( !is_wp_error( $cat_response ) && wp_remote_retrieve_response_code( $cat_response ) == 200 ? json_decode( wp_remote_retrieve_body( $cat_response ), true ) : [] );
        $ticket_cat_color = '#0085ba';
        foreach ( $all_cats as $c ) {
            if ( isset( $c['name'] ) && $c['name'] === $ticket['category'] && !empty( $c['color'] ) ) {
                $ticket_cat_color = $c['color'];
                break;
            }
        }
        ob_start();
        ?>

    <style>

        .ts-ticket-view-wrapper * { box-sizing: border-box; }

        .ts-ticket-container { display: flex; gap: 20px; width: 100%; margin: 20px 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; align-items: flex-start; }

        .ts-main-column { flex: 1; min-width: 0; }

        .ts-sidebar-column { flex: 0 0 240px; width: 240px; display: flex; flex-direction: column; gap: 15px; }

        @media (max-width: 768px) { .ts-ticket-container { flex-direction: column; } .ts-sidebar-column { width: 100%; flex: auto; } }



        .ts-card { background: #fff; border: 1px solid #dcdcde; border-radius: 8px; box-shadow: 0 6px 16px rgba(0,0,0,0.08); padding: 20px; margin-bottom: 20px; }

        .ts-ticket-header { margin-bottom: 20px; }

        .ts-ticket-title { font-size: 26px; font-weight: 700; color: #1d2327; margin: 0 0 10px 0; line-height: 1.2; }

        

        .ts-meta-badges { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

        .ts-badge { display: inline-block; padding: 3px 8px; border-radius: 4px; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; }

        .badge-open { background: #d1fae5; color: #065f46; border: 1px solid #a7f3d0; } 

        .badge-closed { background: #f3f4f6; color: #374151; border: 1px solid #e5e7eb; } 

        .badge-progress { background: #dbeafe; color: #1e40af; border: 1px solid #bfdbfe; } 

        .badge-pending { background: #fef08a; color: #92400e; border: 1px solid #fde047; } 

        .badge-default { background: #e5e5e5; color: #555; }

        .badge-agent { background: #e0e7ff; color: #3730a3; border: 1px solid #c7d2fe; }



        /* Conversation Styles */

        .ts-conversation-thread { display: flex; flex-direction: column; gap: 15px; max-height: 700px; overflow-y: auto; padding-right: 5px; }

        .ts-message { width: 100%; padding: 20px 25px; border: 1px solid #f0f0f1; border-radius: 6px; background: #fff; margin: 0 !important; }

        .ts-message.internal-note { background-color: #fff9db !important; border-color: #ffec99 !important; }

        .ts-message-header { display: flex; justify-content: space-between; margin-bottom: 12px; font-size: 13px; color: #646970; }

        .ts-message-author { font-weight: 700; color: #2c3338; font-size: 14px; }

        .ts-message-body { font-size: 15px; line-height: 1.7; color: #3c434a; white-space: pre-wrap; }

        .ts-read-more-link { display: inline-block; margin-top: 5px; font-size: 12px; font-weight: 600; color: <?php 
        echo esc_attr( get_option( 'ts_widget_color', '#0056b3' ) );
        ?>; cursor: pointer; text-decoration: none; }



        /* Reply Box */

        .ts-reply-box { border: 1px solid #dcdcde; border-radius: 8px; overflow: hidden; background: #fff; box-shadow: 0 6px 16px rgba(0,0,0,0.08); margin-top: 20px; }

        .ts-reply-header { background: #f8f9fa; padding: 10px 20px; border-bottom: 1px solid #eee; font-weight: 600; color: #444; font-size: 13px; display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 10px; }

        .ts-reply-textarea { width: 100%; border: none !important; padding: 25px; font-size: 15px; min-height: 120px; resize: vertical; outline: none !important; transition: background 0.3s; }

        .ts-reply-textarea.internal-active { background-color: #fffde7; }

        

        .ts-reply-footer { background: #f8f9fa; padding: 15px 25px; border-top: 1px solid #eee; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px; }

        .ts-btn-send { background: linear-gradient(135deg, #0ea5e9, #2563eb) !important; color: #fff !important; border: none !important; border-radius: 6px !important; padding: 8px 20px; font-size: 14px; font-weight: 600 !important; cursor: pointer !important; white-space: nowrap; flex-shrink: 0; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important; box-shadow: 0 4px 12px rgba(37, 99, 235, 0.2), 0 2px 4px rgba(37, 99, 235, 0.1) !important; letter-spacing: 0.3px; }
        .ts-btn-send:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(37, 99, 235, 0.3), 0 3px 6px rgba(37, 99, 235, 0.15) !important; filter: brightness(1.05); }
        .ts-btn-send:active { transform: translateY(0); box-shadow: 0 2px 4px rgba(37, 99, 235, 0.2) !important; }

        .ts-internal-toggle { display: flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 600; color: #d6336c; cursor: pointer; white-space: nowrap; flex-shrink: 0; }

        .ts-canned-select { padding: 4px 24px; border: 1px solid #ddd; border-radius: 4px; font-size: 12px; max-width: 250px; }



        /* Custom File Upload */

        .ts-file-wrapper { position: relative; overflow: hidden; display: inline-block; margin-left: 15px; }

        .ts-file-input { position: absolute; left: 0; top: 0; opacity: 0; width: 100%; height: 100%; cursor: pointer; }

        .ts-file-custom { display: flex; align-items: center; gap: 8px; font-size: 12px; color: #666; cursor: pointer; }

        .ts-file-btn { background: #e2e6ea; padding: 4px 8px; border-radius: 4px; font-weight: 600; transition: background 0.2s; white-space: nowrap; flex-shrink: 0; }

        .ts-file-btn:hover { background: #dbe0e5; }



        /* Sidebar */

        .ts-sidebar-label { display: block; font-size: 11px; font-weight: 600; color: #646970; margin-bottom: 4px; text-transform: uppercase; letter-spacing: 0.5px; }

        /* UPDATED: Sidebar Select with Custom Arrow */

        body select.ts-sidebar-select {

            width: 100% !important;

            margin-bottom: 12px !important;

            background-color: #fff !important;

            border: 1px solid #dcdcde !important;

            border-radius: 4px !important;

            font-size: 13px !important;

            color: #333 !important;

            height: auto !important;

            min-height: 40px !important; 

            cursor: pointer !important;

            box-sizing: border-box !important;

            line-height: 1.5 !important;

            

            /* 1. Remove default ugly browser arrow */

            -webkit-appearance: none !important;

            -moz-appearance: none !important;

            appearance: none !important;



            /* 2. Add our own clean arrow (SVG) */

            background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23555' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e") !important;

            background-repeat: no-repeat !important;

            background-size: 16px !important;

        }



        /* 3. ARABIC (RTL): Put arrow on the LEFT */

        body.rtl select.ts-sidebar-select {

            background-position: left 10px center !important;

            padding: 8px 12px 8px 35px !important; /* Extra padding on left so text doesn't hit arrow */

        }



        /* 4. ENGLISH (LTR): Put arrow on the RIGHT */

        body:not(.rtl) select.ts-sidebar-select {

            background-position: right 10px center !important;

            padding: 8px 35px 8px 12px !important; /* Extra padding on right */

        }

        .ts-sidebar-btn { width: 100%; padding: 6px 10px; font-size: 13px; font-weight: 600; background: #f0f0f1; border: 1px solid #dcdcde; color: #2c3338; border-radius: 4px; cursor: pointer; transition: all 0.2s; }

        .ts-sidebar-btn:hover { background: #fff; border-color: <?php 
        echo esc_attr( get_option( 'ts_widget_color', '#0056b3' ) );
        ?>; color: <?php 
        echo esc_attr( get_option( 'ts_widget_color', '#0056b3' ) );
        ?>; }

    </style>



    <div class="wrap ts-ticket-view-wrapper">

        <?php 
        /* phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash */
        if ( isset( $_GET['manage'] ) && sanitize_text_field( wp_unslash( $_GET['manage'] ) ) == 'success' ) {
            ?>

            <div style="padding:15px; background:#d4edda; color:#155724; border:1px solid #c3e6cb; border-radius:5px; margin-bottom:20px;">

                <strong><?php 
            echo esc_html( ts_t( 'Success' ) );
            ?>!</strong> <?php 
            echo esc_html( ts_t( 'Ticket updated successfully.' ) );
            ?>

            </div>

        <?php 
            /* phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash */
        } elseif ( isset( $_GET['manage'] ) && sanitize_text_field( wp_unslash( $_GET['manage'] ) ) == 'failed' ) {
            ?>

            <div style="padding:15px; background:#f8d7da; color:#721c24; border:1px solid #f5c6cb; border-radius:5px; margin-bottom:20px;">

                             <strong><?php 
            echo esc_html( ts_t( 'Error' ) );
            ?>!</strong> <?php 
            echo esc_html( ts_t( 'Failed to update ticket.' ) );
            ?>

            </div>

        <?php 
        }
        ?>

        <div class="ts-ticket-header">

            <h1 class="ts-ticket-title">#<?php 
        echo esc_html( $ticket['id'] );
        ?> - <?php 
        echo esc_html( $ticket['title'] );
        ?></h1>

            <div class="ts-meta-badges">

                <?php 
        $status_class = 'badge-default';
        if ( strtolower( $ticket['status'] ) === 'open' ) {
            $status_class = 'badge-open';
        }
        if ( strtolower( $ticket['status'] ) === 'closed' ) {
            $status_class = 'badge-closed';
        }
        if ( strtolower( $ticket['status'] ) === 'in progress' ) {
            $status_class = 'badge-progress';
        }
        if ( strtolower( $ticket['status'] ) === 'pending' ) {
            $status_class = 'badge-pending';
        }
        ?>

                <span class="ts-badge <?php 
        echo esc_attr( $status_class );
        ?>"><?php 
        echo esc_html( ts_t( $ticket['status'] ) );
        ?></span>

                <?php 
        if ( !empty( $ticket['subStatus'] ) && is_array( $ticket['subStatus'] ) ) {
            ?>

                    <span class="ts-badge" style="background-color:<?php 
            echo esc_attr( $ticket['subStatus']['color'] );
            ?>; color:#fff; border-color:<?php 
            echo esc_attr( $ticket['subStatus']['color'] );
            ?>;"><?php 
            echo esc_html( ts_t( $ticket['subStatus']['name'] ) );
            ?></span>

                <?php 
        }
        ?>

                <span class="ts-badge" style="background:<?php 
        echo esc_attr( $ticket_cat_color );
        ?>15; color:<?php 
        echo esc_attr( $ticket_cat_color );
        ?>; border: 1px solid <?php 
        echo esc_attr( $ticket_cat_color );
        ?>33;"><?php 
        echo esc_html( ts_t( $ticket['category'] ) );
        ?></span>

                <span class="ts-badge" style="background:#fff8e5; color:#996800;"><?php 
        echo esc_html( ts_t( $ticket['priority'] ) );
        ?></span>

                

                <span class="ts-badge badge-default"><?php 
        echo esc_html( $display_name );
        ?></span>

                

                <?php 
        $single_created_raw = ( isset( $ticket['createdDate'] ) ? $ticket['createdDate'] : '' );
        if ( !empty( $single_created_raw ) && !(substr( $single_created_raw, -1 ) === 'Z') ) {
            $single_created_raw .= 'Z';
        }
        $single_closed_raw = ( isset( $ticket['closedDate'] ) ? $ticket['closedDate'] : '' );
        if ( !empty( $single_closed_raw ) && !(substr( $single_closed_raw, -1 ) === 'Z') ) {
            $single_closed_raw .= 'Z';
        }
        ?>

                <span class="ts-badge badge-default" style="font-family: monospace; background:#f1f5f9; color:#475569; border-color:#cbd5e1;">

                    <span class="dashicons dashicons-clock" style="font-size:12px;width:12px;height:12px;line-height:1;margin-top:2px;margin-right:2px;"></span>

                    <?php 
        echo esc_html( ts_t( 'Opened: ' ) );
        ?><span class="ts-single-time" data-utc="<?php 
        echo esc_attr( $single_created_raw );
        ?>"></span>

                </span>

                

                <?php 
        if ( strtolower( $ticket['status'] ) === 'closed' && !empty( $single_closed_raw ) ) {
            ?>

                    <span class="ts-badge" style="font-family: monospace; background:#dcfce7; color:#166534; border-color:#bbf7d0;">

                        <span class="dashicons dashicons-yes-alt" style="font-size:12px;width:12px;height:12px;line-height:1;margin-top:2px;margin-right:2px;"></span>

                        <?php 
            echo esc_html( ts_t( 'Closed: ' ) );
            ?><span class="ts-single-time" data-utc="<?php 
            echo esc_attr( $single_closed_raw );
            ?>"></span>

                    </span>

                <?php 
        }
        ?>

                

                <span class="ts-badge badge-agent"><?php 
        echo esc_html( ts_t( 'Agent' ) . ': ' . esc_html( $agent_name ) );
        ?></span>



                <?php 
        if ( !empty( $ticket['referenceId'] ) ) {
            ?>

                    <span class="ts-badge" style="background:#f3e8ff; color:#701a75; border: 1px solid #e9d5ff;"><span class="dashicons dashicons-cart" style="font-size:12px;width:12px;height:12px;line-height:1;margin-top:1px;"></span> <?php 
            echo esc_html( ts_t( 'Order' ) . ' #' . esc_html( $ticket['referenceId'] ) );
            ?></span>

                <?php 
        }
        ?>

            </div>

        </div>



        <div class="ts-ticket-container">

            <div class="ts-main-column">

                <div class="ts-card">

                    <h3 style="margin-top:0; border-bottom:1px solid #eee; padding-bottom:15px; margin-bottom:0; font-size: 16px;"><?php 
        echo esc_html( ts_t( 'Conversation' ) );
        ?></h3>

                    <div class="ts-conversation-thread" style="padding-top: 15px;">

                        <?php 
        $t_desc = ( isset( $ticket['description'] ) ? $ticket['description'] : (( isset( $ticket['Description'] ) ? $ticket['Description'] : '' )) );
        if ( !empty( $t_desc ) ) {
            $t_date_raw = ( isset( $ticket['createdDate'] ) ? $ticket['createdDate'] : '' );
            try {
                $t_date_obj = new DateTime($t_date_raw, new DateTimeZone('UTC'));
                $t_english_date = wp_date( 'Y-m-d g:i A', $t_date_obj->getTimestamp() );
                $t_formatted_date = ts_format_date_localized( $t_english_date );
            } catch ( Exception $e ) {
                $t_formatted_date = $t_date_raw;
            }
            $t_attach_raw = ( isset( $ticket['attachmentUrl'] ) ? $ticket['attachmentUrl'] : (( isset( $ticket['AttachmentUrl'] ) ? $ticket['AttachmentUrl'] : '' )) );
            $t_attachments = [];
            if ( !empty( $t_attach_raw ) ) {
                foreach ( explode( ',', $t_attach_raw ) as $part ) {
                    $part = trim( $part );
                    if ( !empty( $part ) ) {
                        if ( strpos( $part, 'http' ) === false ) {
                            $part = preg_replace( '#/api(/v1)?$#i', '', rtrim( TS_API_BASE_URL, '/' ) ) . $part;
                        }
                        $t_attachments[] = $part;
                    }
                }
            }
            ?>

                            <div class="ts-message" style="background: #fff; border-color: #f0f0f1;">

                                <div class="ts-message-header">

                                    <span class="ts-message-author"><?php 
            echo esc_html( $display_name );
            ?></span>

                                    <span><?php 
            echo esc_html( $t_formatted_date );
            ?></span>

                                </div>

                                <div class="ts-message-body"><?php 
            echo nl2br( esc_html( $t_desc ) );
            ?></div>

                                <?php 
            if ( !empty( $t_attachments ) ) {
                ?>

                                    <div style="margin-top:10px; font-size:12px;">

                                        <?php 
                foreach ( $t_attachments as $i => $url ) {
                    ?>

                                            📎 <a href="<?php 
                    echo esc_url( $url );
                    ?>" target="_blank" style="margin-right:15px;"><?php 
                    echo esc_html( ts_t( 'View Attachment' ) );
                    ?> <?php 
                    /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
                    echo ( count( $t_attachments ) > 1 ? $i + 1 : '' );
                    ?></a>

                                        <?php 
                }
                ?>

                                    </div>

                                <?php 
            }
            ?>

                            </div>
                                <?php 
        }
        ?>

                        <?php 
        if ( !empty( $comments ) ) {
            foreach ( $comments as $index => $msg ) {
                // ... (Same Message Display Logic as previous step) ...
                $msg_content = ( isset( $msg['content'] ) ? $msg['content'] : (( isset( $msg['message'] ) ? $msg['message'] : '' )) );
                $msg_date_raw = ( isset( $msg['createdDate'] ) ? $msg['createdDate'] : (( isset( $msg['created_at'] ) ? $msg['created_at'] : '' )) );
                try {
                    $date_obj = new DateTime($msg_date_raw, new DateTimeZone('UTC'));
                    $english_date = wp_date( 'Y-m-d g:i A', $date_obj->getTimestamp() );
                    $formatted_date = ts_format_date_localized( $english_date );
                } catch ( Exception $e ) {
                    $formatted_date = $msg_date_raw;
                }
                $msg_attach_raw = ( isset( $msg['attachmentUrl'] ) ? $msg['attachmentUrl'] : '' );
                $msg_attachments = [];
                if ( !empty( $msg_attach_raw ) ) {
                    foreach ( explode( ',', $msg_attach_raw ) as $part ) {
                        $part = trim( $part );
                        if ( !empty( $part ) ) {
                            if ( strpos( $part, 'http' ) === false ) {
                                $part = preg_replace( '#/api(/v1)?$#i', '', rtrim( TS_API_BASE_URL, '/' ) ) . $part;
                            }
                            $msg_attachments[] = $part;
                        }
                    }
                }
                $sender_name = ( isset( $msg['user']['name'] ) ? $msg['user']['name'] : (( isset( $msg['senderName'] ) ? $msg['senderName'] : 'User' )) );
                $is_staff = isset( $msg['user']['role'] ) && in_array( $msg['user']['role'], ['Admin', 'Agent'] ) || strpos( strtolower( $sender_name ), 'admin' ) !== false;
                $is_internal = isset( $msg['isInternal'] ) && $msg['isInternal'] == true;
                if ( $is_internal && $user_role === 'Customer' ) {
                    continue;
                }
                $internal_class = ( $is_internal ? 'internal-note' : '' );
                ?>

                            <div class="ts-message <?php 
                echo esc_html( $internal_class );
                ?>" style="background: <?php 
                echo esc_html( ( $is_staff ? '#f8fbff' : '#fff' ) );
                ?>; border-color: <?php 
                echo esc_html( ( $is_staff ? '#cce5ff' : '#f0f0f1' ) );
                ?>;">

                                <div class="ts-message-header">

                                    <span class="ts-message-author">

                                        <?php 
                echo esc_html( $sender_name );
                ?> 

                                        <?php 
                /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.Security.EscapeOutput.UnsafePrintingFunction */
                if ( $is_staff ) {
                    echo '<span style="font-size:10px; background:#0073aa; color:white; padding:2px 6px; border-radius:4px; margin-left:5px;">STAFF</span>';
                }
                ?>

                                        <?php 
                /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.Security.EscapeOutput.UnsafePrintingFunction */
                if ( $is_internal ) {
                    echo '<span style="font-size:10px; background:#fab005; color:white; padding:2px 6px; border-radius:4px; margin-left:5px;">INTERNAL</span>';
                }
                ?>

                                    </span>

                                    <span><?php 
                echo esc_html( $formatted_date );
                ?></span>

                                </div>

                                <div class="ts-message-body"><?php 
                echo nl2br( esc_html( $msg_content ) );
                ?></div>

                                <?php 
                if ( !empty( $msg_attachments ) ) {
                    ?>

                                    <div style="margin-top:10px; font-size:12px;">

                                        <?php 
                    foreach ( $msg_attachments as $i => $url ) {
                        ?>

                                            📎 <a href="<?php 
                        echo esc_url( $url );
                        ?>" target="_blank" style="margin-right:15px;"><?php 
                        echo esc_html( ts_t( 'View Attachment' ) );
                        ?> <?php 
                        /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
                        echo ( count( $msg_attachments ) > 1 ? $i + 1 : '' );
                        ?></a>

                                        <?php 
                    }
                    ?>

                                    </div>

                                <?php 
                }
                ?>

                            </div>

                        <?php 
            }
        } else {
            ?>

                            <div style="text-align: center; padding: 40px; color: #888;"><?php 
            echo esc_html( ts_t( 'No comments yet.' ) );
            ?></div>

                        <?php 
        }
        ?>

                    </div>

                </div>



                <div class="ts-reply-box">

                    <form action="" method="post" enctype="multipart/form-data" style="margin:0;" onsubmit="tsShowLoading(this)">

                        <div class="ts-reply-header">

                            <span><?php 
        echo esc_html( ts_t( 'Post a Reply' ) );
        ?></span>

                            <div style="display:flex; align-items:center; gap:15px; flex-wrap:wrap; justify-content:flex-end;">

                                <?php 
        if ( ($user_role === 'Agent' || $user_role === 'Admin') && $is_pro ) {
            ?>

                                    <select onchange="tsInsertCanned(this)" class="ts-canned-select">

                                        <option value="">-- <?php 
            echo esc_html( ts_t( 'Insert Response' ) );
            ?> --</option>

                                        <?php 
            if ( $is_pro && !empty( $canned_responses ) ) {
                foreach ( $canned_responses as $cr ) {
                    $val = ( isset( $cr['content'] ) ? $cr['content'] : $cr['Content'] ?? $cr['message'] ?? $cr['Message'] ?? $cr['responseMessage'] ?? '' );
                    ?>
  
                                              <option value="<?php 
                    echo esc_attr( $val );
                    ?>"><?php 
                    echo esc_html( $cr['title'] );
                    ?></option>
  
                                          <?php 
                }
            }
            ?>

                                    </select>

                                    <label class="ts-internal-toggle">

                                        <input type="checkbox" name="is_internal" value="1" onchange="tsToggleInternal(this)">

                                        🔒 <?php 
            echo esc_html( ts_t( 'Internal Note' ) );
            ?>

                                    </label>

                                <?php 
        }
        ?>

                            </div>

                        </div>

                        <?php 
        wp_nonce_field( 'ts_add_comment_action' );
        ?>

                        <input type="hidden" name="ticket_id" value="<?php 
        echo esc_attr( $ticket['id'] );
        ?>">

                        <textarea id="ts_reply_area" name="comment_content" class="ts-reply-textarea" maxlength="5000" placeholder="<?php 
        echo esc_html( ts_t( 'Type your message here...' ) );
        ?>" required></textarea>

                        <div class="ts-reply-footer">

                            <div style="display:flex; align-items:center; gap:15px; flex:1; flex-wrap:wrap;">

                                <button type="submit" name="submit_comment" class="ts-btn-send"><?php 
        echo esc_html( ts_t( 'Submit Reply' ) );
        ?></button>

                                

                                <div class="ts-file-wrapper">

                                    <input type="file" name="comment_attachment" class="ts-file-input" accept=".jpg,.jpeg,.png,.pdf,.doc,.docx,.xls,.xlsx,.zip,.txt" onchange="document.getElementById('reply-file-name').textContent = this.files[0].name; tsValidateFile(this);">

                                    <div class="ts-file-custom">

                                        <span class="ts-file-btn"><?php 
        echo esc_html( ts_t( 'Select File' ) );
        ?></span>

                                        <span id="reply-file-name" style="max-width:150px; overflow:hidden; white-space:nowrap; text-overflow:ellipsis;"><?php 
        echo esc_html( ts_t( 'No file selected' ) );
        ?></span>

                                    </div>

                                </div>

                            </div>

                            <div style="font-size:11px; color:#888;"><?php 
        echo esc_html( ts_t( 'Max 5MB' ) );
        ?></div>

                        </div>

                    </form>

                </div>

            </div>



            <?php 
        if ( $user_role === 'Agent' || $user_role === 'Admin' ) {
            ?>

            <div class="ts-sidebar-column">

                <div class="ts-card" style="border-top: 3px solid <?php 
            echo esc_attr( get_option( 'ts_widget_color', '#0056b3' ) );
            ?>; padding: 15px;">

                    <h3 style="margin-top:0; margin-bottom:12px; font-size:13px; font-weight:700; text-transform:uppercase; color:#999;"><?php 
            echo esc_html( ts_t( 'Manage Ticket' ) );
            ?></h3>

                    <form action="" method="post">

                        <?php 
            wp_nonce_field( 'ts_manage_ticket_action' );
            ?>

                        <input type="hidden" name="ticket_id" value="<?php 
            echo esc_attr( $ticket['id'] );
            ?>">

                        <label class="ts-sidebar-label"><?php 
            echo esc_html( ts_t( 'Status' ) );
            ?></label>

                        <select name="update_status" id="ts_update_status" class="ts-sidebar-select" onchange="tsUpdateSubStatuses()">

                            <option value="Open" <?php 
            selected( $ticket['status'], 'Open' );
            ?>><?php 
            echo esc_html( ts_t( 'Open' ) );
            ?></option>

                            <option value="In Progress" <?php 
            selected( $ticket['status'], 'In Progress' );
            ?>><?php 
            echo esc_html( ts_t( 'In Progress' ) );
            ?></option>

                            <option value="Pending" <?php 
            selected( $ticket['status'], 'Pending' );
            ?>><?php 
            echo esc_html( ts_t( 'Pending' ) );
            ?></option>

                            <option value="Closed" <?php 
            selected( $ticket['status'], 'Closed' );
            ?>><?php 
            echo esc_html( ts_t( 'Closed' ) );
            ?></option>
                            <option value="Resolved" <?php 
            selected( $ticket['status'], 'Resolved' );
            ?>><?php 
            echo esc_html( ts_t( 'Resolved' ) );
            ?></option>

                        </select>

                        <div id="ts_sub_status_container" style="display: none;">

                            <label class="ts-sidebar-label"><?php 
            echo esc_html( ts_t( 'Sub-Status' ) );
            ?></label>

                            <select name="update_sub_status_id" id="ts_update_sub_status_id" class="ts-sidebar-select">

                                <option value=""><?php 
            echo esc_html( ts_t( 'None' ) );
            ?></option>

                            </select>

                        </div>

                        <label class="ts-sidebar-label"><?php 
            echo esc_html( ts_t( 'Assigned Agent' ) );
            ?></label>

                        <?php 
            if ( $is_pro ) {
                ?>

                            <select name="assign_agent_id" class="ts-sidebar-select">

                                <option value=""><?php 
                echo esc_html( ts_t( '-- Unassign --' ) );
                ?></option>

                                <?php 
                foreach ( $agents as $agent ) {
                    ?>

                                    <option value="<?php 
                    echo esc_attr( $agent['id'] );
                    ?>" <?php 
                    selected( ( isset( $ticket['agentId'] ) ? $ticket['agentId'] : '' ), $agent['id'] );
                    ?>><?php 
                    echo esc_html( $agent['name'] );
                    ?></option>

                                <?php 
                }
                ?>

                            </select>

                        <?php 
            } else {
                ?><select disabled class="ts-sidebar-select" style="background:#f0f0f1;"><option>🔒 <?php 
                echo esc_html( ts_t( 'Upgrade to assign' ) );
                ?></option></select><?php 
            }
            ?>

                        <button type="submit" name="submit_manage_ticket" class="ts-sidebar-btn"><?php 
            echo esc_html( ts_t( 'Update' ) );
            ?></button>

                    </form>
                </div>
                <div class="ts-card">

                    <h3 style="margin-top:0; font-size:13px; font-weight:700; text-transform:uppercase; color:#999; margin-bottom:10px;"><?php 
            echo esc_html( ts_t( 'Customer' ) );
            ?></h3>

                    <div style="font-size:13px; color: #333;">

                        <div style="font-weight:600; font-size:14px; margin-bottom:2px;"><?php 
            echo esc_html( $display_name );
            ?></div>

                        <?php 
            if ( !empty( $raw_email ) && $raw_email !== $display_name ) {
                ?>

                            <div style="color:#666; margin-bottom:4px;"><a href="mailto:<?php 
                echo esc_attr( $raw_email );
                ?>" style="text-decoration:none; color:<?php 
                echo esc_attr( get_option( 'ts_widget_color', '#0056b3' ) );
                ?>;"><?php 
                echo esc_html( $raw_email );
                ?></a></div>

                        <?php 
            }
            ?>

                        <?php 
            if ( !empty( $raw_phone ) ) {
                ?>

                            <div style="color:#666;"><span class="dashicons dashicons-phone" style="font-size:14px; width:14px; height:14px; line-height:1; vertical-align:middle; margin-top:-2px;"></span> <a href="tel:<?php 
                echo esc_attr( $raw_phone );
                ?>" style="text-decoration:none; color:#666;"><?php 
                echo esc_html( $raw_phone );
                ?></a></div>

                        <?php 
            }
            ?>

                    </div>

                </div>

                <?php 
            if ( class_exists( 'WooCommerce' ) ) {
                ?>

                <div class="ts-card" style="padding:0; overflow:hidden;">

                    <div style="padding:12px 15px; background:#f9f9f9; border-bottom:1px solid #eee;">

                        <h3 style="margin:0; font-size:13px; font-weight:700; color:#555;"><?php 
                echo esc_html( ts_t( 'Customer Orders' ) );
                ?></h3>

                    </div>

                    <div style="padding:15px;">

                        <?php 
                if ( $is_pro ) {
                    $woo_orders = ( $raw_email && function_exists( 'wc_get_orders' ) ? wc_get_orders( [
                        'customer' => $raw_email,
                        'limit'    => 3,
                    ] ) : [] );
                    if ( !empty( $woo_orders ) ) {
                        foreach ( $woo_orders as $order ) {
                            ?>

                            <div style="margin-bottom:10px; padding-bottom:10px; border-bottom:1px solid #eee; font-size:13px;">

                                <div style="display:flex; justify-content:space-between; font-weight:bold;">

                                    <a href="<?php 
                            echo esc_url( $order->get_edit_order_url() );
                            ?>" target="_blank">#<?php 
                            /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
                            echo $order->get_id();
                            ?></a>

                                    <span><?php 
                            /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
                            echo $order->get_formatted_order_total();
                            ?></span>

                                </div>

                                <div style="color:#666; font-size:11px; margin-top:3px;"><?php 
                            echo esc_html( wc_format_datetime( $order->get_date_created() ) );
                            ?> • <?php 
                            /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
                            echo $order->get_status();
                            ?></div>

                            </div>

                        <?php 
                        }
                    } else {
                        ?><p style="color:#666; font-size:13px; text-align: center;"><?php 
                        echo esc_html( ts_t( 'No recent orders found.' ) );
                        ?></p><?php 
                    }
                } else {
                    ?>

                            <div style="text-align:center; padding:10px 0;"><div style="font-size:24px; margin-bottom:10px;">🔒</div><p style="font-size:12px; color:#666;"><?php 
                    echo esc_html( ts_t( 'See order details without leaving this page.' ) );
                    ?></p>

                            <?php 
                    if ( current_user_can( 'manage_options' ) ) {
                        ?>

                                <a href="<?php 
                        echo esc_url( admin_url( 'admin.php?page=ts-custom-upgrade' ) );
                        ?>" class="button button-secondary" style="font-size:12px;"><?php 
                        echo esc_html( ts_t( 'Unlock Pro Features' ) );
                        ?></a>

                            <?php 
                    }
                    ?>

                                <?php 
                }
                ?>
                            </div>

                        </div>

                    </div>

                </div>

                <?php 
            }
            ?>

            </div> 

            <?php 
        }
        ?>

        </div> 

        <?php 
        echo wp_kses_post( ts_render_footer() );
        ?>

    </div>

    

    <script>

    function tsValidateFile(input) { 

        if (input.files && input.files[0]) {

            var file = input.files[0];

            if (file.size > 5 * 1024 * 1024) { 

                alert("File too large. Max 5MB."); 

                input.value = ""; 

                return;

            }

            var allowedExts = ['.jpg','.jpeg','.png','.pdf','.doc','.docx','.xls','.xlsx','.zip','.txt'];

            var fileName = file.name.toLowerCase();

            var isAllowed = false;

            for (var i=0; i<allowedExts.length; i++) {

                if (fileName.endsWith(allowedExts[i])) { isAllowed = true; break; }

            }

            if (!isAllowed) {

                alert("File type not allowed for security reasons.");

                input.value = "";

            }

        } 

    }

    function tsToggleInternal(checkbox) { 

        var textarea = document.getElementById('ts_reply_area');

        if (checkbox.checked) { 
            textarea.classList.add('internal-active'); 
            textarea.placeholder = "<?php 
        echo esc_html( ts_t( 'Internal Note: Only staff can see this...' ) );
        ?>"; 
        } else { 
            textarea.classList.remove('internal-active'); 
            textarea.placeholder = "<?php 
        echo esc_html( ts_t( 'Type your message here...' ) );
        ?>"; 
        } 

    }

    function tsInsertCanned(select) { 
        if (select.value) { 
            var textarea = document.getElementById('ts_reply_area');
            if (textarea) {
                textarea.value = textarea.value + (textarea.value ? "\n" : "") + select.value;
            }
            select.value = ''; // Reset dropdown
        } 
    }

    function tsShowLoading(form) { var btn = form.querySelector('button[type="submit"]'); if(btn){ btn.style.minWidth=btn.offsetWidth+'px'; btn.innerHTML='⏳ '+"<?php 
        echo esc_html( ts_t( 'Sending...' ) );
        ?>"; btn.style.opacity='0.6'; btn.style.cursor='wait'; btn.style.pointerEvents='none'; } }

    

    var tsAllSubStatuses = <?php 
        /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
        echo wp_json_encode( $sub_statuses );
        ?>;

    var currentSubStatusId = <?php 
        /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.Security.EscapeOutput.UnsafePrintingFunction */
        echo ( isset( $ticket['subStatusId'] ) && !empty( $ticket['subStatusId'] ) ? intval( $ticket['subStatusId'] ) : 'null' );
        ?>;

    

    function tsUpdateSubStatuses() {

        var parentStatus = document.getElementById('ts_update_status').value;

        var subSelect = document.getElementById('ts_update_sub_status_id');

        var subContainer = document.getElementById('ts_sub_status_container');

        subSelect.innerHTML = '<option value="">-- <?php 
        echo esc_html( ts_t( 'None' ) );
        ?> --</option>';

        

        var hasSubStatuses = false;

        tsAllSubStatuses.forEach(function(sub) {

            if (sub.parentStatus === parentStatus) {

                var option = document.createElement('option');

                option.value = sub.id;

                option.text = sub.name;

                if (sub.id == currentSubStatusId) {

                    option.selected = true;

                }

                subSelect.appendChild(option);

                hasSubStatuses = true;

            }

        });



        if (hasSubStatuses) {

            subContainer.style.display = 'block';

        } else {

            subContainer.style.display = 'none';

        }



        currentSubStatusId = null; // Reset after first load so manual changes stick

    }

    document.addEventListener('DOMContentLoaded', function() {

        tsUpdateSubStatuses();

        

        // Format single ticket dates

        document.querySelectorAll('.ts-single-time').forEach(function(el) {

            var utcDate = el.getAttribute('data-utc');

            if (utcDate) {

                var date = new Date(utcDate);

                if (!isNaN(date.getTime())) {

                    el.textContent = date.toLocaleString(undefined, { month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: '2-digit' });

                }

            }

        });

    });

    </script>

    <?php 
        return ob_get_clean();
    }

}
add_shortcode( 'ticketing_system_view_ticket', 'display_single_ticket_view' );
if ( !function_exists( 'handle_comment_submission' ) ) {
    function handle_comment_submission() {
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_POST['submit_comment'] ) && isset( $_SESSION['ts_auth_token'] ) ) {
            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.Security.EscapeOutput.UnsafePrintingFunction, WordPress.Security.NonceVerification
            if ( !isset( $_POST['_wpnonce'] ) || !wp_verify_nonce( sanitize_text_field( wp_unslash( ( isset( $_POST['_wpnonce'] ) ? $_POST['_wpnonce'] : '' ) ) ), 'ts_add_comment_action' ) ) {
                wp_die( 'Security check failed.' );
            }
            $api_key = get_option( 'ts_tenant_api_key' );
            $token = sanitize_text_field( wp_unslash( $_SESSION['ts_auth_token'] ) );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $ticket_id = intval( sanitize_text_field( wp_unslash( $_POST['ticket_id'] ) ) );
            $api_url = TS_API_BASE_URL . '/tickets/' . $ticket_id . '/comments';
            $fields = [
                'Content'    => sanitize_textarea_field( wp_unslash( ( isset( $_POST['comment_content'] ) ? $_POST['comment_content'] : '' ) ) ),
                'IsInternal' => ( isset( $_POST['is_internal'] ) && sanitize_text_field( wp_unslash( $_POST['is_internal'] ) ) == '1' ? 'true' : 'false' ),
            ];
            // Use the new Helper Function (Input name is 'comment_attachment')
            $result = ts_send_api_request_with_file(
                $api_url,
                $fields,
                'comment_attachment',
                $token,
                $api_key
            );
            if ( is_admin() ) {
                $redirect_url = admin_url( 'admin.php?page=ts-view-ticket&ticket_id=' . $ticket_id );
            } else {
                $redirect_url = remove_query_arg( ['comment', 'manage'], add_query_arg( 'ticket_id', $ticket_id, ts_get_page_url( 'view-ticket', 'View Ticket' ) ) );
            }
            if ( $result['code'] == 201 ) {
                wp_safe_redirect( $redirect_url );
                exit;
            } else {
                wp_safe_redirect( add_query_arg( 'comment', 'failed', $redirect_url ) );
                exit;
            }
        }
    }

}
add_action( 'init', 'handle_comment_submission' );
if ( !function_exists( 'handle_manage_ticket_submission' ) ) {
    function handle_manage_ticket_submission() {
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_POST['submit_manage_ticket'] ) && isset( $_SESSION['ts_auth_token'] ) ) {
            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.Security.EscapeOutput.UnsafePrintingFunction, WordPress.Security.NonceVerification
            if ( !isset( $_POST['_wpnonce'] ) || !wp_verify_nonce( sanitize_text_field( wp_unslash( ( isset( $_POST['_wpnonce'] ) ? $_POST['_wpnonce'] : '' ) ) ), 'ts_manage_ticket_action' ) ) {
                wp_die( 'Security check failed.' );
            }
            $api_key = get_option( 'ts_tenant_api_key' );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $ticket_id = intval( sanitize_text_field( wp_unslash( $_POST['ticket_id'] ) ) );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $agent_id = ( isset( $_POST['assign_agent_id'] ) && sanitize_text_field( wp_unslash( $_POST['assign_agent_id'] ) ) !== "" ? intval( sanitize_text_field( wp_unslash( $_POST['assign_agent_id'] ) ) ) : null );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $status = sanitize_text_field( wp_unslash( $_POST['update_status'] ) );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $sub_status_id = ( isset( $_POST['update_sub_status_id'] ) && sanitize_text_field( wp_unslash( $_POST['update_sub_status_id'] ) ) !== "" ? intval( sanitize_text_field( wp_unslash( $_POST['update_sub_status_id'] ) ) ) : null );
            $token = sanitize_text_field( wp_unslash( $_SESSION['ts_auth_token'] ) );
            $api_url = TS_API_BASE_URL . '/tickets/' . $ticket_id;
            $body = [
                'AgentId'     => $agent_id,
                'Status'      => $status,
                'SubStatusId' => $sub_status_id,
            ];
            $args = [
                'method'      => 'PUT',
                'headers'     => [
                    'Content-Type'      => 'application/json',
                    'Authorization'     => 'Bearer ' . $token,
                    'X-Api-Key'         => $api_key,
                    'X-Client-Domain'   => home_url(),
                    'X-Client-Language' => ts_get_api_language(),
                ],
                'body'        => json_encode( $body ),
                'data_format' => 'body',
            ];
            $response = wp_remote_request( $api_url, $args );
            $code = wp_remote_retrieve_response_code( $response );
            if ( is_admin() ) {
                $redirect_url = admin_url( 'admin.php?page=ts-view-ticket&ticket_id=' . $ticket_id );
            } else {
                $redirect_url = remove_query_arg( ['comment', 'manage'], add_query_arg( 'ticket_id', $ticket_id, ts_get_page_url( 'view-ticket', 'View Ticket' ) ) );
            }
            if ( !is_wp_error( $response ) && ($code == 200 || $code == 204) ) {
                wp_safe_redirect( add_query_arg( 'manage', 'success', $redirect_url ) );
                exit;
            } else {
                wp_safe_redirect( add_query_arg( 'manage', 'failed', $redirect_url ) );
                exit;
            }
        }
    }

}
add_action( 'init', 'handle_manage_ticket_submission' );
// 7. HELPERS
// =================================================================
if ( !function_exists( 'ts_get_agents_from_api' ) ) {
    function ts_get_agents_from_api(  $token, $api_key  ) {
        // Now points to the new "safe" endpoint we created for agents
        $api_url = TS_API_BASE_URL . '/users/agents';
        $args = [
            'method'      => 'GET',
            'headers'     => [
                'Authorization' => 'Bearer ' . $token,
                'X-Api-Key'     => $api_key,
            ],
            'data_format' => 'body',
            'timeout'     => 15,
        ];
        $response = wp_remote_get( $api_url, $args );
        if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) != 200 ) {
            return [];
        }
        return json_decode( wp_remote_retrieve_body( $response ), true );
    }

}
if ( !function_exists( 'ts_get_canned_responses_from_api' ) ) {
    function ts_get_canned_responses_from_api(  $token, $api_key  ) {
        $api_url = TS_API_BASE_URL . '/cannedresponses';
        $args = [
            'method'      => 'GET',
            'headers'     => [
                'Authorization' => 'Bearer ' . $token,
                'X-Api-Key'     => $api_key,
            ],
            'data_format' => 'body',
            'timeout'     => 15,
        ];
        $response = wp_remote_get( $api_url, $args );
        if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) != 200 ) {
            return [];
        }
        return json_decode( wp_remote_retrieve_body( $response ), true );
    }

}
// --- TRANSLATION HELPER (MASTER VERSION) ---
if ( !function_exists( 'ts_t' ) ) {
    function ts_t(  $text  ) {
        // 1. Get the Current WordPress Locale (e.g., 'ar', 'ar_EG', 'en_US')
        $locale = get_locale();
        // 2. If it's NOT Arabic, return English immediately
        if ( strpos( $locale, 'ar' ) !== 0 ) {
            return $text;
        }
        $dictionary = [
            'SahlDesk:'                                                                                                                          => 'SahlDesk:',
            'Please check your email from SahlDesk (and your spam folder) to complete your opt-in for Freemius.'                                 => 'يرجى التحقق من بريدك الإلكتروني من SahlDesk (ومجلد البريد العشوائي) لإكمال اشتراكك في Freemius.',
            'Please fill out this field.'                                                                                                        => 'يرجى تعبئة هذا الحقل.',
            'Please fill in Email and Issue.'                                                                                                    => 'يرجى تعبئة البريد الإلكتروني والمشكلة.',
            'File must be less than 5MB'                                                                                                         => 'يجب أن يكون حجم الملف أقل من 5 ميغابايت',
            'Refresh Pricing'                                                                                                                    => 'تحديث الأسعار',
            'Perfect for getting started with basic ticketing.'                                                                                  => 'مثالي للبدء بنظام التذاكر الأساسي.',
            'forever'                                                                                                                            => 'للأبد',
            'Ticket Sub-Statuses'                                                                                                                => 'حالات التذاكر الفرعية',
            'Sub-Statuses'                                                                                                                       => 'الحالات الفرعية',
            'Download Logs'                                                                                                                      => 'تنزيل السجلات',
            'Diagnostics & Debugging'                                                                                                            => 'التشخيص وتصحيح الأخطاء',
            'If you are experiencing issues, you can download the internal plugin logs to share with support.'                                   => 'إذا كنت تواجه مشكلات، يمكنك تنزيل سجلات الإضافة الداخلية لمشاركتها مع الدعم.',
            'User Role Management'                                                                                                               => 'إدارة أدوار المستخدمين',
            'User Roles'                                                                                                                         => 'أدوار المستخدمين',
            'Reports & Analytics'                                                                                                                => 'التقارير والتحليلات',
            'Reports'                                                                                                                            => 'التقارير',
            'Please enter a subject for your ticket.'                                                                                            => 'يرجى إدخال عنوان لتذكرتك.',
            'Please enter a description for your ticket.'                                                                                        => 'يرجى إدخال تفاصيل لتذكرتك.',
            'Canned Responses'                                                                                                                   => 'الردود الجاهزة',
            'This is a Pro feature'                                                                                                              => 'هذه الميزة متوفرة في النسخة المدفوعة',
            'Upgrade to the Pro version to unlock User Role Management and assign custom permissions to your team.'                              => 'قم بالترقية إلى النسخة المدفوعة لفتح إدارة أدوار المستخدمين وتعيين أذونات مخصصة لفريقك.',
            'Upgrade to the Pro version to save hours of typing with Canned Responses.'                                                          => 'قم بالترقية إلى النسخة المدفوعة لتوفير ساعات من الكتابة باستخدام الردود الجاهزة.',
            'Upgrade to the Pro version to organize your workflow with custom Ticket Sub-Statuses.'                                              => 'قم بالترقية إلى النسخة المدفوعة لتنظيم سير عملك باستخدام الحالات الفرعية المخصصة للتذاكر.',
            'Upgrade to the Pro version to unlock advanced Reports & Analytics.'                                                                 => 'قم بالترقية إلى النسخة المدفوعة لفتح التقارير والتحليلات المتقدمة.',
            'Assigned To'                                                                                                                        => 'مسندة إلى',
            'Assigned to Me'                                                                                                                     => 'مسندة إلي',
            'Ticket Categories'                                                                                                                  => 'تصنيفات التذاكر',
            'Categories'                                                                                                                         => 'التصنيفات',
            'Edit Category'                                                                                                                      => 'تعديل التصنيف',
            'Add Category'                                                                                                                       => 'إضافة تصنيف',
            'Color'                                                                                                                              => 'اللون',
            'Cancel'                                                                                                                             => 'إلغاء',
            'Add'                                                                                                                                => 'إضافة',
            'Action'                                                                                                                             => 'إجراء',
            'No categories found.'                                                                                                               => 'لا توجد تصنيفات.',
            'Archived'                                                                                                                           => 'مؤرشف',
            'Edit'                                                                                                                               => 'تعديل',
            'Restore'                                                                                                                            => 'استعادة',
            'Archive'                                                                                                                            => 'أرشفة',
            'Delete'                                                                                                                             => 'حذف',
            'Archive this category? It will be hidden from the customer frontend.'                                                               => 'هل تريد أرشفة هذا التصنيف؟ سيتم إخفاؤه من واجهة العميل.',
            'Permanently delete this category? Warning: Historical tickets might be affected.'                                                   => 'هل تريد حذف هذا التصنيف نهائياً؟ تحذير: قد تتأثر التذاكر السابقة.',
            'Category added.'                                                                                                                    => 'تم إضافة التصنيف.',
            'Category updated.'                                                                                                                  => 'تم تحديث التصنيف.',
            'Category archived. It is now hidden from the customer form.'                                                                        => 'تم أرشفة التصنيف. وهو الآن مخفي من نموذج العميل.',
            'Category restored.'                                                                                                                 => 'تم استعادة التصنيف.',
            'Category deleted.'                                                                                                                  => 'تم حذف التصنيف.',
            'Could not add category.'                                                                                                            => 'تعذر إضافة التصنيف.',
            'Welcome to SahlDesk!'                                                                                                               => 'مرحباً بك في سهل ديسك!',
            'Let\'s finish setting up your account.'                                                                                             => 'دعنا نكمل إعداد حسابك.',
            'Helpdesk Name'                                                                                                                      => 'اسم مكتب المساعدة',
            'e.g. My Store Support'                                                                                                              => 'مثال: دعم متجري',
            'e.g., Awaiting Customer'                                                                                                            => 'مثال: بانتظار العميل',
            'Choose a vibrant color'                                                                                                             => 'اختر لوناً زاهياً',
            'Your Support Email:'                                                                                                                => 'بريد الدعم الخاص بك:',
            'Customers will email this address, and it will automatically create tickets in your dashboard.'                                     => 'سيقوم العملاء بمراسلة هذا البريد، وسيتم إنشاء تذاكر تلقائياً في لوحة التحكم الخاصة بك.',
            'Admin Password'                                                                                                                     => 'كلمة مرور المشرف',
            '(For standalone portal access)'                                                                                                     => '(للوصول إلى البوابة المستقلة)',
            'Choose a secure password'                                                                                                           => 'اختر كلمة مرور آمنة',
            'Admin Email'                                                                                                                        => 'بريد المشرف',
            '(This will be your primary login email)'                                                                                            => '(سيكون هذا بريدك الإلكتروني الأساسي لتسجيل الدخول)',
            'Skip for now'                                                                                                                       => 'تخطى الآن',
            'Complete Setup'                                                                                                                     => 'إكمال الإعداد',
            'Saving...'                                                                                                                          => 'جاري الحفظ...',
            'Please enter a password with at least 6 characters.'                                                                                => 'يرجى إدخال كلمة مرور تتكون من 6 أحرف على الأقل.',
            'Welcome back'                                                                                                                       => 'مرحباً بعودتك',
            'Here is what needs your attention.'                                                                                                 => 'إليك ما يحتاج إلى انتباهك.',
            'Search tickets by subject or ID...'                                                                                                 => 'ابحث عن التذاكر بالموضوع أو الرقم...',
            'All Tickets'                                                                                                                        => 'جميع التذاكر',
            'SahlDesk Settings'                                                                                                                  => 'إعدادات SahlDesk',
            'License Managed via Freemius'                                                                                                       => 'إدارة الترخيص عبر Freemius',
            'Pending Email Verification:'                                                                                                        => 'في انتظار التحقق من البريد الإلكتروني:',
            'Please check your email and click the confirmation link from Freemius to fully activate your account.'                              => 'يرجى التحقق من بريدك الإلكتروني والنقر على رابط التأكيد من Freemius لتفعيل حسابك بالكامل.',
            'Your account is connected to Freemius. The plugin is attempting to retrieve your SahlDesk API Key automatically from your backend.' => 'حسابك متصل بـ Freemius. تحاول الإضافة استرداد مفتاح SahlDesk API الخاص بك تلقائياً من الخادم.',
            'Retry Sync'                                                                                                                         => 'إعادة المحاولة للمزامنة',
            'Enter API Key'                                                                                                                      => 'أدخل مفتاح الـ API',
            'Please enter your API Key to activate the plugin.'                                                                                  => 'يرجى إدخال مفتاح الـ API الخاص بك لتفعيل الإضافة.',
            'Activate License'                                                                                                                   => 'تفعيل الترخيص',
            'SahlDesk Core Setup'                                                                                                                => 'إعدادات SahlDesk الأساسية',
            'Manage your remote ticketing API connection, widget settings, and license syncing.'                                                 => 'إدارة اتصال API لنظام التذاكر، وإعدادات الأداة، ومزامنة الترخيص.',
            'API Connection'                                                                                                                     => 'اتصال الـ API',
            'Active'                                                                                                                             => 'نشط',
            'Company Name'                                                                                                                       => 'اسم الشركة',
            'License Key'                                                                                                                        => 'مفتاح الترخيص',
            'Support Email'                                                                                                                      => 'البريد الإلكتروني للدعم',
            'Not set'                                                                                                                            => 'غير محدد',
            'Current Plan'                                                                                                                       => 'الخطة الحالية',
            'Sync License'                                                                                                                       => 'مزامنة الترخيص',
            'Widget Settings'                                                                                                                    => 'إعدادات أداة الدعم',
            'Enable floating guest support widget on frontend'                                                                                   => 'تفعيل أداة دعم الزوار العائمة في واجهة الموقع',
            'Widget Theme Color'                                                                                                                 => 'لون تصميم الأداة',
            'Select the primary brand color for the floating widget.'                                                                            => 'حدد اللون الأساسي لعلامتك التجارية لأداة الدعم العائمة.',
            'Save Settings'                                                                                                                      => 'حفظ الإعدادات',
            'Deactivate License (Move to another site)'                                                                                          => 'إلغاء تفعيل الترخيص (النقل لموقع آخر)',
            'Status'                                                                                                                             => 'الحالة',
            'Priority'                                                                                                                           => 'الأولوية',
            'Category'                                                                                                                           => 'القسم',
            'Customer'                                                                                                                           => 'العميل',
            'Assigned Agent'                                                                                                                     => 'الموظف المسؤول',
            'Created'                                                                                                                            => 'تاريخ الإنشاء',
            'Date'                                                                                                                               => 'التاريخ',
            'Title'                                                                                                                              => 'العنوان',
            'ID'                                                                                                                                 => 'رقم التذكرة',
            'Welcome'                                                                                                                            => 'مرحباً',
            'Sub-Status'                                                                                                                         => 'الحالة الفرعية',
            'Sub-Statuses'                                                                                                                       => 'الحالات الفرعية',
            'None'                                                                                                                               => 'بدون',
            'Update'                                                                                                                             => 'تحديث',
            'Error'                                                                                                                              => 'خطأ',
            'Success'                                                                                                                            => 'نجاح',
            'Login'                                                                                                                              => 'تسجيل الدخول',
            'Sign In'                                                                                                                            => 'تسجيل الدخول',
            'Please Log In'                                                                                                                      => 'يرجى تسجيل الدخول',
            'Please Log In to view your tickets.'                                                                                                => 'يرجى تسجيل الدخول لعرض تذاكرك.',
            'You need to log in to view your tickets.'                                                                                           => 'يجب عليك تسجيل الدخول لعرض التذاكر.',
            'Login Now'                                                                                                                          => 'سجل دخولك الآن',
            'Email'                                                                                                                              => 'بريد إلكتروني',
            'Email Address'                                                                                                                      => 'البريد الإلكتروني',
            'Password'                                                                                                                           => 'كلمة المرور',
            'Forgot?'                                                                                                                            => 'نسيت؟',
            'Forgot your password?'                                                                                                              => 'نسيت كلمة المرور؟',
            "Don't have an account?"                                                                                                             => 'ليس لديك حساب؟',
            'Register'                                                                                                                           => 'تسجيل حساب',
            'Welcome back'                                                                                                                       => 'مرحباً بعودتك',
            'You are already logged in.'                                                                                                         => 'لقد قمت بتسجيل الدخول بالفعل.',
            'You are currently signed in to your account.'                                                                                       => 'أنت مسجل الدخول حالياً إلى حسابك.',
            'Go to Dashboard'                                                                                                                    => 'الذهاب للوحة التحكم',
            'Logout'                                                                                                                             => 'تسجيل الخروج',
            'Invalid email or password.'                                                                                                         => 'البريد الإلكتروني أو كلمة المرور غير صحيحة.',
            'Connection to the server failed.'                                                                                                   => 'فشل الاتصال بالخادم.',
            'Access Denied'                                                                                                                      => 'تم رفض الوصول',
            'Reset Password'                                                                                                                     => 'إعادة تعيين كلمة المرور',
            'Enter your email and we will send you a reset link.'                                                                                => 'أدخل بريدك الإلكتروني وسنرسل لك رابط إعادة التعيين.',
            'Send Reset Link'                                                                                                                    => 'إرسال الرابط',
            'Back to Login'                                                                                                                      => 'عودة لتسجيل الدخول',
            'Check Your Email'                                                                                                                   => 'تفقد بريدك الإلكتروني',
            'We have sent a password reset link to your email address.'                                                                          => 'تم إرسال رابط إعادة تعيين كلمة المرور إلى بريدك الإلكتروني.',
            'Set New Password'                                                                                                                   => 'تعيين كلمة مرور جديدة',
            'New Password'                                                                                                                       => 'كلمة المرور الجديدة',
            'Update Password'                                                                                                                    => 'تحديث كلمة المرور',
            'Password Changed!'                                                                                                                  => 'تم تغيير كلمة المرور!',
            'Your password has been updated successfully.'                                                                                       => 'تم تحديث كلمة المرور بنجاح.',
            'Error: Invalid or expired token.'                                                                                                   => 'خطأ: الرابط غير صالح أو انتهت صلاحيته.',
            'Invalid or missing reset token.'                                                                                                    => 'رمز إعادة التعيين مفقود أو غير صالح.',
            'Support Dashboard'                                                                                                                  => 'لوحة الدعم',
            'My Tickets'                                                                                                                         => 'تذاكري',
            'No tickets found'                                                                                                                   => 'لا توجد تذاكر',
            'No tickets found.'                                                                                                                  => 'لا توجد تذاكر.',
            'You are all caught up! Create a new ticket to get started.'                                                                         => 'أنت مطلع على كل شيء! أنشئ تذكرة جديدة للبدء.',
            'You are all caught up! When you have tickets, they will appear beautifully here.'                                                   => 'أنت مطلع على كل شيء! عندما يكون لديك تذاكر، ستظهر بشكل جميل هنا.',
            'View dashboard'                                                                                                                     => 'عرض لوحة التحكم',
            'Export to Excel'                                                                                                                    => 'تصدير إلى Excel',
            'Export'                                                                                                                             => 'تصدير',
            'Create a New Ticket'                                                                                                                => 'إنشاء تذكرة جديدة',
            'New Ticket'                                                                                                                         => 'تذكرة جديدة',
            'Subject'                                                                                                                            => 'الموضوع',
            'Description'                                                                                                                        => 'الوصف',
            'Attachment'                                                                                                                         => 'مرفقات',
            'Attachment (Optional)'                                                                                                              => 'المرفقات (اختياري)',
            'Create Ticket'                                                                                                                      => 'إنشاء تذكرة',
            'Ticket Created'                                                                                                                     => 'تم إنشاء التذكرة',
            'All Statuses'                                                                                                                       => 'جميع الحالات',
            'ID'                                                                                                                                 => 'المعرف',
            'No tickets match your search or filter.'                                                                                            => 'لا توجد تذاكر تطابق بحثك أو عامل التصفية الخاص بك.',
            'This Helpdesk name is already taken. Please choose another one.'                                                                    => 'اسم مكتب المساعدة هذا مستخدم بالفعل. يرجى اختيار اسم آخر.',
            'Helpdesk name must contain letters or numbers.'                                                                                     => 'يجب أن يحتوي اسم مكتب المساعدة على أحرف أو أرقام.',
            'Missing required fields.'                                                                                                           => 'الحقول المطلوبة مفقودة.',
            'Your ticket has been submitted successfully.'                                                                                       => 'تم تقديم تذكرتك بنجاح.',
            'A confirmation email has been sent.'                                                                                                => 'تم إرسال بريد إلكتروني للتأكيد.',
            'Please describe your issue in detail'                                                                                               => 'يرجى وصف المشكلة بالتفصيل',
            'e.g., Cannot access my account'                                                                                                     => 'مثال: لا يمكنني الدخول لحسابي',
            'Max 5MB'                                                                                                                            => 'الحد الأقصى 5 ميجابايت',
            'Max 5MB (JPG, PNG, PDF)'                                                                                                            => 'الحد الأقصى 5 ميجابايت (JPG, PNG, PDF)',
            'Manage Ticket'                                                                                                                      => 'إدارة التذكرة',
            'Assign to'                                                                                                                          => 'تعيين إلى',
            '-- Unassign --'                                                                                                                     => '-- إلغاء التعيين --',
            'Unassigned'                                                                                                                         => 'غير معين',
            'Conversation'                                                                                                                       => 'المحادثة',
            'Post a Reply'                                                                                                                       => 'إضافة رد',
            'Submit Reply'                                                                                                                       => 'إرسال الرد',
            'Type your message here...'                                                                                                          => 'اكتب رسالتك هنا...',
            'Internal Note'                                                                                                                      => 'ملاحظة داخلية',
            'Internal Note: Only staff can see this...'                                                                                          => 'ملاحظة داخلية: الموظفون فقط يمكنهم رؤية هذا...',
            'Insert Response'                                                                                                                    => 'إدراج رد جاهز',
            'Sending...'                                                                                                                         => 'جاري الإرسال...',
            'View Attachment'                                                                                                                    => 'عرض المرفق',
            'No comments yet.'                                                                                                                   => 'لا توجد ردود حتى الآن.',
            'Read more'                                                                                                                          => 'قراءة المزيد',
            'Show less'                                                                                                                          => 'عرض أقل',
            'Ticket updated successfully.'                                                                                                       => 'تم تحديث التذكرة بنجاح.',
            'Failed to update ticket.'                                                                                                           => 'فشل في تحديث التذكرة.',
            'Open'                                                                                                                               => 'مفتوح',
            'In Progress'                                                                                                                        => 'جاري العمل',
            'Pending'                                                                                                                            => 'قيد الانتظار',
            'Closed'                                                                                                                             => 'مغلق',
            'Resolved'                                                                                                                           => 'تم الحل',
            'Low'                                                                                                                                => 'منخفض',
            'Medium'                                                                                                                             => 'متوسط',
            'High'                                                                                                                               => 'عاجل',
            'General'                                                                                                                            => 'عام',
            'General Inquiry'                                                                                                                    => 'استفسار عام',
            'Technical'                                                                                                                          => 'دعم فني',
            'Technical Support'                                                                                                                  => 'دعم فني',
            'Billing'                                                                                                                            => 'حسابات',
            'Billing & Accounts'                                                                                                                 => 'الحسابات والفواتير',
            'Sales'                                                                                                                              => 'مبيعات',
            'Sales Question'                                                                                                                     => 'سؤال مبيعات',
            'Email'                                                                                                                              => 'بريد إلكتروني',
            'Customer Orders'                                                                                                                    => 'طلبات العميل',
            'No recent orders found.'                                                                                                            => 'لا توجد طلبات حديثة.',
            'View Order'                                                                                                                         => 'عرض الطلب',
            'Completed'                                                                                                                          => 'مكتمل',
            'Processing'                                                                                                                         => 'قيد المعالجة',
            'On hold'                                                                                                                            => 'معلق',
            'Pending payment'                                                                                                                    => 'بانتظار الدفع',
            'Cancelled'                                                                                                                          => 'ملغي',
            'Refunded'                                                                                                                           => 'مسترجع',
            'Failed'                                                                                                                             => 'فشل',
            'Request Return'                                                                                                                     => 'طلب إرجاع',
            'Return Request for Order'                                                                                                           => 'طلب إرجاع للطلب',
            'Return Request Already Exists'                                                                                                      => 'طلب الإرجاع موجود بالفعل',
            'You already have an active return request for this order.'                                                                          => 'لديك بالفعل طلب إرجاع نشط لهذا الطلب.',
            'View Ticket'                                                                                                                        => 'عرض التذكرة',
            'Order'                                                                                                                              => 'الطلب',
            'Items Purchased'                                                                                                                    => 'العناصر المشتراة',
            'Agent'                                                                                                                              => 'الموظف',
            'Select File'                                                                                                                        => 'اختيار ملف',
            'No file selected'                                                                                                                   => 'لم يتم اختيار ملف',
            'Max 5MB'                                                                                                                            => 'الحد الأقصى 5 ميجابايت',
            'Name'                                                                                                                               => 'الاسم',
            'Phone Number'                                                                                                                       => 'رقم الهاتف',
            'Upgrade to assign'                                                                                                                  => 'الترقية لتعيين',
            'See order details without leaving this page.'                                                                                       => 'شاهد تفاصيل الطلب دون مغادرة هذه الصفحة.',
            'Unlock Pro Features'                                                                                                                => 'فتح الميزات الاحترافية',
            'Upgrade to Pro'                                                                                                                     => 'ترقية إلى النسخة الاحترافية',
            'Upgrade'                                                                                                                            => 'الترقية',
            'Get SahlDesk Pro'                                                                                                                   => 'احصل على SahlDesk Pro',
            'Unlock all premium features including custom statuses, advanced reporting, and ticket categories.'                                  => 'افتح جميع الميزات المميزة بما في ذلك الحالات المخصصة، التقارير المتقدمة، وأقسام التذاكر.',
            'Upgrade Now'                                                                                                                        => 'الترقية الآن',
            'Category limit reached. The Free plan allows a maximum of 3 categories. Please upgrade to Pro to add more.'                         => 'تم الوصول إلى الحد الأقصى للأقسام. تسمح الخطة المجانية بحد أقصى 3 أقسام. يرجى الترقية إلى النسخة الاحترافية لإضافة المزيد.',
            'How can we help?'                                                                                                                   => 'كيف يمكننا مساعدتك؟',
            'Send Message'                                                                                                                       => 'إرسال رسالة',
            'Choose File'                                                                                                                        => 'اختر ملف',
            'No file chosen'                                                                                                                     => 'لم يتم اختيار ملف',
            'Unlock Your Full Potential'                                                                                                         => 'أطلق العنان لإمكانياتك الكاملة',
            'Upgrade to SahlDesk Pro and get access to powerful features designed to supercharge your customer support.'                         => 'قم بالترقية إلى SahlDesk Pro واحصل على ميزات قوية لتعزيز دعم عملائك.',
            'Billed Monthly'                                                                                                                     => 'الدفع شهرياً',
            'Billed Annually'                                                                                                                    => 'الدفع سنوياً',
            'Settings'                                                                                                                           => 'الإعدادات',
            'Account'                                                                                                                            => 'الحساب',
            'Save 20%'                                                                                                                           => 'وفر 20%',
            'Free'                                                                                                                               => 'مجاني',
            'Essential features to get your support desk running.'                                                                               => 'الميزات الأساسية لبدء تشغيل مكتب الدعم الخاص بك.',
            'mo'                                                                                                                                 => 'شهر',
            'yr'                                                                                                                                 => 'سنة',
            'Current Plan'                                                                                                                       => 'الخطة الحالية',
            'Most Popular'                                                                                                                       => 'الأكثر شعبية',
            'Pro'                                                                                                                                => 'احترافي',
            'Advanced tools for growing teams and businesses.'                                                                                   => 'أدوات متقدمة للفرق والشركات المتنامية.',
            'Unlimited Ticket Categories'                                                                                                        => 'تصنيفات تذاكر غير محدودة',
            'Advanced Custom Statuses'                                                                                                           => 'حالات مخصصة متقدمة',
            'Priority Support'                                                                                                                   => 'دعم فني ذو أولوية',
            'Download Logs'                                                                                                                      => 'تنزيل السجلات',
            'Priority Email Support'                                                                                                             => 'دعم فني عبر البريد الإلكتروني بأولوية',
            'Agent Performance Reports'                                                                                                          => 'تقارير أداء الوكلاء',
            'Remove Freemius Branding'                                                                                                           => 'إزالة علامة Freemius التجارية',
            'Unlimited Tickets'                                                                                                                  => 'تذاكر غير محدودة',
            'Unlimited Agents'                                                                                                                   => 'وكلاء غير محدودين',
            'Basic Dashboard'                                                                                                                    => 'لوحة تحكم أساسية',
            'Email Notifications'                                                                                                                => 'إشعارات عبر البريد الإلكتروني',
            'Please log in on the frontend Support Login page first to authenticate your admin session.'                                         => 'يرجى تسجيل الدخول في صفحة الدعم الفني كمسؤول لمصادقة جلستك.',
            'You are currently logged into the ticketing system frontend as a'                                                                   => 'أنت مسجل حالياً في النظام كـ',
            'You must be an Admin to manage user roles. Please log out and log back in using your Admin email address.'                          => 'يجب أن تكون مشرفاً للوصول. يرجى تسجيل الخروج والعودة كمسؤول.',
            'Your security token has expired. Please log in again to continue.'                                                                  => 'انتهت صلاحية الجلسة. يرجى تسجيل الدخول مجدداً.',
            'Upgrade to the Pro version to save hours of typing with Canned Responses.'                                                          => 'قم بالترقية للإصدار الاحترافي لتوفير الوقت باستخدام الردود الجاهزة.',
            'Add New Response'                                                                                                                   => 'إضافة رد جاهز',
            'Title (Short Name)'                                                                                                                 => 'العنوان (اسم قصير)',
            'Name (Optional)'                                                                                                                    => 'الاسم (اختياري)',
            'Support'                                                                                                                            => 'الدعم الفني',
            'Response Message'                                                                                                                   => 'نص الرد',
            'Message'                                                                                                                            => 'الرسالة',
            'Admin'                                                                                                                              => 'مدير',
            'Agent'                                                                                                                              => 'الموظف',
            'Customer'                                                                                                                           => 'العميل',
            'Existing Responses'                                                                                                                 => 'الردود الحالية',
            'No canned responses found.'                                                                                                         => 'لم يتم العثور على ردود جاهزة.',
            'Are you sure?'                                                                                                                      => 'هل أنت متأكد؟',
            'Upgrade to the Pro version to unlock Custom Sub-Statuses.'                                                                          => 'قم بالترقية للإصدار الاحترافي لتخصيص حالات التذاكر الفرعية.',
            'Sub-Status added.'                                                                                                                  => 'تمت إضافة الحالة الفرعية بنجاح.',
            'Sub-Status updated.'                                                                                                                => 'تم تحديث الحالة الفرعية بنجاح.',
            'Sub-Status deleted.'                                                                                                                => 'تم حذف الحالة الفرعية.',
            'Custom Sub-Statuses'                                                                                                                => 'حالات التذاكر الفرعية المخصصة',
            'Create custom sub-statuses to map onto standard ticket statuses (Open, Pending, Resolved).'                                         => 'قم بإنشاء حالات فرعية مخصصة لربطها بالحالات القياسية للتذكرة.',
            'Add New Sub-Status'                                                                                                                 => 'إضافة حالة فرعية',
            'Parent Status'                                                                                                                      => 'الحالة الأصلية',
            'Sub-Status Name'                                                                                                                    => 'اسم الحالة الفرعية',
            'Badge Color'                                                                                                                        => 'لون الشارة',
            'Add Sub-Status'                                                                                                                     => 'إضافة',
            'Existing Sub-Statuses'                                                                                                              => 'الحالات الفرعية الحالية',
            'No sub-statuses found.'                                                                                                             => 'لم يتم العثور على حالات فرعية.',
        ];
        return ( isset( $dictionary[$text] ) ? $dictionary[$text] : $text );
    }

}
if ( !function_exists( 'ts_add_rtl_styles' ) ) {
    function ts_add_rtl_styles() {
        // Check WordPress Locale
        if ( is_rtl() ) {
            // WordPress has a built-in function for this!
            echo '<style>

            .ts-ticket-container, .ts-dashboard-table, .ts-form { direction: rtl; text-align: right; }

            .ts-sidebar { float: left !important; border-right: none !important; border-left: 1px solid #eee; }

            th, td { text-align: right !important; }

            .ts-message-header { flex-direction: row-reverse; } /* Fix message headers in RTL */

        </style>';
        }
    }

}
add_action( 'wp_head', 'ts_add_rtl_styles' );
add_action( 'admin_head', 'ts_add_rtl_styles' );
add_action( 'admin_init', function () {
    if ( function_exists( 'sahldesk_fs' ) ) {
        sahldesk_fs()->remove_sticky( array('license_activated', 'plan_upgraded') );
    }
} );
if ( !function_exists( 'ts_add_global_admin_styles' ) ) {
    function ts_add_global_admin_styles() {
        echo '<style>
        .ts-card { background: #fff; border: 1px solid #ccd0d4; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); overflow: hidden; display: flex; flex-direction: column; }
        .ts-card-header { padding: 15px 20px; border-bottom: 1px solid #f1f1f1; background: #fafafa; }
        .ts-card-title { margin: 0; font-size: 16px; font-weight: 600; color: #1d2327; }
        .ts-card-body { padding: 20px; flex: 1; }
        .fs-notice[data-id=\\"license_activated\\"], .fs-notice[data-id=\\"plan_upgraded\\"] { display: none !important; }
    </style>';
    }

}
add_action( 'admin_head', 'ts_add_global_admin_styles' );
if ( !function_exists( 'ts_hide_freemius_keys' ) ) {
    function ts_hide_freemius_keys() {
        echo '<style>.fs-field-site_public_key, .fs-field-site_secret_key, .fs-field-site_id { display: none !important; }
    /* Hide annoying Freemius email verification notice */
    .fs-notice[data-id="activation_pending"], .fs-notice.fs-pending-activation, .fs-notice[data-id="opt_in_pending"] { display: none !important; }
    </style>';
        /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
        echo '<script>jQuery(document).ready(function($){ 
        $(".fs-field-site_public_key, .fs-field-site_secret_key, .fs-field-site_id").hide(); 
        /* Attempt to dismiss the notice via JS if it appears */
        $(".fs-notice[data-id=\'activation_pending\']").remove();
    });</script>';
        if ( function_exists( 'sahldesk_fs' ) && sahldesk_fs()->has_active_valid_license() ) {
            echo '<style>.fs-field-version .fs-tag { background-color: #27ae60 !important; color: white !important; border-color: #27ae60 !important; }</style>';
            echo '<script>jQuery(document).ready(function($){ $(".fs-field-version .fs-tag").text("Premium version").css("background-color", "#27ae60").css("color", "white"); });</script>';
        }
    }

}
add_action( 'admin_footer', 'ts_hide_freemius_keys', 999 );
// --- DATE TRANSLATION HELPER ---
if ( !function_exists( 'ts_format_date_localized' ) ) {
    function ts_format_date_localized(  $date_string  ) {
        // Check WordPress Locale
        $locale = get_locale();
        if ( strpos( $locale, 'ar' ) !== 0 ) {
            return $date_string;
        }
        $replacements = [
            'January'   => 'يناير',
            'Feb'       => 'فبراير',
            'February'  => 'فبراير',
            'Mar'       => 'مارس',
            'March'     => 'مارس',
            'Apr'       => 'أبريل',
            'April'     => 'أبريل',
            'May'       => 'مايو',
            'Jun'       => 'يونيو',
            'June'      => 'يونيو',
            'Jul'       => 'يوليو',
            'July'      => 'يوليو',
            'Aug'       => 'أغسطس',
            'August'    => 'أغسطس',
            'Sep'       => 'سبتمبر',
            'September' => 'سبتمبر',
            'Oct'       => 'أكتوبر',
            'October'   => 'أكتوبر',
            'Nov'       => 'نوفمبر',
            'November'  => 'نوفمبر',
            'Dec'       => 'ديسمبر',
            'December'  => 'ديسمبر',
            'Jan'       => 'يناير',
            'AM'        => 'ص',
            'PM'        => 'م',
            'am'        => 'ص',
            'pm'        => 'م',
        ];
        return str_replace( array_keys( $replacements ), array_values( $replacements ), $date_string );
    }

}
// 8. USER ROLE ADMIN PAGE
// =================================================================
if ( !function_exists( 'ts_render_user_management_page' ) ) {
    function ts_render_user_management_page() {
        if ( !defined( 'TS_IS_PRO' ) || !TS_IS_PRO ) {
            echo '<div class="wrap"><div style="text-align:center; padding:50px; background:#fff; border-radius:8px; border:1px solid #ddd; margin-top:20px;">';
            echo '<div style="font-size:48px; margin-bottom:20px;">⭐</div>';
            /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
            echo '<h2>' . esc_html( ts_t( 'This is a Pro feature' ) ) . '</h2>';
            /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
            echo '<p style=\\"font-size:16px; color:#666;\\">' . esc_html( ts_t( 'Upgrade to the Pro version to unlock User Role Management and assign custom permissions to your team.' ) ) . '</p>';
            echo '<a href="' . esc_url( admin_url( 'admin.php?page=ts-custom-upgrade' ) ) . '" class="button button-primary button-large" style="margin-top:15px;">' . esc_html( ts_t( 'Upgrade to Pro' ) ) . '</a>';
            echo '</div></div>';
            return;
        }
        // <fs_premium_only>
        if ( !current_user_can( 'manage_options' ) ) {
            $is_arabic = strpos( get_locale(), 'ar' ) === 0;
            $error_msg = ( $is_arabic ? 'عذراً، غير مسموح لك بالوصول إلى هذه الصفحة.' : 'Sorry, you are not allowed to access this page.' );
            $error_title = ( $is_arabic ? 'رفض الوصول' : 'Access Denied' );
            /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
            wp_die( $error_msg, $error_title );
        }
        $api_key = get_option( 'ts_tenant_api_key' );
        if ( empty( $api_key ) ) {
            /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
            echo '<div class="wrap"><h3>' . esc_html( ts_t( 'Error' ) ) . '</h3><p>' . ts_t( 'API Key missing.' ) . '</p></div>';
            return;
        }
        $token = ( isset( $_SESSION['ts_auth_token'] ) ? sanitize_text_field( wp_unslash( $_SESSION['ts_auth_token'] ) ) : '' );
        $saas_role = ( isset( $_SESSION['ts_user_role'] ) ? sanitize_text_field( wp_unslash( $_SESSION['ts_user_role'] ) ) : 'Customer' );
        $is_arabic = strpos( get_locale(), 'ar' ) === 0;
        $title = ts_t( 'User Management' );
        if ( empty( $token ) ) {
            $req_auth = ( $is_arabic ? 'مطلوب تسجيل الدخول' : 'Authentication Required' );
            $req_auth_desc = ( $is_arabic ? 'يرجى تسجيل الدخول باستخدام حساب المشرف الخاص بك على صفحة تسجيل الدخول للوصول إلى هذه الميزة.' : 'Please log in with your admin account on the front-end login page to access this feature.' );
            $login_btn = ( $is_arabic ? 'تسجيل الدخول الآن' : 'Log In Now' );
            ?>
        <div class="wrap">
            <h1 style="font-family: 'Cairo', sans-serif; font-weight: 700; margin-bottom: 20px;"><?php 
            echo esc_html( $title );
            ?></h1>
            <div style="max-width: 500px; margin: 50px auto; background: #ffffff; border-radius: 16px; padding: 40px; text-align: center; border: 1px solid #e2e8f0; box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.05);">
                <div style="background: rgba(239, 68, 68, 0.08); color: #ef4444; width: 64px; height: 64px; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 20px;">
                    <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-lock"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
                </div>
                <h3 style="font-family: <?php 
            echo esc_html( ( $is_arabic ? "'Cairo'" : "'Inter'" ) );
            ?>, sans-serif; font-size: 20px; font-weight: 700; color: #0f172a; margin-top: 0; margin-bottom: 12px;"><?php 
            echo esc_html( $req_auth );
            ?></h3>
                <p style="font-family: <?php 
            echo esc_html( ( $is_arabic ? "'Cairo'" : "'Inter'" ) );
            ?>, sans-serif; font-size: 14px; color: #64748b; line-height: 1.6; margin-bottom: 24px;"><?php 
            echo esc_html( $req_auth_desc );
            ?></p>
                <a href="<?php 
            echo esc_url( ts_get_page_url( ( $is_arabic ? 'support-login-ar' : 'support-login' ), ( $is_arabic ? '[ticketing_system_login]' : 'Support Login' ) ) );
            ?>" target="_blank" class="button button-primary" style="background: #2563eb; border-color: #2563eb; padding: 6px 20px; font-size: 14px; font-weight: 600; border-radius: 8px; font-family: <?php 
            echo esc_html( ( $is_arabic ? "'Cairo'" : "'Inter'" ) );
            ?>, sans-serif; height: auto; line-height: 2;">
                    <?php 
            echo esc_html( $login_btn );
            ?>
                </a>
            </div>
        </div>
        <?php 
            return;
        }
        if ( $saas_role !== 'Admin' ) {
            echo '<div class="wrap"><h1 class="wp-heading-inline">' . ts_t( 'User Management' ) . '</h1><div class="notice notice-error"><p><strong>' . ts_t( 'Access Denied:' ) . '</strong> ' . ts_t( 'You are currently logged into the ticketing system frontend as a' ) . ' <strong>' . esc_html( ts_t( $saas_role ) ) . '</strong>. ' . ts_t( 'You must be an Admin to manage user roles. Please log out and log back in using your Admin email address.' ) . '</p></div></div>';
            return;
        }
        $api_url = TS_API_BASE_URL . '/users';
        $args = [
            'method'      => 'GET',
            'headers'     => [
                'Authorization' => 'Bearer ' . $token,
                'X-Api-Key'     => $api_key,
            ],
            'data_format' => 'body',
            'timeout'     => 15,
        ];
        $response = wp_remote_get( $api_url, $args );
        /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
        echo '<div class="wrap"><h1 class="wp-heading-inline">' . ts_t( 'User Management' ) . '</h1><hr class="wp-header-end">';
        settings_errors( 'ts_user_roles' );
        if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) != 200 ) {
            $err = ( is_wp_error( $response ) ? $response->get_error_message() : wp_remote_retrieve_body( $response ) );
            $code = ( is_wp_error( $response ) ? 'cURL' : wp_remote_retrieve_response_code( $response ) );
            if ( $code == 401 || $code == 403 ) {
                unset($_SESSION['ts_auth_token']);
                unset($_SESSION['ts_user_role']);
                echo '<script>window.location.reload();</script>';
                return;
            }
            echo '<div class="notice notice-error"><p>' . ts_t( 'Error loading users (HTTP' ) . ' ' . esc_html( $code ) . '): ' . $err . '</p></div>';
        } else {
            $users = json_decode( wp_remote_retrieve_body( $response ), true );
            echo '<div class="ts-card" style="margin-top: 20px;">';
            /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
            echo '<div class="ts-card-header"><h2 class="ts-card-title">' . ts_t( 'User Roles' ) . '</h2></div>';
            echo '<div class="ts-card-body" style="padding: 0;">';
            if ( empty( $users ) ) {
                /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
                echo '<p style="padding: 20px;">' . ts_t( 'No users found.' ) . '</p>';
            } else {
                ?>
            <div style="overflow-x: auto;">
            <table class="wp-list-table widefat striped" style="border: 0; box-shadow: none;">
                <thead><tr><th><?php 
                echo esc_html( ts_t( 'Name' ) );
                ?></th><th><?php 
                echo esc_html( ts_t( 'Email' ) );
                ?></th><th><?php 
                echo esc_html( ts_t( 'Role' ) );
                ?></th><th><?php 
                echo esc_html( ts_t( 'Manage' ) );
                ?></th></tr></thead>
                <tbody><?php 
                foreach ( $users as $user ) {
                    ?>
                    <tr>
                        <td style="vertical-align: middle; font-weight:600;"><?php 
                    echo esc_html( $user['name'] );
                    ?></td>
                        <td style="vertical-align: middle; color:#666;"><?php 
                    echo esc_html( $user['email'] );
                    ?></td>
                        <td style="vertical-align: middle;">
                            <?php 
                    $role_badge_style = '';
                    if ( $user['role'] === 'Admin' ) {
                        $role_badge_style = 'background: #d1fae5; color: #065f46; border: 1px solid #10b981;';
                    } else {
                        if ( $user['role'] === 'Agent' ) {
                            $role_badge_style = 'background: #e0f2fe; color: #0369a1; border: 1px solid #0ea5e9;';
                        } else {
                            $role_badge_style = 'background: #f3f4f6; color: #374151; border: 1px solid #d1d5db;';
                        }
                    }
                    ?>
                            <span style="display: inline-block; padding: 4px 10px; border-radius: 12px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; <?php 
                    echo esc_attr( $role_badge_style );
                    ?>"><?php 
                    echo esc_html( ts_t( $user['role'] ) );
                    ?></span>
                        </td>
                        <td style="vertical-align: middle;">
                             <form method="post" action="" style="display: flex; gap: 8px; align-items: center; margin: 0; flex-wrap: wrap;">
                                <?php 
                    wp_nonce_field( 'ts_manage_user_action', 'nonce_manage_user' );
                    ?>
                                <input type="hidden" name="user_id" value="<?php 
                    echo esc_attr( $user['id'] );
                    ?>">
                                <select name="new_role" style="height:32px; flex: 1; min-width: 100px; border-radius: 4px; border: 1px solid #ddd;">
                                    <option value="Customer" <?php 
                    selected( $user['role'], 'Customer' );
                    ?>><?php 
                    echo esc_html( ts_t( 'Customer' ) );
                    ?></option>
                                    <option value="Agent" <?php 
                    selected( $user['role'], 'Agent' );
                    ?>><?php 
                    echo esc_html( ts_t( 'Agent' ) );
                    ?></option>
                                    <option value="Admin" <?php 
                    selected( $user['role'], 'Admin' );
                    ?>><?php 
                    echo esc_html( ts_t( 'Admin' ) );
                    ?></option>
                                </select>
                                <button type="submit" name="submit_change_role" class="button button-primary" style="height: 32px; line-height: 30px; padding: 0 12px; white-space: nowrap;"><?php 
                    echo esc_html( ts_t( 'Update' ) );
                    ?></button>
                            </form>
                        </td>
                    </tr>
                <?php 
                }
                ?></tbody>
            </table>
            </div>
        <?php 
            }
            echo '</div></div>';
        }
        echo '</div>';
        // </fs_premium_only>
    }

}
// <fs_premium_only>
if ( !function_exists( 'ts_handle_admin_page_submissions' ) ) {
    function ts_handle_admin_page_submissions() {
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_POST['submit_change_role'] ) ) {
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            if ( !isset( $_POST['nonce_manage_user'] ) || !wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce_manage_user'] ) ), 'ts_manage_user_action' ) ) {
                return;
            }
            $api_key = get_option( 'ts_tenant_api_key' );
            $token = ( isset( $_SESSION['ts_auth_token'] ) ? sanitize_text_field( wp_unslash( $_SESSION['ts_auth_token'] ) ) : '' );
            if ( empty( $token ) ) {
                add_settings_error(
                    'ts_user_roles',
                    'error',
                    'Authentication required. Please log in.',
                    'error'
                );
                return;
            }
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $user_id = intval( sanitize_text_field( wp_unslash( $_POST['user_id'] ) ) );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $new_role = sanitize_text_field( wp_unslash( $_POST['new_role'] ) );
            $api_url = TS_API_BASE_URL . '/users/' . $user_id . '/role';
            $body = [
                'role' => $new_role,
            ];
            $args = [
                'method'      => 'PUT',
                'headers'     => [
                    'Content-Type'  => 'application/json',
                    'Authorization' => 'Bearer ' . $token,
                    'X-Api-Key'     => $api_key,
                ],
                'body'        => json_encode( $body ),
                'data_format' => 'body',
                'timeout'     => 15,
            ];
            $response = wp_remote_request( $api_url, $args );
            if ( wp_remote_retrieve_response_code( $response ) == 204 ) {
                add_settings_error(
                    'ts_user_roles',
                    'success',
                    'Role updated.',
                    'success'
                );
            } else {
                add_settings_error(
                    'ts_user_roles',
                    'error',
                    'Failed to update role.',
                    'error'
                );
            }
        }
    }

}
add_action( 'admin_init', 'ts_handle_admin_page_submissions' );
// </fs_premium_only>
// 9. CANNED RESPONSES ADMIN PAGE (FIXED DISPLAY)
// =================================================================
if ( !function_exists( 'ts_render_canned_responses_page' ) ) {
    function ts_render_canned_responses_page() {
        if ( !defined( 'TS_IS_PRO' ) || !TS_IS_PRO ) {
            echo '<div class="wrap"><div style="text-align:center; padding:50px; background:#fff; border-radius:8px; border:1px solid #ddd; margin-top:20px;">';
            echo '<div style="font-size:48px; margin-bottom:20px;">⭐</div>';
            /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
            echo '<h2>' . esc_html( ts_t( 'This is a Pro feature' ) ) . '</h2>';
            /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
            echo '<p style=\\"font-size:16px; color:#666;\\">' . esc_html( ts_t( 'Upgrade to the Pro version to save hours of typing with Canned Responses.' ) ) . '</p>';
            echo '<a href="' . esc_url( admin_url( 'admin.php?page=ts-custom-upgrade' ) ) . '" class="button button-primary button-large" style="margin-top:15px;">' . esc_html( ts_t( 'Upgrade to Pro' ) ) . '</a>';
            echo '</div></div>';
            return;
        }
        // <fs_premium_only>
        if ( !current_user_can( 'manage_options' ) ) {
            $is_arabic = strpos( get_locale(), 'ar' ) === 0;
            $error_msg = ( $is_arabic ? 'عذراً، غير مسموح لك بالوصول إلى هذه الصفحة.' : 'Sorry, you are not allowed to access this page.' );
            $error_title = ( $is_arabic ? 'رفض الوصول' : 'Access Denied' );
            /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
            wp_die( $error_msg, $error_title );
        }
        $api_key = get_option( 'ts_tenant_api_key' );
        $token = ( isset( $_SESSION['ts_auth_token'] ) ? sanitize_text_field( wp_unslash( $_SESSION['ts_auth_token'] ) ) : '' );
        if ( empty( $api_key ) ) {
            /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
            echo '<div class="wrap"><h3>' . esc_html( ts_t( 'Error' ) ) . '</h3><p>' . esc_html( ts_t( 'API Key missing in settings.' ) ) . '</p></div>';
            return;
        }
        $is_arabic = strpos( get_locale(), 'ar' ) === 0;
        $title = ts_t( 'Canned Responses' );
        if ( empty( $token ) ) {
            $req_auth = ( $is_arabic ? 'مطلوب تسجيل الدخول' : 'Authentication Required' );
            $req_auth_desc = ( $is_arabic ? 'يرجى تسجيل الدخول باستخدام حساب المشرف الخاص بك على صفحة تسجيل الدخول للوصول إلى هذه الميزة.' : 'Please log in with your admin account on the front-end login page to access this feature.' );
            $login_btn = ( $is_arabic ? 'تسجيل الدخول الآن' : 'Log In Now' );
            ?>
        <div class="wrap">
            <h1 style="font-family: 'Cairo', sans-serif; font-weight: 700; margin-bottom: 20px;"><?php 
            echo esc_html( $title );
            ?></h1>
            <div style="max-width: 500px; margin: 50px auto; background: #ffffff; border-radius: 16px; padding: 40px; text-align: center; border: 1px solid #e2e8f0; box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.05);">
                <div style="background: rgba(239, 68, 68, 0.08); color: #ef4444; width: 64px; height: 64px; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 20px;">
                    <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-lock"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
                </div>
                <h3 style="font-family: <?php 
            echo esc_html( ( $is_arabic ? "'Cairo'" : "'Inter'" ) );
            ?>, sans-serif; font-size: 20px; font-weight: 700; color: #0f172a; margin-top: 0; margin-bottom: 12px;"><?php 
            echo esc_html( $req_auth );
            ?></h3>
                <p style="font-family: <?php 
            echo esc_html( ( $is_arabic ? "'Cairo'" : "'Inter'" ) );
            ?>, sans-serif; font-size: 14px; color: #64748b; line-height: 1.6; margin-bottom: 24px;"><?php 
            echo esc_html( $req_auth_desc );
            ?></p>
                <a href="<?php 
            echo esc_url( ts_get_page_url( ( $is_arabic ? 'support-login-ar' : 'support-login' ), ( $is_arabic ? '[ticketing_system_login]' : 'Support Login' ) ) );
            ?>" target="_blank" class="button button-primary" style="background: #2563eb; border-color: #2563eb; padding: 6px 20px; font-size: 14px; font-weight: 600; border-radius: 8px; font-family: <?php 
            echo esc_html( ( $is_arabic ? "'Cairo'" : "'Inter'" ) );
            ?>, sans-serif; height: auto; line-height: 2;">
                    <?php 
            echo esc_html( $login_btn );
            ?>
                </a>
            </div>
        </div>
        <?php 
            return;
        }
        $api_url = TS_API_BASE_URL . '/cannedresponses';
        $args = [
            'method'      => 'GET',
            'headers'     => [
                'Authorization' => 'Bearer ' . $token,
                'X-Api-Key'     => $api_key,
            ],
            'data_format' => 'body',
        ];
        $response = wp_remote_get( $api_url, $args );
        $canned_responses = [];
        if ( !is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) == 200 ) {
            $canned_responses = json_decode( wp_remote_retrieve_body( $response ), true );
        }
        ?>
    <div class="wrap">
        <h1 class="wp-heading-inline"><?php 
        echo esc_html( ts_t( 'Canned Responses' ) );
        ?></h1>
        <hr class="wp-header-end">
        <?php 
        settings_errors( 'ts_canned_responses' );
        ?>

        <div style="display:flex; gap:20px; flex-wrap:wrap; margin-top:20px;">
            <div class="ts-card" style="flex: 1; min-width: 300px;">
                <div class="ts-card-header"><h2 class="ts-card-title"><?php 
        echo esc_html( ts_t( 'Add New Response' ) );
        ?></h2></div>
                <div class="ts-card-body">
                    <form method="post" action="">
                        <?php 
        wp_nonce_field( 'ts_add_canned_action', 'ts_canned_nonce' );
        ?>
                        <p>
                            <label for="cr_title" style="font-weight:600;"><?php 
        echo esc_html( ts_t( 'Title (Short Name)' ) );
        ?></label><br>
                            <input type="text" name="cr_title" id="cr_title" class="regular-text" style="width:100%; border-radius: 4px; border: 1px solid #ccc; padding: 6px 10px;" required>
                        </p>
                        <p>
                            <label for="cr_message" style="font-weight:600;"><?php 
        echo esc_html( ts_t( 'Response Message' ) );
        ?></label><br>
                            <textarea name="cr_message" id="cr_message" rows="8" style="width:100%; border-radius: 4px; border: 1px solid #ccc; padding: 10px;" required></textarea>
                        </p>
                        <p class="submit" style="margin-bottom:0; padding-bottom:0;">
                            <input type="submit" name="submit_add_canned" id="submit" class="button button-primary" value="<?php 
        echo esc_html( ts_t( 'Add New Response' ) );
        ?>">
                        </p>
                    </form>
                </div>
            </div>

            <div class="ts-card" style="flex: 2; min-width: 400px;">
                <div class="ts-card-header"><h2 class="ts-card-title"><?php 
        echo esc_html( ts_t( 'Existing Responses' ) );
        ?></h2></div>
                <div class="ts-card-body" style="padding: 0;">
                    <table class="wp-list-table widefat fixed striped" style="border:0; box-shadow:none;">
                        <thead>
                            <tr>
                                <th style="width: 25%; font-weight: 600; border-bottom: 2px solid #f1f1f1;"><?php 
        echo esc_html( ts_t( 'Title' ) );
        ?></th>
                                <th style="font-weight: 600; border-bottom: 2px solid #f1f1f1;"><?php 
        echo esc_html( ts_t( 'Message' ) );
        ?></th>
                                <th style="width: 80px; font-weight: 600; border-bottom: 2px solid #f1f1f1;"><?php 
        echo esc_html( ts_t( 'Action' ) );
        ?></th>
                            </tr>
                        </thead>
                        <tbody>
                            <?php 
        if ( empty( $canned_responses ) ) {
            ?>
                                <tr><td colspan="3" style="padding: 20px; color: #666;"><?php 
            echo esc_html( ts_t( 'No canned responses found.' ) );
            ?></td></tr>
                            <?php 
        } else {
            ?>
                                <?php 
            foreach ( $canned_responses as $cr ) {
                $cr_content = ( isset( $cr['content'] ) ? $cr['content'] : (( isset( $cr['Content'] ) ? $cr['Content'] : (( isset( $cr['message'] ) ? $cr['message'] : '' )) )) );
                ?>
                                    <tr>
                                        <td style="font-weight:700; color:#1d2327; vertical-align:middle;"><?php 
                echo esc_html( $cr['title'] );
                ?></td>
                                        <td style="vertical-align:middle; color:#50575e;"><?php 
                echo nl2br( esc_html( $cr_content ) );
                ?></td>
                                        <td style="vertical-align:middle;">
                                            <form method="post" action="" onsubmit="return confirm('<?php 
                /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
                echo esc_js( ts_t( 'Are you sure?' ) );
                ?>');" style="margin:0;">
                                                <?php 
                wp_nonce_field( 'ts_delete_canned_action', 'ts_delete_nonce' );
                ?>
                                                <input type="hidden" name="delete_id" value="<?php 
                echo esc_attr( $cr['id'] );
                ?>">
                                                <button type="submit" name="submit_delete_canned" class="button" style="color:#b32d2e; border-color:#b32d2e; font-weight:600; border-radius: 4px;"><?php 
                echo esc_html( ts_t( 'Delete' ) );
                ?></button>
                                            </form>
                                        </td>
                                    </tr>
                                <?php 
            }
            ?>
                            <?php 
        }
        ?>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
    <?php 
        // </fs_premium_only>
    }

}
// 9.6 SUB-STATUSES ADMIN PAGE (NEW)
// =================================================================
if ( !function_exists( 'ts_render_sub_statuses_page' ) ) {
    function ts_render_sub_statuses_page() {
        if ( !defined( 'TS_IS_PRO' ) || !TS_IS_PRO ) {
            echo '<div class="wrap"><div style="text-align:center; padding:50px; background:#fff; border-radius:8px; border:1px solid #ddd; margin-top:20px;">';
            echo '<div style="font-size:48px; margin-bottom:20px;">⭐</div>';
            /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
            echo '<h2>' . esc_html( ts_t( 'This is a Pro feature' ) ) . '</h2>';
            /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
            echo '<p style=\\"font-size:16px; color:#666;\\">' . esc_html( ts_t( 'Upgrade to the Pro version to unlock Custom Sub-Statuses.' ) ) . '</p>';
            echo '<a href="' . esc_url( admin_url( 'admin.php?page=ts-custom-upgrade' ) ) . '" class="button button-primary button-large" style="margin-top:15px;">' . esc_html( ts_t( 'Upgrade to Pro' ) ) . '</a>';
            echo '</div></div>';
            return;
        }
        // <fs_premium_only>
        if ( !current_user_can( 'manage_options' ) ) {
            $is_arabic = strpos( get_locale(), 'ar' ) === 0;
            $error_msg = ( $is_arabic ? 'عذراً، غير مسموح لك بالوصول إلى هذه الصفحة.' : 'Sorry, you are not allowed to access this page.' );
            $error_title = ( $is_arabic ? 'رفض الوصول' : 'Access Denied' );
            /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
            wp_die( $error_msg, $error_title );
        }
        $api_key = get_option( 'ts_tenant_api_key' );
        $token = ( isset( $_SESSION['ts_auth_token'] ) ? sanitize_text_field( wp_unslash( $_SESSION['ts_auth_token'] ) ) : '' );
        if ( empty( $api_key ) ) {
            /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
            echo '<div class="wrap"><h3>' . esc_html( ts_t( 'Error' ) ) . '</h3><p>' . esc_html( ts_t( 'API Key missing in settings.' ) ) . '</p></div>';
            return;
        }
        $is_arabic = strpos( get_locale(), 'ar' ) === 0;
        $title = ts_t( 'Ticket Sub-Statuses' );
        if ( empty( $token ) ) {
            $req_auth = ( $is_arabic ? 'مطلوب تسجيل الدخول' : 'Authentication Required' );
            $req_auth_desc = ( $is_arabic ? 'يرجى تسجيل الدخول باستخدام حساب المشرف الخاص بك على صفحة تسجيل الدخول للوصول إلى هذه الميزة.' : 'Please log in with your admin account on the front-end login page to access this feature.' );
            $login_btn = ( $is_arabic ? 'تسجيل الدخول الآن' : 'Log In Now' );
            ?>
        <div class="wrap">
            <h1 style="font-family: 'Cairo', sans-serif; font-weight: 700; margin-bottom: 20px;"><?php 
            echo esc_html( $title );
            ?></h1>
            <div style="max-width: 500px; margin: 50px auto; background: #ffffff; border-radius: 16px; padding: 40px; text-align: center; border: 1px solid #e2e8f0; box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.05);">
                <div style="background: rgba(239, 68, 68, 0.08); color: #ef4444; width: 64px; height: 64px; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 20px;">
                    <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-lock"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
                </div>
                <h3 style="font-family: <?php 
            echo esc_html( ( $is_arabic ? "'Cairo'" : "'Inter'" ) );
            ?>, sans-serif; font-size: 20px; font-weight: 700; color: #0f172a; margin-top: 0; margin-bottom: 12px;"><?php 
            echo esc_html( $req_auth );
            ?></h3>
                <p style="font-family: <?php 
            echo esc_html( ( $is_arabic ? "'Cairo'" : "'Inter'" ) );
            ?>, sans-serif; font-size: 14px; color: #64748b; line-height: 1.6; margin-bottom: 24px;"><?php 
            echo esc_html( $req_auth_desc );
            ?></p>
                <a href="<?php 
            echo esc_url( ts_get_page_url( ( $is_arabic ? 'support-login-ar' : 'support-login' ), ( $is_arabic ? '[ticketing_system_login]' : 'Support Login' ) ) );
            ?>" target="_blank" class="button button-primary" style="background: #2563eb; border-color: #2563eb; padding: 6px 20px; font-size: 14px; font-weight: 600; border-radius: 8px; font-family: <?php 
            echo esc_html( ( $is_arabic ? "'Cairo'" : "'Inter'" ) );
            ?>, sans-serif; height: auto; line-height: 2;">
                    <?php 
            echo esc_html( $login_btn );
            ?>
                </a>
            </div>
        </div>
        <?php 
            return;
        }
        // Handle Add
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_POST['submit_add_sub_status'] ) ) {
            check_admin_referer( 'ts_add_sub_status_action' );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $name = sanitize_text_field( wp_unslash( ( isset( $_POST['sub_status_name'] ) ? $_POST['sub_status_name'] : '' ) ) );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $color = sanitize_hex_color( sanitize_text_field( wp_unslash( ( isset( $_POST['sub_status_color'] ) ? $_POST['sub_status_color'] : '' ) ) ) );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $parent_status = sanitize_text_field( wp_unslash( $_POST['sub_status_parent'] ) );
            wp_remote_post( TS_API_BASE_URL . '/ticketsubstatuses', [
                'headers'     => [
                    'Content-Type'  => 'application/json',
                    'Authorization' => 'Bearer ' . $token,
                    'X-Api-Key'     => $api_key,
                ],
                'body'        => json_encode( [
                    'name'         => $name,
                    'color'        => $color,
                    'parentStatus' => $parent_status,
                ] ),
                'data_format' => 'body',
            ] );
            /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
            echo '<div class="notice notice-success"><p>' . esc_html( ts_t( 'Sub-Status added.' ) ) . '</p></div>';
        }
        // Handle Update
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_POST['submit_update_sub_status'] ) ) {
            check_admin_referer( 'ts_update_sub_status_action' );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $id = intval( sanitize_text_field( wp_unslash( $_POST['sub_status_id'] ) ) );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $name = sanitize_text_field( wp_unslash( ( isset( $_POST['sub_status_name'] ) ? $_POST['sub_status_name'] : '' ) ) );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $color = sanitize_hex_color( sanitize_text_field( wp_unslash( ( isset( $_POST['sub_status_color'] ) ? $_POST['sub_status_color'] : '' ) ) ) );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $parent_status = sanitize_text_field( wp_unslash( $_POST['sub_status_parent'] ) );
            wp_remote_request( TS_API_BASE_URL . '/ticketsubstatuses/' . $id, [
                'method'      => 'PUT',
                'headers'     => [
                    'Content-Type'  => 'application/json',
                    'Authorization' => 'Bearer ' . $token,
                    'X-Api-Key'     => $api_key,
                ],
                'body'        => json_encode( [
                    'id'           => $id,
                    'name'         => $name,
                    'color'        => $color,
                    'parentStatus' => $parent_status,
                ] ),
                'data_format' => 'body',
            ] );
            /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
            echo '<div class="notice notice-success"><p>' . esc_html( ts_t( 'Sub-Status updated.' ) ) . '</p></div>';
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            unset($_GET['edit_id']);
            echo '<script>window.history.replaceState({}, document.title, "' . esc_url_raw( remove_query_arg( 'edit_id' ) ) . '");</script>';
        }
        // Handle Delete
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_POST['submit_delete_sub_status'] ) ) {
            check_admin_referer( 'ts_delete_sub_status_action' );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $id = intval( sanitize_text_field( wp_unslash( $_POST['delete_id'] ) ) );
            wp_remote_request( TS_API_BASE_URL . '/ticketsubstatuses/' . $id, [
                'method'      => 'DELETE',
                'headers'     => [
                    'Authorization' => 'Bearer ' . $token,
                    'X-Api-Key'     => $api_key,
                ],
                'data_format' => 'body',
            ] );
            /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
            echo '<div class="notice notice-success"><p>' . esc_html( ts_t( 'Sub-Status deleted.' ) ) . '</p></div>';
        }
        // Fetch Sub-Statuses
        $response = wp_remote_get( TS_API_BASE_URL . '/ticketsubstatuses', [
            'headers'     => [
                'Authorization' => 'Bearer ' . $token,
                'X-Api-Key'     => $api_key,
            ],
            'data_format' => 'body',
        ] );
        $sub_statuses = [];
        if ( !is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) == 200 ) {
            $sub_statuses = json_decode( wp_remote_retrieve_body( $response ), true );
        }
        // Determine Edit Mode
        $edit_sub = null;
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_GET['edit_id'] ) ) {
            foreach ( $sub_statuses as $s ) {
                // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
                if ( $s['id'] == sanitize_text_field( wp_unslash( $_GET['edit_id'] ) ) ) {
                    $edit_sub = $s;
                    break;
                }
            }
        }
        ?>
    <div class="wrap">
        <h1 class="wp-heading-inline"><?php 
        echo esc_html( ts_t( 'Custom Sub-Statuses' ) );
        ?></h1>
        <hr class="wp-header-end">
        <p style="color: #646970; font-size: 14px;"><?php 
        echo esc_html( ts_t( 'Create custom sub-statuses to map onto standard ticket statuses (Open, Pending, Resolved).' ) );
        ?></p>
        
        <div style="display:flex; gap:20px; flex-wrap:wrap; margin-top:20px;">
            <!-- ADD/EDIT NEW FORM -->
            <div class="ts-card" style="flex: 1; min-width: 300px;">
                <div class="ts-card-header"><h2 class="ts-card-title"><?php 
        echo esc_html( ( $edit_sub ? ts_t( 'Edit Sub-Status' ) : ts_t( 'Add New Sub-Status' ) ) );
        ?></h2></div>
                <div class="ts-card-body">
                    <form method="post" action="">
                        <?php 
        if ( $edit_sub ) {
            ?>
                            <?php 
            wp_nonce_field( 'ts_update_sub_status_action' );
            ?>
                            <input type="hidden" name="sub_status_id" value="<?php 
            echo esc_attr( $edit_sub['id'] );
            ?>">
                        <?php 
        } else {
            ?>
                            <?php 
            wp_nonce_field( 'ts_add_sub_status_action' );
            ?>
                        <?php 
        }
        ?>
                        
                        <p>
                            <label for="sub_status_parent" style="font-weight:600;"><?php 
        echo esc_html( ts_t( 'Parent Status' ) );
        ?></label><br>
                            <select name="sub_status_parent" id="sub_status_parent" style="width:100%; border-radius: 4px; border: 1px solid #ccc; padding: 6px 10px;" required>
                                <option value="Open" <?php 
        if ( $edit_sub ) {
            selected( $edit_sub['parentStatus'], 'Open' );
        }
        ?>><?php 
        echo esc_html( ts_t( 'Open' ) );
        ?></option>
                                <option value="In Progress" <?php 
        if ( $edit_sub ) {
            selected( $edit_sub['parentStatus'], 'In Progress' );
        }
        ?>><?php 
        echo esc_html( ts_t( 'In Progress' ) );
        ?></option>
                                <option value="Pending" <?php 
        if ( $edit_sub ) {
            selected( $edit_sub['parentStatus'], 'Pending' );
        }
        ?>><?php 
        echo esc_html( ts_t( 'Pending' ) );
        ?></option>
                                <option value="Closed" <?php 
        if ( $edit_sub ) {
            selected( $edit_sub['parentStatus'], 'Closed' );
        }
        ?>><?php 
        echo esc_html( ts_t( 'Closed' ) );
        ?></option>
                                <option value="Resolved" <?php 
        if ( $edit_sub ) {
            selected( $edit_sub['parentStatus'], 'Resolved' );
        }
        ?>><?php 
        echo esc_html( ts_t( 'Resolved' ) );
        ?></option>
                            </select>
                        </p>
                        <p>
                            <label for="sub_status_name" style="font-weight:600;"><?php 
        echo esc_html( ts_t( 'Sub-Status Name' ) );
        ?></label><br>
                            <input type="text" name="sub_status_name" id="sub_status_name" class="regular-text" style="width:100%; border-radius: 4px; border: 1px solid #ccc; padding: 6px 10px;" required placeholder="<?php 
        echo esc_attr( ts_t( 'e.g., Awaiting Customer' ) );
        ?>" value="<?php 
        echo ( $edit_sub ? esc_attr( $edit_sub['name'] ) : '' );
        ?>" oninvalid="this.setCustomValidity('<?php 
        echo esc_js( ts_t( 'Please fill out this field.' ) );
        ?>')" oninput="this.setCustomValidity('')">
                        </p>
                        <p>
                            <label for="sub_status_color" style="font-weight:600;"><?php 
        echo esc_html( ts_t( 'Badge Color' ) );
        ?></label><br>
                            <div style="display: flex; align-items: center; gap: 10px;">
                                <input type="color" name="sub_status_color" id="sub_status_color" value="<?php 
        echo ( $edit_sub && isset( $edit_sub['color'] ) ? esc_attr( $edit_sub['color'] ) : '#0ea5e9' );
        ?>" style="width:50px; height:40px; padding:0; border:1px solid #ccc; border-radius:4px; cursor:pointer;" required>
                                <span style="color: #666; font-size: 13px;"><?php 
        echo esc_html( ts_t( 'Choose a vibrant color' ) );
        ?></span>
                            </div>
                        </p>
                        <p class="submit" style="margin-bottom:0; padding-bottom:0; margin-top: 25px;">
                            <input type="submit" name="<?php 
        echo esc_html( ( $edit_sub ? 'submit_update_sub_status' : 'submit_add_sub_status' ) );
        ?>" id="submit" class="button button-primary" value="<?php 
        echo esc_html( ( $edit_sub ? ts_t( 'Update' ) : ts_t( 'Add Sub-Status' ) ) );
        ?>">
                            <?php 
        if ( $edit_sub ) {
            ?><a href="<?php 
            echo esc_url( remove_query_arg( 'edit_id' ) );
            ?>" class="button"><?php 
            echo esc_html( ts_t( 'Cancel' ) );
            ?></a><?php 
        }
        ?>
                        </p>
                    </form>
                </div>
            </div>

            <!-- EXISTING SUB-STATUSES -->
            <div class="ts-card" style="flex: 2; min-width: 400px;">
                <div class="ts-card-header"><h2 class="ts-card-title"><?php 
        echo esc_html( ts_t( 'Existing Sub-Statuses' ) );
        ?></h2></div>
                <div class="ts-card-body" style="padding: 0;">
                    <table class="wp-list-table widefat fixed striped" style="border:0; box-shadow:none;">
                        <thead>
                            <tr>
                                <th style="font-weight: 600; border-bottom: 2px solid #f1f1f1;"><?php 
        echo esc_html( ts_t( 'Parent Status' ) );
        ?></th>
                                <th style="font-weight: 600; border-bottom: 2px solid #f1f1f1;"><?php 
        echo esc_html( ts_t( 'Sub-Status Name' ) );
        ?></th>
                                <th style="font-weight: 600; border-bottom: 2px solid #f1f1f1;"><?php 
        echo esc_html( ts_t( 'Color' ) );
        ?></th>
                                <th style="width: 150px; font-weight: 600; border-bottom: 2px solid #f1f1f1;"><?php 
        echo esc_html( ts_t( 'Action' ) );
        ?></th>
                            </tr>
                        </thead>
                        <tbody>
                            <?php 
        if ( empty( $sub_statuses ) ) {
            ?>
                                <tr><td colspan="4" style="padding: 20px; color: #666;"><?php 
            echo esc_html( ts_t( 'No sub-statuses found.' ) );
            ?></td></tr>
                            <?php 
        } else {
            ?>
                                <?php 
            foreach ( $sub_statuses as $st ) {
                ?>
                                    <tr>
                                        <td style="vertical-align:middle; font-weight:700; color: #333;"><?php 
                echo esc_html( ts_t( $st['parentStatus'] ) );
                ?></td>
                                        <td style="vertical-align:middle;">
                                            <span style="display:inline-block; padding:4px 12px; border-radius:12px; font-size:12px; font-weight:700; color:#fff; box-shadow: 0 2px 4px rgba(0,0,0,0.1); background:<?php 
                echo esc_attr( $st['color'] );
                ?>;">
                                                <?php 
                echo esc_html( $st['name'] );
                ?>
                                            </span>
                                        </td>
                                        <td style="vertical-align:middle;"><code style="background:none; color: #666;"><?php 
                echo esc_html( $st['color'] );
                ?></code></td>
                                        <td style="vertical-align:middle;">
                                            <div style="display:flex; gap:10px;">
                                                <a href="<?php 
                echo esc_url( add_query_arg( 'edit_id', $st['id'] ) );
                ?>" class="button"><?php 
                echo esc_html( ts_t( 'Edit' ) );
                ?></a>
                                                <form method="post" action="" onsubmit="return confirm('<?php 
                /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
                echo esc_js( ts_t( 'Are you sure?' ) );
                ?>');" style="margin:0;">
                                                    <?php 
                wp_nonce_field( 'ts_delete_sub_status_action' );
                ?>
                                                    <input type="hidden" name="delete_id" value="<?php 
                echo esc_attr( $st['id'] );
                ?>">
                                                    <button type="submit" name="submit_delete_sub_status" class="button" style="color:#b32d2e; border-color:#b32d2e; font-weight: 600; border-radius: 4px;"><?php 
                echo esc_html( ts_t( 'Delete' ) );
                ?></button>
                                                </form>
                                            </div>
                                        </td>
                                    </tr>
                                <?php 
            }
            ?>
                            <?php 
        }
        ?>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
    <?php 
        // </fs_premium_only>
    }

}
// <fs_premium_only>
if ( !function_exists( 'ts_handle_canned_response_submissions' ) ) {
    if ( !function_exists( 'ts_handle_canned_response_submissions' ) ) {
        function ts_handle_canned_response_submissions() {
            // 1. Handle ADD
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            if ( isset( $_POST['submit_add_canned'] ) ) {
                // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
                if ( !isset( $_POST['ts_canned_nonce'] ) || !wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['ts_canned_nonce'] ) ), 'ts_add_canned_action' ) ) {
                    return;
                }
                $api_key = get_option( 'ts_tenant_api_key' );
                $token = ( isset( $_SESSION['ts_auth_token'] ) ? sanitize_text_field( wp_unslash( $_SESSION['ts_auth_token'] ) ) : '' );
                if ( empty( $token ) ) {
                    add_settings_error(
                        'ts_canned_responses',
                        'error',
                        'Authentication required. Please log in.',
                        'error'
                    );
                    return;
                }
                $api_url = TS_API_BASE_URL . '/cannedresponses';
                // FIX: Changed keys to 'Title' and 'Content' to match your API
                $body = [
                    'Title'   => sanitize_text_field( wp_unslash( ( isset( $_POST['cr_title'] ) ? $_POST['cr_title'] : '' ) ) ),
                    'Content' => sanitize_textarea_field( wp_unslash( ( isset( $_POST['cr_message'] ) ? $_POST['cr_message'] : '' ) ) ),
                ];
                $args = [
                    'method'      => 'POST',
                    'headers'     => [
                        'Content-Type'  => 'application/json',
                        'Authorization' => 'Bearer ' . $token,
                        'X-Api-Key'     => $api_key,
                    ],
                    'body'        => json_encode( $body ),
                    'data_format' => 'body',
                ];
                $response = wp_remote_post( $api_url, $args );
                $code = wp_remote_retrieve_response_code( $response );
                if ( $code == 200 || $code == 201 ) {
                    add_settings_error(
                        'ts_canned_responses',
                        'success',
                        'Response added successfully.',
                        'success'
                    );
                } else {
                    // Keep the error visible just in case
                    $error_body = wp_remote_retrieve_body( $response );
                    add_settings_error(
                        'ts_canned_responses',
                        'error',
                        "Error ({$code}): " . esc_html( substr( $error_body, 0, 200 ) ),
                        'error'
                    );
                }
            }
            // 2. Handle DELETE
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            if ( isset( $_POST['submit_delete_canned'] ) ) {
                // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
                if ( !isset( $_POST['ts_delete_nonce'] ) || !wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['ts_delete_nonce'] ) ), 'ts_delete_canned_action' ) ) {
                    return;
                }
                $api_key = get_option( 'ts_tenant_api_key' );
                $token = ( isset( $_SESSION['ts_auth_token'] ) ? sanitize_text_field( wp_unslash( $_SESSION['ts_auth_token'] ) ) : '' );
                if ( empty( $token ) ) {
                    add_settings_error(
                        'ts_canned_responses',
                        'error',
                        'Authentication required. Please log in.',
                        'error'
                    );
                    return;
                }
                // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
                $delete_id = intval( sanitize_text_field( wp_unslash( $_POST['delete_id'] ) ) );
                $api_url = TS_API_BASE_URL . '/cannedresponses/' . $delete_id;
                $args = [
                    'method'      => 'DELETE',
                    'headers'     => [
                        'Authorization' => 'Bearer ' . $token,
                        'X-Api-Key'     => $api_key,
                    ],
                    'data_format' => 'body',
                ];
                $response = wp_remote_request( $api_url, $args );
                $code = wp_remote_retrieve_response_code( $response );
                if ( $code == 200 || $code == 204 ) {
                    add_settings_error(
                        'ts_canned_responses',
                        'success',
                        'Response deleted.',
                        'success'
                    );
                } else {
                    add_settings_error(
                        'ts_canned_responses',
                        'error',
                        "Delete Failed (Code: {$code}).",
                        'error'
                    );
                }
            }
        }

    }
}
add_action( 'admin_init', 'ts_handle_canned_response_submissions' );
// </fs_premium_only>
// 9.5 CATEGORIES ADMIN PAGE (NEW)
// =================================================================
if ( !function_exists( 'ts_render_categories_page' ) ) {
    function ts_render_categories_page() {
        if ( !current_user_can( 'manage_options' ) ) {
            $is_arabic = strpos( get_locale(), 'ar' ) === 0;
            $error_msg = ( $is_arabic ? 'عذراً، غير مسموح لك بالوصول إلى هذه الصفحة.' : 'Sorry, you are not allowed to access this page.' );
            $error_title = ( $is_arabic ? 'رفض الوصول' : 'Access Denied' );
            /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
            wp_die( $error_msg, $error_title );
        }
        $api_key = get_option( 'ts_tenant_api_key' );
        $token = ( isset( $_SESSION['ts_auth_token'] ) ? sanitize_text_field( wp_unslash( $_SESSION['ts_auth_token'] ) ) : '' );
        if ( empty( $api_key ) ) {
            echo '<div class="wrap"><h3>Error</h3><p>API Key missing.</p></div>';
            return;
        }
        $is_arabic = strpos( get_locale(), 'ar' ) === 0;
        $title = ts_t( 'Ticket Categories' );
        if ( empty( $token ) ) {
            $req_auth = ( $is_arabic ? 'مطلوب تسجيل الدخول' : 'Authentication Required' );
            $req_auth_desc = ( $is_arabic ? 'يرجى تسجيل الدخول باستخدام حساب المشرف الخاص بك على صفحة تسجيل الدخول للوصول إلى هذه الميزة.' : 'Please log in with your admin account on the front-end login page to access this feature.' );
            $login_btn = ( $is_arabic ? 'تسجيل الدخول الآن' : 'Log In Now' );
            ?>
        <div class="wrap">
            <h1 style="font-family: 'Cairo', sans-serif; font-weight: 700; margin-bottom: 20px;"><?php 
            echo esc_html( $title );
            ?></h1>
            <div style="max-width: 500px; margin: 50px auto; background: #ffffff; border-radius: 16px; padding: 40px; text-align: center; border: 1px solid #e2e8f0; box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.05);">
                <div style="background: rgba(239, 68, 68, 0.08); color: #ef4444; width: 64px; height: 64px; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 20px;">
                    <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-lock"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
                </div>
                <h3 style="font-family: <?php 
            echo esc_html( ( $is_arabic ? "'Cairo'" : "'Inter'" ) );
            ?>, sans-serif; font-size: 20px; font-weight: 700; color: #0f172a; margin-top: 0; margin-bottom: 12px;"><?php 
            echo esc_html( $req_auth );
            ?></h3>
                <p style="font-family: <?php 
            echo esc_html( ( $is_arabic ? "'Cairo'" : "'Inter'" ) );
            ?>, sans-serif; font-size: 14px; color: #64748b; line-height: 1.6; margin-bottom: 24px;"><?php 
            echo esc_html( $req_auth_desc );
            ?></p>
                <a href="<?php 
            echo esc_url( ts_get_page_url( ( $is_arabic ? 'support-login-ar' : 'support-login' ), ( $is_arabic ? '[ticketing_system_login]' : 'Support Login' ) ) );
            ?>" target="_blank" class="button button-primary" style="background: #2563eb; border-color: #2563eb; padding: 6px 20px; font-size: 14px; font-weight: 600; border-radius: 8px; font-family: <?php 
            echo esc_html( ( $is_arabic ? "'Cairo'" : "'Inter'" ) );
            ?>, sans-serif; height: auto; line-height: 2;">
                    <?php 
            echo esc_html( $login_btn );
            ?>
                </a>
            </div>
        </div>
        <?php 
            return;
        }
        // Handle Add
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_POST['submit_add_category'] ) ) {
            check_admin_referer( 'ts_add_category_action' );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $name = sanitize_text_field( wp_unslash( ( isset( $_POST['cat_name'] ) ? $_POST['cat_name'] : '' ) ) );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $color = sanitize_hex_color( sanitize_text_field( wp_unslash( ( isset( $_POST['cat_color'] ) ? $_POST['cat_color'] : '' ) ) ) );
            $response = wp_remote_post( TS_API_BASE_URL . '/categories', [
                'headers'     => [
                    'Content-Type'  => 'application/json',
                    'Authorization' => 'Bearer ' . $token,
                    'X-Api-Key'     => $api_key,
                ],
                'body'        => json_encode( [
                    'name'  => $name,
                    'color' => $color,
                ] ),
                'data_format' => 'body',
            ] );
            if ( is_wp_error( $response ) ) {
                echo '<div class="notice notice-error"><p>' . esc_html( $response->get_error_message() ) . '</p></div>';
            } else {
                $code = wp_remote_retrieve_response_code( $response );
                if ( $code === 200 || $code === 201 ) {
                    echo '<div class="notice notice-success"><p>Category added.</p></div>';
                } else {
                    $body = json_decode( wp_remote_retrieve_body( $response ), true );
                    $msg = ( isset( $body['message'] ) ? $body['message'] : ts_t( ts_t( 'Could not add category.' ) ) );
                    echo '<div class="notice notice-error"><p>' . esc_html( $msg ) . '</p></div>';
                }
            }
        }
        // Handle Update
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_POST['submit_update_category'] ) ) {
            check_admin_referer( 'ts_update_category_action' );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $id = intval( sanitize_text_field( wp_unslash( $_POST['cat_id'] ) ) );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $name = sanitize_text_field( wp_unslash( ( isset( $_POST['cat_name'] ) ? $_POST['cat_name'] : '' ) ) );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $color = sanitize_hex_color( sanitize_text_field( wp_unslash( ( isset( $_POST['cat_color'] ) ? $_POST['cat_color'] : '' ) ) ) );
            $response = wp_remote_request( TS_API_BASE_URL . '/categories/' . $id, [
                'method'      => 'PUT',
                'headers'     => [
                    'Content-Type'  => 'application/json',
                    'Authorization' => 'Bearer ' . $token,
                    'X-Api-Key'     => $api_key,
                ],
                'body'        => json_encode( [
                    'id'    => $id,
                    'name'  => $name,
                    'color' => $color,
                ] ),
                'data_format' => 'body',
            ] );
            if ( is_wp_error( $response ) ) {
                echo '<div class="notice notice-error"><p>' . esc_html( $response->get_error_message() ) . '</p></div>';
            } else {
                $code = wp_remote_retrieve_response_code( $response );
                if ( $code === 200 || $code === 204 ) {
                    /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
                    echo '<div class="notice notice-success"><p>' . esc_html( ts_t( 'Category updated.' ) ) . '</p></div>';
                    // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
                    unset($_GET['edit_id']);
                    echo '<script>window.history.replaceState({}, document.title, "' . esc_url_raw( remove_query_arg( 'edit_id' ) ) . '");</script>';
                } else {
                    $body = json_decode( wp_remote_retrieve_body( $response ), true );
                    $msg = ( isset( $body['title'] ) ? $body['title'] : wp_remote_retrieve_body( $response ) );
                    echo '<div class="notice notice-error"><p>Error updating category (Code: ' . esc_html( $code ) . '): ' . esc_html( $msg ) . '</p></div>';
                }
            }
        }
        // Handle Archive
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_POST['submit_archive_category'] ) ) {
            check_admin_referer( 'ts_archive_category_action' );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $id = intval( sanitize_text_field( wp_unslash( $_POST['archive_id'] ) ) );
            $archived = get_option( 'ts_archived_categories', [] );
            if ( !in_array( $id, $archived ) ) {
                $archived[] = $id;
                update_option( 'ts_archived_categories', $archived );
            }
            echo '<div class="notice notice-success"><p>Category archived. It is now hidden from the customer form.</p></div>';
        }
        // Handle Restore
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_POST['submit_restore_category'] ) ) {
            check_admin_referer( 'ts_restore_category_action' );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $id = intval( sanitize_text_field( wp_unslash( $_POST['restore_id'] ) ) );
            $archived = get_option( 'ts_archived_categories', [] );
            $archived = array_diff( $archived, [$id] );
            update_option( 'ts_archived_categories', $archived );
            echo '<div class="notice notice-success"><p>Category restored.</p></div>';
        }
        // Handle Delete
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_POST['submit_delete_category'] ) ) {
            check_admin_referer( 'ts_delete_category_action' );
            // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
            $id = intval( sanitize_text_field( wp_unslash( $_POST['delete_id'] ) ) );
            wp_remote_request( TS_API_BASE_URL . '/categories/' . $id, [
                'method'      => 'DELETE',
                'headers'     => [
                    'Authorization' => 'Bearer ' . $token,
                    'X-Api-Key'     => $api_key,
                ],
                'data_format' => 'body',
            ] );
            $archived = get_option( 'ts_archived_categories', [] );
            $archived = array_diff( $archived, [$id] );
            update_option( 'ts_archived_categories', $archived );
            echo '<div class="notice notice-success"><p>Category deleted.</p></div>';
        }
        // Fetch Categories
        $response = wp_remote_get( TS_API_BASE_URL . '/categories', [
            'headers'     => [
                'Authorization' => 'Bearer ' . $token,
                'X-Api-Key'     => $api_key,
            ],
            'data_format' => 'body',
        ] );
        $categories = ( !is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) == 200 ? json_decode( wp_remote_retrieve_body( $response ), true ) : [] );
        // Determine Edit Mode
        $edit_cat = null;
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_GET['edit_id'] ) ) {
            foreach ( $categories as $c ) {
                // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
                if ( $c['id'] == sanitize_text_field( wp_unslash( $_GET['edit_id'] ) ) ) {
                    $edit_cat = $c;
                    break;
                }
            }
        }
        $archived_cats = get_option( 'ts_archived_categories', [] );
        ?>

    <style>

        .ts-admin-flex-container { display: flex; flex-wrap: wrap; gap: 24px; margin-top: 24px; }
        .ts-admin-flex-form { flex: 1; min-width: 300px; background: #fff; padding: 24px; border: none; border-radius: 12px; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.05), 0 2px 4px -1px rgba(0,0,0,0.03); box-sizing: border-box; }
        .ts-admin-flex-table { flex: 2; min-width: 300px; background: #fff; padding: 0; border: none; border-radius: 12px; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.05), 0 2px 4px -1px rgba(0,0,0,0.03); box-sizing: border-box; overflow: hidden; }
        .ts-admin-flex-table table { border: none; margin: 0; box-shadow: none; }
        .ts-admin-flex-table thead th { background: #f8fafc; border-bottom: 1px solid #e2e8f0; padding: 16px; font-weight: 600; color: #475569; }
        .ts-admin-flex-table tbody td { padding: 16px; vertical-align: middle; border-bottom: 1px solid #f1f5f9; }
        .ts-admin-flex-table tbody tr { transition: background 0.2s; }
        .ts-admin-flex-table tbody tr:hover { background: #f8fafc; }
        
        .ts-action-buttons { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
        
        .ts-action-btn { display: inline-flex; align-items: center; justify-content: center; padding: 5px 10px; font-size: 12px; font-weight: 600; border-radius: 6px; cursor: pointer; text-decoration: none; transition: all 0.2s ease; border: 1px solid transparent; }
        .ts-action-btn-primary { background: linear-gradient(135deg, #0ea5e9, #2563eb); color: white !important; box-shadow: 0 2px 4px rgba(37,99,235,0.1); padding: 8px 16px; font-size: 14px; }
        .ts-action-btn-primary:hover { transform: translateY(-1px); box-shadow: 0 4px 8px rgba(37,99,235,0.2); filter: brightness(1.05); }
        .ts-action-btn-secondary { background: #fff; border-color: #cbd5e1; color: #475569 !important; box-shadow: 0 1px 2px rgba(0,0,0,0.02); }
        .ts-action-btn-secondary:hover { background: #f8fafc; border-color: #94a3b8; color: #1e293b !important; transform: translateY(-1px); }
        .ts-action-btn-danger { background: #fff; border-color: #fecdd3; color: #e11d48 !important; box-shadow: 0 1px 2px rgba(0,0,0,0.02); }
        .ts-action-btn-danger:hover { background: #fff1f2; border-color: #fda4af; color: #be123c !important; transform: translateY(-1px); }


    </style>

    <div class="wrap">

        <h1><?php 
        echo esc_html( ts_t( 'Ticket Categories' ) );
        ?></h1>

        <div class="ts-admin-flex-container">

            <div class="ts-admin-flex-form">

                <h2><?php 
        echo esc_html( ( $edit_cat ? ts_t( 'Edit Category' ) : ts_t( 'Add Category' ) ) );
        ?></h2>

                <?php 
        $is_free_limit = (!defined( 'TS_IS_PRO' ) || !TS_IS_PRO) && count( $categories ) >= 3 && !$edit_cat;
        if ( $is_free_limit ) {
            ?>
                    <div style="background: #fff8e5; border-left: 4px solid #ffb900; padding: 15px; margin-bottom: 20px; box-sizing: border-box;">
                        <p style="margin: 0; font-weight: 600; color: #8a6d3b;">
                            <?php 
            echo esc_html( ts_t( 'Category limit reached. The Free plan allows a maximum of 3 categories. Please upgrade to Pro to add more.' ) );
            ?>
                        </p>
                        <p style="margin: 10px 0 0 0;">
                            <a href="<?php 
            echo esc_url( admin_url( 'admin.php?page=ts-custom-upgrade' ) );
            ?>" class="button button-primary">
                                                             <?php 
            echo esc_html( ts_t( 'Upgrade to Pro' ) );
            ?>
                            </a>
                        </p>
                    </div>
                <?php 
        } else {
            ?>

                <form method="post">

                    <?php 
            if ( $edit_cat ) {
                ?>

                        <?php 
                wp_nonce_field( 'ts_update_category_action' );
                ?>

                        <input type="hidden" name="cat_id" value="<?php 
                echo esc_attr( $edit_cat['id'] );
                ?>">

                    <?php 
            } else {
                ?>

                        <?php 
                wp_nonce_field( 'ts_add_category_action' );
                ?>

                    <?php 
            }
            ?>

                    

                    <p><label><?php 
            echo esc_html( ts_t( 'Name' ) );
            ?></label><br><input type="text" name="cat_name" value="<?php 
            echo ( $edit_cat ? esc_attr( $edit_cat['name'] ) : '' );
            ?>" required style="width:100%; padding: 8px; border-radius: 6px; border: 1px solid #cbd5e1;"></p>
                    <p><label><?php 
            echo esc_html( ts_t( 'Color' ) );
            ?></label><br><input type="color" name="cat_color" value="<?php 
            echo ( $edit_cat && isset( $edit_cat['color'] ) ? esc_attr( $edit_cat['color'] ) : '#0ea5e9' );
            ?>" style="width:100%; height:40px; padding: 2px; border-radius: 6px; border: 1px solid #cbd5e1;"></p>

                    <p style="margin-top: 24px; display: flex; gap: 10px;"><input type="submit" name="<?php 
            echo esc_html( ( $edit_cat ? 'submit_update_category' : 'submit_add_category' ) );
            ?>" class="ts-action-btn ts-action-btn-primary" value="<?php 
            echo esc_html( ( $edit_cat ? ts_t( 'Update' ) : ts_t( 'Add' ) ) );
            ?>">

                    <?php 
            if ( $edit_cat ) {
                ?><a href="<?php 
                echo esc_url( remove_query_arg( 'edit_id' ) );
                ?>" class="ts-action-btn ts-action-btn-secondary"><?php 
                echo esc_html( ts_t( 'Cancel' ) );
                ?></a><?php 
            }
            ?>

                    </p>

                </form>

                <?php 
        }
        ?>

            </div>

            <div class="ts-admin-flex-table" style="overflow-x: auto;">

                <table class="wp-list-table widefat striped" style="border: 0; box-shadow: none;">

                    <thead><tr><th style="width:50px;"><?php 
        echo esc_html( ts_t( 'Color' ) );
        ?></th><th><?php 
        echo esc_html( ts_t( 'Name' ) );
        ?></th><th style="min-width:160px;"><?php 
        echo esc_html( ts_t( 'Action' ) );
        ?></th></tr></thead>

                    <tbody>

                        <?php 
        if ( empty( $categories ) ) {
            ?><tr><td colspan="3"><?php 
            echo esc_html( ts_t( 'No categories found.' ) );
            ?></td></tr><?php 
        }
        ?>

                        <?php 
        foreach ( $categories as $cat ) {
            // phpcs:ignore WordPress.Security.NonceVerification.Missing
            $is_archived = in_array( $cat['id'], $archived_cats );
            // phpcs:ignore WordPress.Security.NonceVerification.Missing
            // phpcs:ignore WordPress.Security.NonceVerification.Missing
            $row_opacity = ( $is_archived ? 'opacity:0.6; background:#f9f9f9;' : '' );
            // phpcs:ignore WordPress.Security.NonceVerification.Missing
            ?>

                        <tr style="<?php 
            echo esc_attr( $row_opacity );
            ?>">

                            <td><div style="width:20px; height:20px; border-radius:50%; background-color:<?php 
            echo ( isset( $cat['color'] ) ? esc_attr( $cat['color'] ) : '#000' );
            ?>;"></div></td>

                            <td>
                                <?php 
            echo esc_html( $cat['name'] );
            ?>
                                <?php 
            if ( $is_archived ) {
                echo '<span class="dashicons dashicons-hidden" style="color:#a00; font-size:16px; margin-left:5px; margin-top:2px;" title="Archived"></span> <small style="color:#a00; font-weight:600;">' . esc_html( ts_t( 'Archived' ) ) . '</small>';
            }
            ?>

                            </td>

                            <td class="ts-action-buttons">

                                <a href="<?php 
            echo esc_html( add_query_arg( 'edit_id', $cat['id'] ) );
            ?>" class="ts-action-btn ts-action-btn-secondary"><?php 
            echo esc_html( ts_t( 'Edit' ) );
            ?></a>

                                <?php 
            if ( $is_archived ) {
                ?>

                                    <form method="post" style="display:inline-block; margin:0;">

                                        <?php 
                wp_nonce_field( 'ts_restore_category_action' );
                ?>

                                        <input type="hidden" name="restore_id" value="<?php 
                echo esc_html( $cat['id'] );
                ?>">

                                        <button type="submit" name="submit_restore_category" class="ts-action-btn ts-action-btn-secondary"><?php 
                echo esc_html( ts_t( 'Restore' ) );
                ?></button>

                                    </form>

                                <?php 
            } else {
                ?>

                                    <form method="post" style="display:inline-block; margin:0;" onsubmit="return confirm('<?php 
                /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
                echo esc_js( ts_t( 'Archive this category? It will be hidden from the customer frontend.' ) );
                ?>');">

                                        <?php 
                wp_nonce_field( 'ts_archive_category_action' );
                ?>

                                        <input type="hidden" name="archive_id" value="<?php 
                echo esc_html( $cat['id'] );
                ?>">

                                        <button type="submit" name="submit_archive_category" class="ts-action-btn ts-action-btn-secondary"><?php 
                echo esc_html( ts_t( 'Archive' ) );
                ?></button>

                                    </form>

                                <?php 
            }
            ?>

                                <form method="post" style="display:inline-block; margin:0;" onsubmit="return confirm('<?php 
            /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
            echo esc_js( ts_t( 'Permanently delete this category? Warning: Historical tickets might be affected.' ) );
            ?>');">

                                    <?php 
            wp_nonce_field( 'ts_delete_category_action' );
            ?>

                                    <input type="hidden" name="delete_id" value="<?php 
            echo esc_html( $cat['id'] );
            ?>">

                                    <button type="submit" name="submit_delete_category" class="ts-action-btn ts-action-btn-danger"><?php 
            echo esc_html( ts_t( 'Delete' ) );
            ?></button>

                                </form>

                            </td>

                        </tr>

                        <?php 
        }
        ?>

                    </tbody>

                </table>

            </div>

        </div>

    

        </div>

        

        

    



    <?php 
    }

}
// =================================================================
// 10. PASSWORD RESET (REDESIGNED)
// =================================================================
if ( !function_exists( 'display_forgot_password_form' ) ) {
    function display_forgot_password_form() {
        // Check for Success Message
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_GET['status'] ) && sanitize_text_field( wp_unslash( $_GET['status'] ) ) == 'success' ) {
            return '<div style="max-width:400px; margin:40px auto; text-align:center; padding:40px; background:#fff; border-radius:12px; box-shadow: 0 10px 25px rgba(0,0,0,0.05); border:1px solid #f0f0f1;">

            <div style="font-size:40px; margin-bottom:10px;">✉️ </div>

            <h3 style="margin-top:0; color:#333;">' . ts_t( 'Check Your Email' ) . '</h3>

            <p style="color:#666; font-size:14px; line-height:1.5;">' . ts_t( 'We have sent a password reset link to your email address.' ) . '</p>

            <a href="' . ts_get_page_url( 'support-login', 'Support Login' ) . '" class="button button-primary" style="margin-top:10px;">' . ts_t( 'Back to Login' ) . '</a>

        </div>';
        }
        ob_start();
        ?>

    

    <style>

        /* Reusing the same classes for consistency */

        .ts-auth-container { max-width: 400px; margin: 40px auto; background: #ffffff; padding: 40px; border-radius: 12px; box-shadow: 0 10px 30px -5px rgba(0, 0, 0, 0.1); border: 1px solid #e2e8f0; font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; color: #0f172a; }

        .ts-form-group { margin-bottom: 20px; }

        .ts-form-label { display: block; margin-bottom: 8px; font-weight: 600; color: #2c3e50; font-size: 14px; }

        .ts-form-input { width: 100%; padding: 12px 15px; border: 1px solid #dfe1e5; border-radius: 6px; font-size: 15px; box-sizing: border-box; transition: all 0.2s; }

        .ts-form-input:focus { border-color: <?php 
        echo esc_attr( get_option( 'ts_widget_color', '#0056b3' ) );
        ?>; outline: none; box-shadow: 0 0 0 3px rgba(0, 86, 179, 0.1); }

        .ts-submit-btn { width: 100%; padding: 12px; background: linear-gradient(135deg, #0ea5e9, #2563eb); color: white; border: none; border-radius: 8px; font-size: 16px; font-weight: 600; cursor: pointer; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); box-shadow: 0 4px 12px rgba(37, 99, 235, 0.2), 0 2px 4px rgba(37, 99, 235, 0.1); letter-spacing: 0.3px; }

        .ts-submit-btn:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(37, 99, 235, 0.3), 0 3px 6px rgba(37, 99, 235, 0.15); filter: brightness(1.05); }
        .ts-submit-btn:active { transform: translateY(0); box-shadow: 0 2px 4px rgba(37, 99, 235, 0.2); }

        .ts-back-link { display: block; text-align: center; margin-top: 20px; font-size: 13px; color: #666; text-decoration: none; }

        .ts-back-link:hover { color: <?php 
        echo esc_attr( get_option( 'ts_widget_color', '#0056b3' ) );
        ?>; }

    </style>



    <div class="ts-auth-container">

        <h2 style="text-align:center; margin-top:0; margin-bottom:10px; color:#333;"><?php 
        echo esc_html( ts_t( 'Reset Password' ) );
        ?></h2>

        <p style="text-align:center; color:#666; font-size:13px; margin-bottom:30px;"><?php 
        echo esc_html( ts_t( 'Enter your email and we will send you a reset link.' ) );
        ?></p>



        <form action="" method="post">

            <?php 
        wp_nonce_field( 'ts_forgot_pass_action' );
        ?>

            

            <div class="ts-form-group">

                <label class="ts-form-label" for="ts_email"><?php 
        echo esc_html( ts_t( 'Email Address' ) );
        ?></label>

                <input type="email" id="ts_email" name="ts_email" class="ts-form-input" required oninvalid="this.setCustomValidity('<?php 
        /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
        echo esc_js( ts_t( 'Please fill out this field.' ) );
        ?>')" oninput="this.setCustomValidity('')" placeholder="name@company.com">

            </div>

            

            <button type="submit" name="submit_forgot_password" class="ts-submit-btn"><?php 
        echo esc_html( ts_t( 'Send Reset Link' ) );
        ?></button>

        </form>



        <a href="<?php 
        echo esc_url( ts_get_page_url( 'support-login', 'Support Login' ) );
        ?>" class="ts-back-link">

            ← <?php 
        echo esc_html( ts_t( 'Back to Login' ) );
        ?>

        </a>

    </div>

    <?php 
        return ob_get_clean();
    }

}
add_shortcode( 'ticketing_system_forgot_password', 'display_forgot_password_form' );
if ( !function_exists( 'handle_forgot_password_submission' ) ) {
    function handle_forgot_password_submission() {
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_POST['submit_forgot_password'] ) ) {
            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.Security.EscapeOutput.UnsafePrintingFunction, WordPress.Security.NonceVerification
            if ( !wp_verify_nonce( sanitize_text_field( wp_unslash( ( isset( $_POST['_wpnonce'] ) ? $_POST['_wpnonce'] : '' ) ) ), 'ts_forgot_pass_action' ) ) {
                wp_die( 'Security check failed' );
            }
            $api_key = get_option( 'ts_tenant_api_key' );
            if ( empty( $api_key ) ) {
                wp_die( 'Error: API Key is missing. Please go to SahlDesk Settings and click "Sync License" to connect your account.' );
            }
            $api_url = TS_API_BASE_URL . '/auth/forgot-password';
            // FIX: Added 'BaseUrl' to the JSON body
            // home_url() automatically gets your current site address (e.g., http://localhost/ticketingtestv3)
            $body = [
                'Email'    => sanitize_email( sanitize_text_field( wp_unslash( ( isset( $_POST['ts_email'] ) ? $_POST['ts_email'] : '' ) ) ) ),
                'BaseUrl'  => home_url(),
                'Language' => ts_get_api_language(),
            ];
            $args = [
                'method'      => 'POST',
                'headers'     => [
                    'Content-Type' => 'application/json',
                    'X-Api-Key'    => $api_key,
                ],
                'body'        => json_encode( $body ),
                'data_format' => 'body',
                'timeout'     => 15,
            ];
            $response = wp_remote_post( $api_url, $args );
            if ( is_wp_error( $response ) ) {
                wp_die( "<h3>Connection Error</h3><p>" . esc_html( $response->get_error_message() ) . "</p><p><a href='javascript:history.back()'>Try Again</a></p>" );
            }
            $code = wp_remote_retrieve_response_code( $response );
            $response_body = wp_remote_retrieve_body( $response );
            if ( $code == 200 ) {
                wp_safe_redirect( add_query_arg( 'status', 'success', home_url( sanitize_text_field( wp_unslash( ( isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '' ) ) ) ) ) );
                exit;
            } else {
                // If it fails, show the specific error message from the API
                wp_die( "<h3>Error ({$code})</h3><p>The server said: " . esc_html( substr( $response_body, 0, 300 ) ) . "</p><p><a href='javascript:history.back()'>Try Again</a></p>" );
            }
        }
    }

}
add_action( 'init', 'handle_forgot_password_submission' );
// --- HELPER: Send Multipart Request (File Upload) ---
if ( !function_exists( 'ts_send_api_request_with_file' ) ) {
    function ts_send_api_request_with_file(
        $url,
        $fields,
        $file_input_name,
        $token,
        $api_key
    ) {
        $boundary = wp_generate_password( 24, false, false );
        $payload = '';
        // Append regular fields
        foreach ( $fields as $name => $value ) {
            $payload .= '--' . $boundary . "\r\n";
            $payload .= 'Content-Disposition: form-data; name="' . $name . '"' . "\r\n\r\n";
            $payload .= $value . "\r\n";
        }
        // Append file if exists
        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        if ( !empty( ( isset( $_FILES[$file_input_name]['tmp_name'] ) ? $_FILES[$file_input_name]['tmp_name'] : '' ) ) ) {
            // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            $file_path = ( isset( $_FILES[$file_input_name]['tmp_name'] ) ? $_FILES[$file_input_name]['tmp_name'] : '' );
            $file_name = basename( ( isset( $_FILES[$file_input_name]['name'] ) ? sanitize_file_name( wp_unslash( $_FILES[$file_input_name]['name'] ) ) : '' ) );
            $file_type = ( isset( $_FILES[$file_input_name]['type'] ) ? sanitize_mime_type( wp_unslash( $_FILES[$file_input_name]['type'] ) ) : '' );
            $file_content = file_get_contents( $file_path );
            if ( $file_content !== false ) {
                $payload .= '--' . $boundary . "\r\n";
                $payload .= 'Content-Disposition: form-data; name="attachment"; filename="' . $file_name . '"' . "\r\n";
                $payload .= 'Content-Type: ' . $file_type . "\r\n\r\n";
                $payload .= $file_content . "\r\n";
            }
        }
        $payload .= '--' . $boundary . '--' . "\r\n";
        $headers = [
            'X-Api-Key'         => $api_key,
            'X-Client-Domain'   => home_url(),
            'X-Client-Language' => ts_get_api_language(),
            'Content-Type'      => 'multipart/form-data; boundary=' . $boundary,
        ];
        if ( !empty( $token ) ) {
            $headers['Authorization'] = 'Bearer ' . $token;
        }
        $args = [
            'method'  => 'POST',
            'headers' => $headers,
            'body'    => $payload,
            'timeout' => 30,
        ];
        $response = wp_remote_post( $url, $args );
        if ( is_wp_error( $response ) ) {
            return [
                'code' => 500,
                'body' => "WP HTTP Error: " . $response->get_error_message(),
            ];
        } else {
            return [
                'code' => wp_remote_retrieve_response_code( $response ),
                'body' => wp_remote_retrieve_body( $response ),
            ];
        }
    }

}
// 12. RESET PASSWORD SHORTCODE (SAFE FALLBACK VERSION)
// =================================================================
if ( !function_exists( 'display_reset_password_form' ) ) {
    function display_reset_password_form() {
        // 1. Check for Token
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        $token = ( isset( $_GET['token'] ) ? sanitize_text_field( wp_unslash( $_GET['token'] ) ) : '' );
        // --- THE FIX: SAFE FALLBACK ---
        // If there is NO token and NO status message, don't show an error.
        // Instead, assume the user is lost and show the Login Form.
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( empty( $token ) && !isset( $_GET['status'] ) ) {
            return display_login_form();
        }
        // -----------------------------
        // 2. Check for Success
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_GET['status'] ) && sanitize_text_field( wp_unslash( $_GET['status'] ) ) == 'success' ) {
            return '<div style="max-width:400px; margin:40px auto; text-align:center; padding:40px; background:#d4edda; border-radius:12px; color:#155724;">

            <h3>' . ts_t( 'Password Changed!' ) . '</h3>

            <p>' . ts_t( 'Your password has been updated successfully.' ) . '</p>

            <a href="' . ts_get_page_url( 'support-login', 'Support Login' ) . '" class="button button-primary">' . ts_t( 'Login Now' ) . '</a>

        </div>';
            // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet
        }
        ob_start();
        ?>

    

    <style>

        .ts-auth-container { max-width: 400px; margin: 40px auto; background: #ffffff; padding: 40px; border-radius: 12px; box-shadow: 0 10px 30px -5px rgba(0, 0, 0, 0.1); border: 1px solid #e2e8f0; font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; color: #0f172a; }

        .ts-form-group { margin-bottom: 20px; }

        .ts-form-label { display: block; margin-bottom: 8px; font-weight: 600; color: #2c3e50; font-size: 14px; }

        .ts-form-input { width: 100%; padding: 12px 15px; border: 1px solid #dfe1e5; border-radius: 6px; font-size: 15px; box-sizing: border-box; transition: all 0.2s; }

        .ts-form-input:focus { border-color: <?php 
        echo esc_attr( get_option( 'ts_widget_color', '#0056b3' ) );
        ?>; outline: none; box-shadow: 0 0 0 3px rgba(0, 86, 179, 0.1); }

        .ts-submit-btn { width: 100%; padding: 12px; background: linear-gradient(135deg, #0ea5e9, #2563eb); color: white; border: none; border-radius: 8px; font-size: 16px; font-weight: 600; cursor: pointer; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); box-shadow: 0 4px 12px rgba(37, 99, 235, 0.2), 0 2px 4px rgba(37, 99, 235, 0.1); letter-spacing: 0.3px; }

        .ts-submit-btn:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(37, 99, 235, 0.3), 0 3px 6px rgba(37, 99, 235, 0.15); filter: brightness(1.05); }
        .ts-submit-btn:active { transform: translateY(0); box-shadow: 0 2px 4px rgba(37, 99, 235, 0.2); }

    </style>



    <div class="ts-auth-container">

        <h2 style="text-align:center; margin-top:0; margin-bottom:20px; color:#333;"><?php 
        echo esc_html( ts_t( 'Set New Password' ) );
        ?></h2>

        

        <?php 
        /* phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash */
        if ( isset( $_GET['error'] ) ) {
            ?>

            <div style="color:red; text-align:center; margin-bottom:15px;">

                <?php 
            echo esc_html( ts_t( 'Error: Invalid or expired token.' ) );
            ?>

            </div>

        <?php 
        }
        ?>



        <form action="" method="post">

            <?php 
        wp_nonce_field( 'ts_reset_pass_action' );
        ?>

            <input type="hidden" name="ts_token" value="<?php 
        echo esc_attr( $token );
        ?>">

            

            <div class="ts-form-group">

                <label class="ts-form-label"><?php 
        echo esc_html( ts_t( 'New Password' ) );
        ?></label>

                <input type="password" name="ts_new_password" class="ts-form-input" required placeholder="********" minlength="6">

            </div>

            

            <button type="submit" name="submit_reset_password" class="ts-submit-btn"><?php 
        echo esc_html( ts_t( 'Update Password' ) );
        ?></button>

        </form>

    </div>

    <?php 
        return ob_get_clean();
    }

}
add_shortcode( 'ticketing_system_reset_password', 'display_reset_password_form' );
if ( !function_exists( 'handle_reset_password_submission' ) ) {
    function handle_reset_password_submission() {
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_POST['submit_reset_password'] ) ) {
            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.Security.EscapeOutput.UnsafePrintingFunction, WordPress.Security.NonceVerification
            if ( !wp_verify_nonce( sanitize_text_field( wp_unslash( ( isset( $_POST['_wpnonce'] ) ? $_POST['_wpnonce'] : '' ) ) ), 'ts_reset_pass_action' ) ) {
                wp_die( 'Security check failed' );
            }
            $api_key = get_option( 'ts_tenant_api_key' );
            $api_url = TS_API_BASE_URL . '/auth/reset-password';
            $body = [
                'Token'       => sanitize_text_field( wp_unslash( ( isset( $_POST['ts_token'] ) ? $_POST['ts_token'] : '' ) ) ),
                'NewPassword' => sanitize_text_field( wp_unslash( ( isset( $_POST['ts_new_password'] ) ? $_POST['ts_new_password'] : '' ) ) ),
            ];
            $args = [
                'method'      => 'POST',
                'headers'     => [
                    'Content-Type' => 'application/json',
                    'X-Api-Key'    => $api_key,
                ],
                'body'        => json_encode( $body ),
                'data_format' => 'body',
                'timeout'     => 15,
            ];
            $response = wp_remote_post( $api_url, $args );
            if ( is_wp_error( $response ) ) {
                wp_safe_redirect( add_query_arg( 'error', 'failed', home_url( sanitize_text_field( wp_unslash( ( isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '' ) ) ) ) ) );
                exit;
            }
            $code = wp_remote_retrieve_response_code( $response );
            if ( $code == 200 ) {
                wp_safe_redirect( add_query_arg( 'status', 'success', home_url( sanitize_text_field( wp_unslash( ( isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '' ) ) ) ) ) );
                exit;
            } else {
                wp_safe_redirect( add_query_arg( 'error', 'failed', home_url( sanitize_text_field( wp_unslash( ( isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '' ) ) ) ) ) );
                exit;
            }
        }
    }

}
add_action( 'init', 'handle_reset_password_submission' );
// 11. LOGOUT
// =================================================================
if ( !function_exists( 'handle_logout_action' ) ) {
    function handle_logout_action() {
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_GET['action'] ) && sanitize_text_field( wp_unslash( $_GET['action'] ) ) == 'ts_logout' ) {
            if ( !session_id() ) {
                session_start();
            }
            session_destroy();
            setcookie(
                'wordpress_logged_in_ts_auth_token',
                '',
                time() - 3600,
                COOKIEPATH,
                COOKIE_DOMAIN
            );
            setcookie(
                'wordpress_logged_in_ts_user_role',
                '',
                time() - 3600,
                COOKIEPATH,
                COOKIE_DOMAIN
            );
            setcookie(
                'wordpress_logged_in_ts_user_name',
                '',
                time() - 3600,
                COOKIEPATH,
                COOKIE_DOMAIN
            );
            wp_safe_redirect( ts_get_page_url( 'support-login', 'Support Login' ) );
            exit;
        }
    }

}
add_action( 'init', 'handle_logout_action', 5 );
// =================================================================
// API HELPER FUNCTIONS (PASTE AT BOTTOM OF FILE)
// =================================================================
/**
 * Fetch a single ticket FROM THE API
 */
if ( !function_exists( 'ts_get_ticket_from_api' ) ) {
    function ts_get_ticket_from_api(  $ticket_id  ) {
        if ( !isset( $_SESSION['ts_auth_token'] ) ) {
            return null;
        }
        $api_key = get_option( 'ts_tenant_api_key' );
        $token = sanitize_text_field( wp_unslash( $_SESSION['ts_auth_token'] ) );
        $api_url = TS_API_BASE_URL . '/tickets/' . $ticket_id;
        $args = [
            'method'      => 'GET',
            'headers'     => [
                'Authorization' => 'Bearer ' . $token,
                'X-Api-Key'     => $api_key,
            ],
            'data_format' => 'body',
        ];
        $response = wp_remote_get( $api_url, $args );
        if ( is_wp_error( $response ) ) {
            return [
                'error' => 'CURL Error: ' . $response->get_error_message(),
            ];
        }
        $code = wp_remote_retrieve_response_code( $response );
        if ( $code != 200 ) {
            return [
                'error' => 'API Error Code ' . $code . ': ' . wp_remote_retrieve_body( $response ),
            ];
        }
        return json_decode( wp_remote_retrieve_body( $response ), true );
    }

}
/**
 * Fetch ticket messages/comments FROM THE API
 */
if ( !function_exists( 'ts_get_ticket_messages' ) ) {
    function ts_get_ticket_messages(  $ticket_id  ) {
        if ( !isset( $_SESSION['ts_auth_token'] ) ) {
            return [];
        }
        $api_key = get_option( 'ts_tenant_api_key' );
        $token = sanitize_text_field( wp_unslash( $_SESSION['ts_auth_token'] ) );
        // Assuming your API endpoint for comments is /tickets/{id}/comments
        $api_url = TS_API_BASE_URL . '/tickets/' . $ticket_id . '/comments';
        $args = [
            'method'      => 'GET',
            'headers'     => [
                'Authorization' => 'Bearer ' . $token,
                'X-Api-Key'     => $api_key,
            ],
            'data_format' => 'body',
        ];
        $response = wp_remote_get( $api_url, $args );
        if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) != 200 ) {
            return [];
        }
        $comments = json_decode( wp_remote_retrieve_body( $response ), true );
        // Map API fields to the format the View expects
        // The View expects: sender_id, sender_name, message, created_at, attachment_path
        $formatted_messages = [];
        if ( $comments ) {
            foreach ( $comments as $c ) {
                $formatted_messages[] = [
                    'sender_id'       => ( isset( $c['senderId'] ) ? $c['senderId'] : '' ),
                    'sender_name'     => ( isset( $c['senderName'] ) ? $c['senderName'] : 'User' ),
                    'message'         => ( isset( $c['content'] ) ? $c['content'] : '' ),
                    'created_at'      => ( isset( $c['createdDate'] ) ? $c['createdDate'] : '' ),
                    'attachment_path' => ( isset( $c['attachmentUrl'] ) ? $c['attachmentUrl'] : '' ),
                ];
            }
        }
        return $formatted_messages;
    }

}
/**
 * Check User Role Helper
 */
if ( !function_exists( 'ts_get_user_role' ) ) {
    function ts_get_user_role() {
        // If we have it in session from login, use that
        if ( isset( $_SESSION['ts_user_role'] ) ) {
            return sanitize_text_field( wp_unslash( $_SESSION['ts_user_role'] ) );
        }
        // Check WordPress capabilities first for native logins
        if ( current_user_can( 'manage_options' ) ) {
            return 'Admin';
        } elseif ( current_user_can( 'ts_agent' ) ) {
            return 'Agent';
        }
        return 'Customer';
    }

}
/**
 * Get Agents (from API cache or Session)
 */
if ( !function_exists( 'ts_get_agents' ) ) {
    function ts_get_agents() {
        // For now, return empty or implement ts_get_agents_from_api call here
        // If you need the dropdown to populate, you need to call the API users endpoint
        return [];
    }

}
/**
 * Fetch a single ticket by ID (Restoring the missing fetch logic)
 */
if ( !function_exists( 'ts_get_ticket' ) ) {
    function ts_get_ticket(  $ticket_id  ) {
        global $wpdb;
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared
        $table_name = $wpdb->prefix . 'ts_tickets';
        // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared
        return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table_name} WHERE id = %d", $ticket_id ), ARRAY_A );
    }

}
// 12. REPORTS PAGE RENDERER
// =================================================================
if ( !function_exists( 'ts_render_reports_page' ) ) {
    function ts_render_reports_page() {
        if ( !defined( 'TS_IS_PRO' ) || !TS_IS_PRO ) {
            echo '<div class="wrap"><div style="text-align:center; padding:50px; background:#fff; border-radius:8px; border:1px solid #ddd; margin-top:20px;">';
            echo '<div style="font-size:48px; margin-bottom:20px;">⭐</div>';
            /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
            echo '<h2>' . esc_html( ts_t( 'This is a Pro feature' ) ) . '</h2>';
            /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
            echo '<p style=\\"font-size:16px; color:#666;\\">' . esc_html( ts_t( 'Upgrade to the Pro version to unlock advanced Reports & Analytics.' ) ) . '</p>';
            echo '<a href="' . esc_url( admin_url( 'admin.php?page=ts-custom-upgrade' ) ) . '" class="button button-primary button-large" style="margin-top:15px;">' . esc_html( ts_t( 'Upgrade to Pro' ) ) . '</a>';
            echo '</div></div>';
            return;
        }
        // <fs_premium_only>
        if ( !current_user_can( 'manage_options' ) ) {
            $is_arabic = strpos( get_locale(), 'ar' ) === 0;
            $error_msg = ( $is_arabic ? 'عذراً، غير مسموح لك بالوصول إلى هذه الصفحة.' : 'Sorry, you are not allowed to access this page.' );
            $error_title = ( $is_arabic ? 'رفض الوصول' : 'Access Denied' );
            // phpcs:ignore PluginCheck.CodeAnalysis.Offloading.OffloadedContent, WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.WP.EnqueuedResources.NonEnqueuedScript
            /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
            wp_die( $error_msg, $error_title );
        }
        $api_key = get_option( 'ts_tenant_api_key' );
        $token = ( isset( $_SESSION['ts_auth_token'] ) ? sanitize_text_field( wp_unslash( $_SESSION['ts_auth_token'] ) ) : '' );
        $is_arabic = strpos( get_locale(), 'ar' ) === 0;
        $title = ( $is_arabic ? 'لوحة تحليلات الدعم الفني' : 'Support Desk Analytics' );
        // Check requirements
        if ( empty( $api_key ) ) {
            echo '<div class="wrap"><h3>Error</h3><p>API Key missing.</p></div>';
            return;
        }
        if ( empty( $token ) ) {
            $req_auth = ( $is_arabic ? 'مطلوب تسجيل الدخول' : 'Authentication Required' );
            $req_auth_desc = ( $is_arabic ? 'يرجى تسجيل الدخول باستخدام حساب المشرف الخاص بك على صفحة تسجيل الدخول للوصول إلى هذه الميزة.' : 'Please log in with your admin account on the front-end login page to access this feature.' );
            $login_btn = ( $is_arabic ? 'تسجيل الدخول الآن' : 'Log In Now' );
            ?>

        <div class="wrap">

            <h1 style="font-family: 'Cairo', sans-serif; font-weight: 700; margin-bottom: 20px;"><?php 
            echo esc_html( $title );
            ?></h1>

            <div style="max-width: 500px; margin: 50px auto; background: #ffffff; border-radius: 16px; padding: 40px; text-align: center; border: 1px solid #e2e8f0; box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.05);">

                <div style="background: rgba(239, 68, 68, 0.08); color: #ef4444; width: 64px; height: 64px; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 20px;">

                    <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-lock"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>

                </div>

                <h3 style="font-family: <?php 
            echo esc_html( ( $is_arabic ? "'Cairo'" : "'Inter'" ) );
            ?>, sans-serif; font-size: 20px; font-weight: 700; color: #0f172a; margin-top: 0; margin-bottom: 12px;"><?php 
            echo esc_html( $req_auth );
            ?></h3>

                <p style="font-family: <?php 
            echo esc_html( ( $is_arabic ? "'Cairo'" : "'Inter'" ) );
            ?>, sans-serif; font-size: 14px; color: #64748b; line-height: 1.6; margin-bottom: 24px;"><?php 
            echo esc_html( $req_auth_desc );
            ?></p>

                <a href="<?php 
            echo esc_url( ts_get_page_url( ( $is_arabic ? 'support-login-ar' : 'support-login' ), ( $is_arabic ? '[ticketing_system_login]' : 'Support Login' ) ) );
            ?>" target="_blank" class="button button-primary" style="background: #2563eb; border-color: #2563eb; padding: 6px 20px; font-size: 14px; font-weight: 600; border-radius: 8px; font-family: <?php 
            echo esc_html( ( $is_arabic ? "'Cairo'" : "'Inter'" ) );
            ?>, sans-serif; height: auto; line-height: 2;">

                    <?php 
            echo esc_html( $login_btn );
            ?>

                </a>

            </div>

        </div>

        <?php 
            return;
        }
        ?>

    <link rel="preconnect" href="https://fonts.googleapis.com">

    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

    <link href="https://fonts.googleapis.com/css2?family=Cairo:wght@400;600;700;800&family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">

    

    <div class="wrap">

        <div class="sahl-dashboard-wrapper <?php 
        echo esc_html( ( $is_arabic ? 'rtl' : 'ltr' ) );
        ?>">

            

            <!-- LOADING OVERLAY -->

            <div class="sd-loading-overlay" id="sd-loading-overlay">

                <div class="sd-spinner"></div>

            </div>



            <!-- HEADER -->

            <div class="sd-header">

                <div class="sd-title-area">

                    <div class="sd-title-icon">

                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/></svg>

                    </div>

                    <div class="sd-title-text">

                        <h2><?php 
        echo esc_html( $title );
        ?></h2>

                        <p><?php 
        echo esc_html( ( $is_arabic ? 'مراقبة فورية لأداء فريق الدعم الفني وحجم التذاكر.' : 'Real-time monitoring of support team operations & ticket loads.' ) );
        ?></p>

                    </div>

                </div>

                

                <div class="sd-filter-group">

                    <button class="sd-filter-btn" data-days="7"><?php 
        echo esc_html( ( $is_arabic ? 'آخر ٧ أيام' : '7 Days' ) );
        ?></button>

                    <button class="sd-filter-btn active" data-days="30"><?php 
        echo esc_html( ( $is_arabic ? 'آخر ٣٠ يوماً' : '30 Days' ) );
        ?></button>

                    <button class="sd-filter-btn" data-days="90"><?php 
        echo esc_html( ( $is_arabic ? 'آخر ٩٠ يوماً' : '90 Days' ) );
        ?></button>

                    <button class="sd-filter-btn" data-days="0"><?php 
        echo esc_html( ( $is_arabic ? 'الكل' : 'All Time' ) );
        ?></button>

                </div>

            </div>



            <!-- KPI CARD GRID -->

            <div class="sd-kpi-grid">

                <!-- Card 1: Total -->

                <div class="sd-kpi-card sd-kpi-total">

                    <div class="sd-kpi-content">

                        <span class="sd-kpi-label"><?php 
        echo esc_html( ( $is_arabic ? 'إجمالي التذاكر' : 'Total Tickets' ) );
        ?></span>

                        <span class="sd-kpi-value" id="kpi-total">-</span>

                    </div>

                    <div class="sd-kpi-icon">

                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M15 5v2m0 4v2m0 4v2M5 5a2 2 0 00-2 2v3a2 2 0 110 4v3a2 2 0 002 2h14a2 2 0 002-2v-3a2 2 0 110-4V7a2 2 0 00-2-2H5z"/></svg>

                    </div>

                </div>

                <!-- Card 2: Open -->

                <div class="sd-kpi-card sd-kpi-open">

                    <div class="sd-kpi-content">

                        <span class="sd-kpi-label"><?php 
        echo esc_html( ( $is_arabic ? 'مفتوح' : 'Open' ) );
        ?></span>

                        <span class="sd-kpi-value" id="kpi-open">-</span>

                    </div>

                    <div class="sd-kpi-icon">

                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8 4H6a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-2m-4-1v8m0 0l3-3m-3 3L9 8"/></svg>

                    </div>

                </div>

                <!-- Card 3: In Progress -->

                <div class="sd-kpi-card sd-kpi-progress">

                    <div class="sd-kpi-content">

                        <span class="sd-kpi-label"><?php 
        echo esc_html( ( $is_arabic ? 'جاري العمل' : 'In Progress' ) );
        ?></span>

                        <span class="sd-kpi-value" id="kpi-progress">-</span>

                    </div>

                    <div class="sd-kpi-icon">

                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 10V3L4 14h7v7l9-11h-7z"/></svg>

                    </div>

                </div>

                        <!-- Card 3.5: Pending -->

                <div class="sd-kpi-card sd-kpi-pending">

                    <div class="sd-kpi-content">

                        <span class="sd-kpi-label"><?php 
        echo esc_html( ( $is_arabic ? 'قيد الانتظار' : 'Pending' ) );
        ?></span>

                        <span class="sd-kpi-value" id="kpi-pending">-</span>

                    </div>

                    <div class="sd-kpi-icon">

                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>

                    </div>

                </div>

                <!-- Card 4: Closed -->

                <div class="sd-kpi-card sd-kpi-closed">

                    <div class="sd-kpi-content">

                        <span class="sd-kpi-label"><?php 
        echo esc_html( ( $is_arabic ? 'مغلق' : 'Closed' ) );
        ?></span>

                        <span class="sd-kpi-value" id="kpi-closed">-</span>

                    </div>

                    <div class="sd-kpi-icon">

                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>

                    </div>

                </div>

                <!-- Card 5: Avg Resolution Time -->

                <div class="sd-kpi-card sd-kpi-avg">

                    <div class="sd-kpi-content">

                        <span class="sd-kpi-label"><?php 
        echo esc_html( ( $is_arabic ? 'متوسط وقت الحل' : 'Avg. Resolution' ) );
        ?></span>

                        <span class="sd-kpi-value" id="kpi-avg">-</span>

                    </div>

                    <div class="sd-kpi-icon">

                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>

                    </div>

                </div>

            </div>



            <!-- DASHBOARD DYNAMIC EMPTY STATE -->

            <div class="sd-empty-state" id="dashboard-empty-state" style="display: none;">

                <div class="sd-empty-icon">

                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bar-chart-3" style="width:64px; height:64px;"><path d="M3 3v18h18"/><path d="M18 17V9"/><path d="M13 17V5"/><path d="M8 17v-3"/></svg>

                </div>

                <h4><?php 
        echo esc_html( ( $is_arabic ? 'لا توجد بيانات كافية' : 'No Analytics Data Found' ) );
        ?></h4>

                <p><?php 
        echo esc_html( ( $is_arabic ? 'لم يتم العثور على تذاكر دعم فني خلال الفترة المحددة.' : 'Try adjusting your date range filter or creating new tickets to see support desk activity.' ) );
        ?></p>

            </div>



            <!-- DASHBOARD CHARTS WRAPPER -->

            <div class="sd-charts-wrapper" id="dashboard-charts-wrapper">

                

                <!-- ROW 1 -->

                <div class="sd-charts-grid">

                    <!-- Volume Trend Line (2/3 width) -->

                    <div class="sd-widget">

                        <h3><?php 
        echo esc_html( ( $is_arabic ? 'معدل حجم التذاكر اليومي' : 'Ticket Volume Trend' ) );
        ?></h3>

                        <div class="sd-widget-content">

                            <div class="sd-canvas-container">

                                <canvas id="trendChart"></canvas>

                            </div>

                        </div>

                    </div>

                    <!-- Status Distribution Doughnut (1/3 width) -->

                    <div class="sd-widget">

                        <h3><?php 
        echo esc_html( ( $is_arabic ? 'التذاكر حسب الحالة' : 'Tickets by Status' ) );
        ?></h3>

                        <div class="sd-widget-content">

                            <div class="sd-canvas-container">

                                <canvas id="statusChart"></canvas>

                            </div>

                        </div>

                    </div>

                </div>



                <!-- ROW 2 -->

                <div class="sd-charts-grid">

                    <!-- Agent workloads comparison bar (2/3 width) -->

                    <div class="sd-widget">

                        <h3><?php 
        echo esc_html( ( $is_arabic ? 'أعباء العمل ومعدل الحلول للموظفين' : 'Agent Workloads & Resolution Rate' ) );
        ?></h3>

                        <div class="sd-widget-content">

                            <div class="sd-canvas-container">

                                <canvas id="agentChart"></canvas>

                            </div>

                        </div>

                    </div>

                    

                    <!-- Pie and progress block (1/3 width) -->

                    <div class="sd-widget-stack">

                        <!-- Categories Pie -->

                        <div class="sd-widget" style="margin-bottom: 24px;">

                            <h3><?php 
        echo esc_html( ( $is_arabic ? 'التذاكر حسب القسم' : 'Tickets by Category' ) );
        ?></h3>

                            <div class="sd-widget-content">

                                <div class="sd-canvas-container" style="height: 220px;">

                                    <canvas id="categoryChart"></canvas>

                                </div>

                            </div>

                        </div>

                        

                        <!-- Priorities progress list -->

                        <div class="sd-widget">

                            <h3><?php 
        echo esc_html( ( $is_arabic ? 'التذاكر حسب الأولوية' : 'Tickets by Priority' ) );
        ?></h3>

                            <div class="sd-widget-content">

                                <div class="sd-priority-list">

                                    

                                    <div class="sd-priority-item">

                                        <div class="sd-priority-info">

                                            <span class="sd-priority-dot sd-dot-high"></span>

                                            <span class="sd-priority-name"><?php 
        echo esc_html( ( $is_arabic ? 'عاجل' : 'High Priority' ) );
        ?></span>

                                        </div>

                                        <div class="sd-priority-bar-wrapper">

                                            <div class="sd-priority-bar-fill sd-fill-high" id="priority-high-bar" style="width: 0%"></div>

                                            <span class="sd-priority-count" id="priority-high-count">0</span>

                                        </div>

                                    </div>

                                    

                                    <div class="sd-priority-item">

                                        <div class="sd-priority-info">

                                            <span class="sd-priority-dot sd-dot-medium"></span>

                                            <span class="sd-priority-name"><?php 
        echo esc_html( ( $is_arabic ? 'متوسط' : 'Medium Priority' ) );
        ?></span>

                                        </div>

                                        <div class="sd-priority-bar-wrapper">

                                            <div class="sd-priority-bar-fill sd-fill-medium" id="priority-medium-bar" style="width: 0%"></div>

                                            <span class="sd-priority-count" id="priority-medium-count">0</span>

                                        </div>

                                    </div>

                                    

                                    <div class="sd-priority-item">

                                        <div class="sd-priority-info">

                                            <span class="sd-priority-dot sd-dot-low"></span>

                                            <span class="sd-priority-name"><?php 
        echo esc_html( ( $is_arabic ? 'منخفض' : 'Low Priority' ) );
        ?></span>

                                        </div>

                                        <div class="sd-priority-bar-wrapper">

                                            <div class="sd-priority-bar-fill sd-fill-low" id="priority-low-bar" style="width: 0%"></div>

                                            <span class="sd-priority-count" id="priority-low-count">0</span>

                                        </div>

                                    </div>

                                    

                                </div>

                            </div>

                        </div>

                    </div>

                </div>



            </div>

            


        </div>

    </div>



    <!-- Chart.js CDN -->

    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>



    <!-- DASHBOARD CONTROLLER SCRIPT -->


    <?php 
        // </fs_premium_only>
    }

}
// =================================================================
// 13. AUTO-SETUP: CREATE PAGES ON ACTIVATION
// =================================================================
register_activation_hook( __FILE__, 'ts_plugin_activation_logic' );
if ( !function_exists( 'ts_plugin_activation_logic' ) ) {
    function ts_plugin_activation_logic() {
        // Create SahlDesk Agent Role
        add_role( 'sahldesk_agent', 'SahlDesk Agent', [
            'read' => true,
        ] );
        // Detect site language
        $locale = get_locale();
        $is_arabic = strpos( $locale, 'ar' ) === 0;
        // List of pages to create: "Page Title" => "Shortcode"
        if ( $is_arabic ) {
            $pages_to_create = [
                'support-dashboard-ar' => [
                    'title'     => 'Support Dashboard AR',
                    'shortcode' => '[ticketing_system_dashboard]',
                ],
                'create-ticket-ar'     => [
                    'title'     => 'Create Ticket AR',
                    'shortcode' => '[ticketing_system_create]',
                ],
                'view-ticket-ar'       => [
                    'title'     => 'View Ticket AR',
                    'shortcode' => '[ticketing_system_view_ticket]',
                ],
                'support-login-ar'     => [
                    'title'     => 'Support Login AR',
                    'shortcode' => '[ticketing_system_login]',
                ],
                'register-ar'          => [
                    'title'     => 'Register AR',
                    'shortcode' => '[ticketing_system_register]',
                ],
                'reset-password-ar'    => [
                    'title'     => 'Reset Password AR',
                    'shortcode' => '[ticketing_system_reset_password]',
                ],
                'forgot-password-ar'   => [
                    'title'     => 'Forgot Password AR',
                    'shortcode' => '[ticketing_system_forgot_password]',
                ],
            ];
        } else {
            $pages_to_create = [
                'support-dashboard' => [
                    'title'     => 'Support Dashboard',
                    'shortcode' => '[ticketing_system_dashboard]',
                ],
                'create-ticket'     => [
                    'title'     => 'Create Ticket',
                    'shortcode' => '[ticketing_system_create]',
                ],
                'view-ticket'       => [
                    'title'     => 'View Ticket',
                    'shortcode' => '[ticketing_system_view_ticket]',
                ],
                'support-login'     => [
                    'title'     => 'Support Login',
                    'shortcode' => '[ticketing_system_login]',
                ],
                'register'          => [
                    'title'     => 'Register',
                    'shortcode' => '[ticketing_system_register]',
                ],
                'reset-password'    => [
                    'title'     => 'Reset Password',
                    'shortcode' => '[ticketing_system_reset_password]',
                ],
                'forgot-password'   => [
                    'title'     => 'Forgot Password',
                    'shortcode' => '[ticketing_system_forgot_password]',
                ],
            ];
        }
        foreach ( $pages_to_create as $slug => $data ) {
            // Check if page exists by slug
            $existing_page = get_page_by_path( $slug );
            // If not, create it
            if ( !$existing_page ) {
                $page_details = [
                    'post_title'   => $data['title'],
                    'post_content' => $data['shortcode'],
                    'post_status'  => 'publish',
                    'post_type'    => 'page',
                    'post_name'    => $slug,
                ];
                wp_insert_post( $page_details );
            }
        }
        // Auto-provision SahlDesk API Key immediately upon SahlDesk plugin activation
        ts_sync_license_with_backend();
    }

}
// =================================================================
// HIDE UTILITY PAGES FROM DEFAULT WORDPRESS MENU
// =================================================================
add_filter( 'wp_page_menu_args', 'ts_exclude_utility_pages_from_menu' );
if ( !function_exists( 'ts_exclude_utility_pages_from_menu' ) ) {
    function ts_exclude_utility_pages_from_menu(  $args  ) {
        $exclude_slugs = [
            'view-ticket',
            'register',
            'reset-password',
            'forgot-password',
            'view-ticket-ar',
            'register-ar',
            'reset-password-ar',
            'forgot-password-ar'
        ];
        $exclude_ids = [];
        foreach ( $exclude_slugs as $slug ) {
            $page = get_page_by_path( $slug );
            if ( $page ) {
                $exclude_ids[] = $page->ID;
            }
        }
        if ( !empty( $exclude_ids ) ) {
            $existing_excludes = ( isset( $args['exclude'] ) ? $args['exclude'] : '' );
            // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude
            $args['exclude'] = ( $existing_excludes ? $existing_excludes . ',' . implode( ',', $exclude_ids ) : implode( ',', $exclude_ids ) );
        }
        return $args;
    }

}
// =================================================================
// DISABLE CACHING FOR TICKETING PAGES
// =================================================================
if ( !function_exists( 'ts_disable_caching_for_plugin_pages' ) ) {
    if ( !function_exists( 'ts_disable_caching_for_plugin_pages' ) ) {
        function ts_disable_caching_for_plugin_pages() {
            global $post;
            // 1. List of your plugin page slugs
            // UPDATE THESE to match your exact page URLs
            $plugin_pages = [
                'support-dashboard',
                'create-ticket',
                'support-login',
                'view-ticket',
                'register',
                'forgot-password',
                'support-dashboard-ar',
                'support-login-ar',
                'create-ticket-ar',
                'view-ticket-ar'
            ];
            if ( $post && in_array( $post->post_name, $plugin_pages ) ) {
                // A. Tell WordPress/Plugins not to cache this
                if ( !defined( 'DONOTCACHEPAGE' ) ) {
                    define( 'DONOTCACHEPAGE', true );
                }
                // B. Send HTTP Headers to browser
                nocache_headers();
            }
        }

    }
}
add_action( 'template_redirect', 'ts_disable_caching_for_plugin_pages' );
// =================================================================
// 14. GUEST WIDGET (FLOATING)
// =================================================================
if ( !function_exists( 'ts_render_guest_widget' ) ) {
    function ts_render_guest_widget() {
        // phpcs:ignore PluginCheck.CodeAnalysis.EnqueuedResourceOffloading.OffloadedContent, PluginCheck.CodeAnalysis.Offloading.OffloadedContent, WordPress.WP.EnqueuedResourceParameters.MissingVersion, WordPress.WP.EnqueuedResources.NonEnqueuedScript
        wp_enqueue_script(
            'ts-turnstile',
            'https://challenges.cloudflare.com/turnstile/v0/api.js',
            array(),
            TS_PLUGIN_VERSION,
            true
        );
        // Check Company Setting (Default to true if not set)
        if ( !get_option( 'ts_allow_guest_tickets', true ) ) {
            return;
        }
        $widget_color = get_option( 'ts_widget_color', '#0056b3' );
        ?>

    <style>

        /* Widget Styles */

        #ts-guest-widget-btn { position: fixed; bottom: 25px; right: 25px; background: <?php 
        echo esc_attr( $widget_color );
        ?>; color: #fff; width: 60px; height: 60px; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; box-shadow: 0 4px 15px rgba(0,0,0,0.2); z-index: 99999; transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); }

        #ts-guest-widget-btn:hover { transform: translateY(-3px); box-shadow: 0 6px 20px rgba(0,0,0,0.3); }

        

        #ts-guest-widget-popup { display: none; position: fixed; bottom: 100px; right: 25px; width: 350px; background: #fff; border-radius: 16px; box-shadow: 0 10px 40px rgba(0,0,0,0.15); z-index: 99999; overflow: hidden; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; border: 1px solid rgba(0,0,0,0.05); animation: tsSlideUp 0.3s ease-out; }

        @keyframes tsSlideUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }



        .ts-widget-header { background: <?php 
        echo esc_attr( $widget_color );
        ?>; color: #fff; padding: 18px 20px; font-weight: 600; font-size: 16px; display: flex; justify-content: space-between; align-items: center; }

        .ts-widget-body { padding: 25px; background: #fcfcfc; }

        

        .ts-widget-input, .ts-widget-textarea { width: 100%; padding: 12px 15px; margin-bottom: 15px; border: 1px solid #e2e8f0; border-radius: 8px; box-sizing: border-box; font-size: 14px; background: #fff; transition: border-color 0.2s, box-shadow 0.2s; font-family: inherit; }

        .ts-widget-input:focus, .ts-widget-textarea:focus { border-color: <?php 
        echo esc_attr( $widget_color );
        ?>; outline: none; box-shadow: 0 0 0 3px rgba(0,0,0,0.05); }

        

        .ts-widget-textarea { min-height: 100px; resize: vertical; }

        .ts-widget-btn { width: 100%; background: <?php 
        echo esc_attr( $widget_color );
        ?>; color: #fff; border: none; padding: 14px; border-radius: 10px; cursor: pointer; font-weight: 600; font-size: 15px; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); box-shadow: 0 4px 12px rgba(0,0,0,0.1), 0 2px 4px rgba(0,0,0,0.06); letter-spacing: 0.3px; }

        .ts-widget-btn:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(0,0,0,0.15), 0 3px 6px rgba(0,0,0,0.1); filter: brightness(1.1); }
        .ts-widget-btn:active { transform: translateY(0); box-shadow: 0 2px 4px rgba(0,0,0,0.1); filter: brightness(1); }

        .ts-widget-close { cursor: pointer; font-size: 20px; opacity: 0.8; transition: opacity 0.2s; }

        .ts-widget-close:hover { opacity: 1; }

    </style>



    <div id="ts-guest-widget-btn" onclick="document.getElementById('ts-guest-widget-popup').style.display = (document.getElementById('ts-guest-widget-popup').style.display === 'block' ? 'none' : 'block')">

        <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>

    </div>



    <div id="ts-guest-widget-popup">

        <div class="ts-widget-header">

            <span><?php 
        echo esc_html( ts_t( 'Support' ) );
        ?></span>

            <span class="ts-widget-close" onclick="document.getElementById('ts-guest-widget-popup').style.display='none'">&times;</span>

        </div>

        <div class="ts-widget-body" id="ts-widget-form-container">

            <input type="text" id="ts_guest_name" class="ts-widget-input" dir="auto" style="text-align: start;" placeholder="<?php 
        echo esc_html( ts_t( 'Name (Optional)' ) );
        ?>">
            <input type="email" id="ts_guest_email" class="ts-widget-input" dir="auto" style="text-align: start;" placeholder="<?php 
        echo esc_html( ts_t( 'Email' ) );
        ?>" required oninvalid="this.setCustomValidity('<?php 
        echo esc_js( ts_t( 'Please fill out this field.' ) );
        ?>')" oninput="this.setCustomValidity('')">

            <input type="tel" id="ts_guest_phone" class="ts-widget-input" dir="auto" style="text-align: start;" placeholder="<?php 
        echo esc_html( ts_t( 'Phone Number' ) );
        ?>">

            <textarea id="ts_guest_issue" class="ts-widget-textarea" dir="auto" style="text-align: start;" placeholder="<?php 
        echo esc_html( ts_t( 'How can we help?' ) );
        ?>" maxlength="10000" required></textarea>

            

            <div class=\"cf-turnstile\" data-sitekey=\"[INSERT_TURNSTILE_SITE_KEY_HERE]\" style=\"margin-bottom: 15px; display: flex; justify-content: center;\"></div>

            <label for="ts_guest_attachment" class="ts-widget-input" style="display: flex; align-items: center; justify-content: center; cursor: pointer; background: #f8f9fa; border: 1px dashed #ced4da; padding: 10px; color: #495057; font-size: 13px; text-align: center;">

                <span id="ts_file_name_display"><?php 
        echo esc_html( ts_t( 'Choose File' ) );
        ?></span>

            </label>

            <input type="file" id="ts_guest_attachment" style="display: none;" accept=".jpg,.jpeg,.png,.pdf,.doc,.docx" onchange="document.getElementById('ts_file_name_display').textContent = this.files.length > 0 ? this.files[0].name : '<?php 
        echo esc_html( ts_t( 'No file chosen' ) );
        ?>'">



            <button onclick="tsSubmitGuestTicket()" class="ts-widget-btn" id="ts-guest-submit-btn"><?php 
        echo esc_html( ts_t( 'Send Message' ) );
        ?></button>

            <div style="text-align:center; margin-top:10px; font-size:11px; color:#999;">Powered by <a href="https://sahldesk.com" target="_blank" style="color:#999; text-decoration:none;">SahlDesk</a></div>

        </div>

        <div class="ts-widget-body" id="ts-widget-success" style="display:none; text-align:center; color: #155724;">

            <div style="margin-bottom: 10px; display:flex; justify-content:center;">
                <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="color: #28a745;"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline></svg>
            </div>

            <p><?php 
        echo esc_html( ts_t( 'Ticket Created' ) ) . '!';
        ?> <strong id="ts-guest-created-id"></strong></p>

            <p style="font-size:12px; color:#666;"><?php 
        echo esc_html( ts_t( 'A confirmation email has been sent.' ) );
        ?></p>

        </div>

    </div>




    <?php 
    }

}
add_action( 'wp_footer', 'ts_render_guest_widget' );
// --- ADMIN NOTICES ---
add_action( 'admin_notices', 'ts_license_expired_notice' );
if ( !function_exists( 'ts_license_expired_notice' ) ) {
    function ts_license_expired_notice() {
        if ( !function_exists( 'sahldesk_fs' ) ) {
            return;
        }
        if ( !current_user_can( 'manage_options' ) ) {
            return;
        }
        $fs = sahldesk_fs();
        if ( $fs->is_registered() ) {
            $license = $fs->_get_license();
            // Check if license exists and is expired
            if ( is_object( $license ) && method_exists( $license, 'is_expired' ) && $license->is_expired() ) {
                // Check dismissal
                if ( get_user_meta( get_current_user_id(), 'ts_dismissed_expired_notice', true ) ) {
                    return;
                }
                ?>

            <div class="notice notice-error is-dismissible ts-expired-notice">

                <p>

                    <strong><?php 
                esc_html_e( 'Ticketing System License Expired', 'sahldesk' );
                ?></strong>: 

                    <?php 
                esc_html_e( 'Your license has expired. Please renew to continue receiving updates and support.', 'sahldesk' );
                ?> 

                    <a href="<?php 
                echo esc_url( $fs->get_account_url() );
                ?>" class="button button-small button-primary" style="margin-left: 5px;"><?php 
                esc_html_e( 'Renew Now', 'sahldesk' );
                ?></a>

                </p>

            </div>

            <script>

                jQuery(document).ready(function($) {

                    $('.ts-expired-notice').on('click', '.notice-dismiss', function() {

                        $.post(ajaxurl, {

                            action: 'ts_dismiss_expired_notice',

                            nonce: '<?php 
                echo esc_attr( wp_create_nonce( 'ts_dismiss_notice_nonce' ) );
                ?>'

                        });

                    });

                });

            </script>

            <?php 
            }
        }
    }

}
add_action( 'wp_ajax_ts_dismiss_expired_notice', 'ts_dismiss_expired_notice_handler' );
if ( !function_exists( 'ts_dismiss_expired_notice_handler' ) ) {
    function ts_dismiss_expired_notice_handler() {
        check_ajax_referer( 'ts_dismiss_notice_nonce', 'nonce' );
        update_user_meta( get_current_user_id(), 'ts_dismissed_expired_notice', 1 );
        /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
        wp_die();
    }

}
// --- FOOTER HELPER ---
if ( !function_exists( 'ts_render_footer' ) ) {
    function ts_render_footer() {
        return '<div style="text-align: center; font-size: 12px; color: #999; margin-top: 20px; padding-top: 10px; border-top: 1px solid #eee;">

        ' . ts_t( 'Powered by' ) . ' <a href="https://sahldesk.com" target="_blank" style="color:' . esc_attr( get_option( 'ts_widget_color', '#0056b3' ) ) . '; text-decoration: none; font-weight: 500;">SahlDesk</a>

    </div>';
    }

}
// --- LANGUAGE HELPER ---
if ( !function_exists( 'ts_get_api_language' ) ) {
    function ts_get_api_language() {
        return ( strpos( get_locale(), 'ar' ) === 0 ? 'ar' : 'en' );
    }

}
// =================================================================
// 15. WOOCOMMERCE RMA RETURN BUTTON
// =================================================================
if ( defined( 'TS_IS_PRO' ) && TS_IS_PRO ) {
    add_filter(
        'woocommerce_my_account_my_orders_actions',
        'ts_add_rma_order_action',
        10,
        2
    );
    if ( !function_exists( 'ts_add_rma_order_action' ) ) {
        function ts_add_rma_order_action(  $actions, $order  ) {
            if ( $order->has_status( 'completed' ) ) {
                $actions['rma_return'] = array(
                    'url'  => add_query_arg( 'order_id', $order->get_id(), ( strpos( get_locale(), 'ar' ) === 0 ? ts_get_page_url( 'create-ticket-ar', 'Create Ticket AR' ) : ts_get_page_url( 'create-ticket', 'Create Ticket' ) ) ),
                    'name' => ts_t( 'Request Return' ),
                );
            }
            return $actions;
        }

    }
}
// =================================================================
// 16. RESPONSIVE DESIGN (GLOBAL)
// =================================================================
add_action( 'wp_head', 'ts_responsive_styles' );
if ( !function_exists( 'ts_responsive_styles' ) ) {
    function ts_responsive_styles() {
        echo '<style>

        /* Responsive Overrides for SahlDesk */

        @media (max-width: 768px) {

            /* Forms (Login, Register, Forgot Password, Create Ticket) */

            .ts-form-container { width: 90% !important; max-width: 100% !important; padding: 20px !important; margin: 20px auto !important; }

            .ts-form-header h2 { font-size: 20px !important; }

            

            /* Dashboard */

            .ts-dashboard-wrapper { padding: 10px !important; }

            .ts-dash-header { flex-direction: column !important; align-items: flex-start !important; gap: 10px !important; }

            .ts-actions { width: 100% !important; justify-content: flex-start !important; }

            .ts-table-card { border-radius: 4px !important; }

            

            /* Single Ticket View */

            .ts-ticket-container { flex-direction: column !important; }

            .ts-sidebar-column { width: 100% !important; flex: none !important; }

            .ts-comment-meta { flex-direction: column !important; align-items: flex-start !important; }

            .ts-ticket-title { font-size: 20px !important; }

        }

        @media (max-width: 480px) {

            .ts-submit-btn, .ts-btn-new, .ts-btn-export { width: 100% !important; justify-content: center !important; }

        }

    </style>';
    }

}
// Handle automatic checkout popup on Freemius native pricing page
// removed auto checkout
if ( !function_exists( 'ts_freemius_auto_checkout_js' ) ) {
    function ts_freemius_auto_checkout_js() {
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( isset( $_GET['page'] ) && sanitize_text_field( wp_unslash( $_GET['page'] ) ) === 'my-ticketing-system-pricing' && isset( $_GET['auto_checkout'] ) ) {
            ?>

        <script type="text/javascript">

            jQuery(document).ready(function($) {

                // Wait for Freemius React/Vue app to render the pricing table

                var checkExist = setInterval(function() {

                    var btn = jQuery('.fs-checkout-button');

                    if (btn.length) {

                        clearInterval(checkExist);

                        // Freemius modal expects user interaction, but we can simulate it

                        btn.first().click();

                    }

                }, 500);

            });

        </script>

        <?php 
        }
    }

}
// Rename Freemius Submenus to Arabic (and hide Account for Free users)
add_action( 'admin_menu', function () {
    global $submenu;
    if ( isset( $submenu['ts_settings_page'] ) ) {
        foreach ( $submenu['ts_settings_page'] as $index => &$item ) {
            // Check by slug ($item[2]) instead of title ($item[0]) because titles change based on locale
            if ( strpos( $item[2], 'account' ) !== false ) {
                // Hide Account tab if the user is on the Free plan, or if they are just on a Trial
                if ( function_exists( 'sahldesk_fs' ) ) {
                    $is_free = !sahldesk_fs()->has_active_valid_license();
                    $is_trial = sahldesk_fs()->is_trial();
                    // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
                    if ( ($is_free || $is_trial) && empty( $_GET['enter_license'] ) && empty( $_GET['fs_action'] ) ) {
                        unset($submenu['ts_settings_page'][$index]);
                        continue;
                    }
                }
                $item[0] = ts_t( 'Account' );
            }
            if ( strpos( $item[2], 'pricing' ) !== false || strpos( $item[0], 'Upgrade' ) !== false ) {
                $item[0] = ts_t( 'Upgrade' );
            }
        }
    }
}, PHP_INT_MAX );
// --- DYNAMIC FREEMIUS PRICING FETCH ---
if ( !function_exists( 'ts_get_freemius_plans_data' ) ) {
    function ts_get_freemius_plans_data() {
        $transient_key = 'ts_fs_plans_cache_v6';
        $cached = get_transient( $transient_key );
        if ( $cached !== false && is_array( $cached ) && !empty( $cached['plan_id'] ) ) {
            if ( !defined( 'WP_DEBUG' ) || !WP_DEBUG ) {
                return $cached;
            }
        }
        $monthly_price = '19.99';
        $yearly_price = '191.88';
        $plan_id = '13840';
        // Fallback to a valid Freemius plan ID structure just in case
        $found_internal = false;
        if ( function_exists( 'sahldesk_fs' ) ) {
            $fs = sahldesk_fs();
            // Fetch dynamically from the public Freemius checkout page
            // This is robust, requires no API secret keys, and works for any customer automatically
            try {
                $plugin_id = $fs->get_id();
                $public_key = $fs->get_public_key();
                $checkout_url = "https://checkout.freemius.com/?billing_cycle=annual&plugin_id={$plugin_id}&public_key={$public_key}&_nocache=" . time();
                $response = wp_remote_get( $checkout_url, [
                    'timeout' => 15,
                ] );
                if ( !is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) === 200 ) {
                    $html = wp_remote_retrieve_body( $response );
                    // Extract prices
                    if ( preg_match( '/&quot;monthly_price&quot;:([0-9.]+),&quot;annual_price&quot;:([0-9.]+)/', $html, $matches ) ) {
                        $monthly_price = $matches[1];
                        $yearly_price = $matches[2];
                    }
                    // Extract the Pro plan ID
                    if ( preg_match( '/&quot;plan_id&quot;:&quot;([0-9]+)&quot;/', $html, $matches ) ) {
                        $plan_id = $matches[1];
                        $found_internal = true;
                    }
                }
            } catch ( Throwable $e ) {
            }
        }
        $is_arabic = get_user_locale() === 'ar' || get_locale() === 'ar' || is_rtl();
        $pricing_data = [
            'monthly'       => $monthly_price,
            'yearly'        => $yearly_price,
            'plan_id'       => $plan_id,
            'currency'      => '$',
            'free_features' => [
                ( $is_arabic ? 'إضافة خفيفة (يتم حفظ البيانات سحابياً)' : 'Thin Plugin (Data Stored on Cloud)' ),
                ( $is_arabic ? 'لوحة تحكم العميل' : 'The Customer Dashboard' ),
                ( $is_arabic ? 'إنشاء التذاكر' : 'Create Tickets' ),
                ( $is_arabic ? 'أداة المحادثة العائمة للزوار' : 'The Floating Guest Widget' ),
                ( $is_arabic ? 'إشعارات البريد الإلكتروني' : 'Email Notifications' ),
                ( $is_arabic ? 'وصول لمدير واحد' : 'Single Admin Access' ),
                ( $is_arabic ? 'دعم كامل باللغتين العربية والإنجليزية' : 'Full English & Arabic Support' )
            ],
            'pro_features'  => [
                ( $is_arabic ? 'جميع الميزات المجانية' : 'All Free Features' ),
                ( $is_arabic ? 'إدارة الموظفين والوكلاء' : 'Staff and Agent Management' ),
                ( $is_arabic ? 'سجل طلبات WooCommerce' : 'WooCommerce Order History' ),
                ( $is_arabic ? 'زر الإرجاع لـ WooCommerce' : 'WooCommerce RMA Button' ),
                ( $is_arabic ? 'الردود الجاهزة' : 'Canned Responses' ),
                ( $is_arabic ? 'التقارير والتحليلات' : 'Reports and Analytics' ),
                ( $is_arabic ? 'تصنيفات مخصصة' : 'Custom Categories' ),
                ( $is_arabic ? 'حالات فرعية مخصصة' : 'Custom Sub Status' ),
                ( $is_arabic ? 'تحويل البريد الإلكتروني إلى تذكرة' : 'Email To Ticket' )
            ],
        ];
        if ( $found_internal && !empty( $pricing_data['plan_id'] ) ) {
            if ( !defined( 'WP_DEBUG' ) || !WP_DEBUG ) {
                set_transient( 'ts_fs_plans_cache_v6', $pricing_data, 12 * HOUR_IN_SECONDS );
            } else {
                // Delete cache during debug so it's always fresh
                delete_transient( 'ts_fs_plans_cache_v6' );
            }
        }
        return $pricing_data;
    }

}
if ( !function_exists( 'ts_render_custom_upgrade_page' ) ) {
    function ts_render_custom_upgrade_page() {
        if ( defined( 'TS_IS_PRO' ) && TS_IS_PRO ) {
            // If they just upgraded, Freemius redirects here. Send them to the main settings page.
            echo '<script>window.location.replace("' . esc_url_raw( admin_url( 'admin.php?page=ts_settings_page' ) ) . '");</script>';
            return;
        }
        $is_arabic = strpos( get_locale(), 'ar' ) === 0;
        $lang = ( $is_arabic ? 'ar' : 'en' );
        $upgrade_url = ( function_exists( 'sahldesk_fs' ) ? sahldesk_fs()->checkout_url( 12, false, [
            'language' => $lang,
            'locale'   => $lang,
        ] ) : '#' );
        $monthly_url = ( function_exists( 'sahldesk_fs' ) ? sahldesk_fs()->checkout_url( 1, false, [
            'language' => $lang,
            'locale'   => $lang,
        ] ) : '#' );
        $pricing = ts_get_freemius_plans_data();
        // We can also use Freemius specific checkout URLs for Monthly vs Annual if needed,
        // but the generic upgrade URL automatically handles the Freemius UI gracefully.
        ?>
    <div class="wrap ts-upgrade-wrap" style="max-width: 1000px; margin: 40px auto; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;">
        
        <div style="text-align: center; margin-bottom: 50px;">
            <div style="font-size: 60px; margin-bottom: 10px; animation: float 3s ease-in-out infinite;">🚀</div>
            <h1 style="font-size: 42px; font-weight: 800; color: #1e293b; letter-spacing: -1px; margin-bottom: 15px;"><?php 
        echo esc_html( ts_t( 'Unlock Your Full Potential' ) );
        ?></h1>
            <p style="font-size: 18px; color: #64748b; max-width: 600px; margin: 0 auto; line-height: 1.6;"><?php 
        echo esc_html( ts_t( 'Upgrade to SahlDesk Pro and get access to powerful features designed to supercharge your customer support.' ) );
        ?></p>
        </div>

        
        
<div style="display: flex; justify-content: center; align-items: center; margin-bottom: 40px; gap: 15px;">
            <span style="font-size: 16px; font-weight: 600; color: #64748b;" id="billing-monthly-label"><?php 
        echo esc_html( ts_t( 'Billed Monthly' ) );
        ?></span>
            <label class="ts-switch">
                <input type="checkbox" id="billing-toggle" checked>
                <span class="ts-slider ts-round"></span>
            </label>
            <span style="font-size: 16px; font-weight: 600; color: #1e293b;" id="billing-yearly-label"><?php 
        echo esc_html( ts_t( 'Billed Annually' ) );
        ?> <span style="background: #10b981; color: white; padding: 2px 8px; border-radius: 12px; font-size: 12px; margin-left: 5px;"><?php 
        echo esc_html( ts_t( 'Save 20%' ) );
        ?></span></span>
        </div>

        <div style="display: flex; gap: 30px; justify-content: center; flex-wrap: wrap;">
            <!-- FREE PLAN -->
            <div class="ts-pricing-card" style="flex: 1; min-width: 300px; max-width: 400px; background: #ffffff; border-radius: 24px; padding: 40px; box-shadow: 0 10px 25px rgba(0,0,0,0.05); border: 1px solid #e2e8f0; position: relative;">
                <h3 style="font-size: 24px; font-weight: 700; color: #1e293b; margin-top: 0; margin-bottom: 10px;"><?php 
        echo esc_html( ts_t( 'Free' ) );
        ?></h3>
                <p style="color: #64748b; font-size: 15px; margin-bottom: 30px; height: 45px;"><?php 
        echo esc_html( ts_t( 'Perfect for getting started with basic ticketing.' ) );
        ?></p>
                
                <div style="font-size: 48px; font-weight: 800; color: #1e293b; margin-bottom: 30px;">
                    $0<span style="font-size: 16px; font-weight: 500; color: #94a3b8;">/<?php 
        echo esc_html( ts_t( 'forever' ) );
        ?></span>
                </div>

                <ul style="list-style: none; padding: 0; margin: 0 0 40px 0;">
                    <?php 
        foreach ( $pricing['free_features'] as $feature ) {
            ?>
                        <li style="margin-bottom: 15px; display: flex; align-items: center; color: #475569; font-size: 15px;">
                            <svg style="width: 20px; height: 20px; color: #10b981; margin-right: 12px; margin-left: <?php 
            echo esc_html( ( is_rtl() ? '12px' : '0' ) );
            ?>; flex-shrink: 0;" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path></svg>
                            <?php 
            echo esc_html( $feature );
            ?>
                        </li>
                    <?php 
        }
        ?>
                </ul>
                <button disabled style="width: 100%; padding: 14px; border-radius: 12px; background: #f1f5f9; color: #94a3b8; border: none; font-size: 16px; font-weight: 600; cursor: not-allowed;"><?php 
        echo esc_html( ts_t( 'Current Plan' ) );
        ?></button>
            </div>

            <!-- PRO PLAN -->
            <div class="ts-pricing-card ts-pro-card" style="flex: 1; min-width: 300px; max-width: 400px; background: linear-gradient(145deg, #1e293b, #0f172a); border-radius: 24px; padding: 40px; box-shadow: 0 20px 40px rgba(59,130,246,0.2); border: 1px solid #334155; position: relative; overflow: hidden;">
                <div style="position: absolute; top: 0; left: 0; right: 0; height: 4px; background: linear-gradient(90deg, #3b82f6, #8b5cf6);"></div>
                <div style="position: absolute; top: 20px; <?php 
        echo esc_html( ( is_rtl() ? 'left: 20px;' : 'right: 20px;' ) );
        ?> background: rgba(59,130,246,0.2); color: #60a5fa; padding: 4px 12px; border-radius: 20px; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 1px;"><?php 
        echo esc_html( ts_t( 'Most Popular' ) );
        ?></div>
                
                <h3 style="font-size: 24px; font-weight: 700; color: #ffffff; margin-top: 0; margin-bottom: 10px;"><?php 
        echo esc_html( ts_t( 'Pro' ) );
        ?></h3>
                <p style="color: #94a3b8; font-size: 15px; margin-bottom: 30px; height: 45px;"><?php 
        echo esc_html( ts_t( 'Advanced tools for growing teams and businesses.' ) );
        ?></p>
                
                <div style="font-size: 48px; font-weight: 800; color: #ffffff; margin-bottom: 30px;" id="pro-price-display">
                    <?php 
        echo esc_html( $pricing['currency'] );
        ?><span id="pro-price-amount" data-monthly="<?php 
        echo esc_attr( $pricing['monthly'] );
        ?>" data-yearly="<?php 
        echo esc_attr( $pricing['yearly'] );
        ?>"><?php 
        echo esc_html( $pricing['yearly'] );
        ?></span><span style="font-size: 16px; font-weight: 500; color: #64748b;">/<span id="pro-price-period" data-mo="<?php 
        echo esc_attr( ts_t( 'mo' ) );
        ?>" data-yr="<?php 
        echo esc_attr( ts_t( 'yr' ) );
        ?>"><?php 
        echo esc_html( ts_t( 'yr' ) );
        ?></span></span>
                </div>

                <ul style="list-style: none; padding: 0; margin: 0 0 40px 0;">
                    <?php 
        foreach ( $pricing['pro_features'] as $feature ) {
            ?>
                        <li style="margin-bottom: 15px; display: flex; align-items: center; color: #ffffff; font-size: 15px; font-weight: 500;">
                            <svg style="width: 20px; height: 20px; color: #8b5cf6; margin-right: 12px; margin-left: <?php 
            echo esc_html( ( is_rtl() ? '12px' : '0' ) );
            ?>; flex-shrink: 0;" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path></svg>
                            <?php 
            echo esc_html( $feature );
            ?>
                        </li>
                    <?php 
        }
        ?>
                </ul>

                <a id="ts-upgrade-btn" href="javascript:void(0);" onclick="open_checkout();"  class="ts-upgrade-btn" style="display: block; width: 100%; text-align: center; padding: 16px; border-radius: 12px; background: linear-gradient(90deg, #3b82f6, #6366f1); color: #ffffff; text-decoration: none; font-size: 18px; font-weight: 700; box-shadow: 0 10px 20px rgba(59,130,246,0.3); transition: all 0.3s ease; box-sizing: border-box;"><?php 
        echo esc_html( ts_t( 'Upgrade Now' ) );
        ?></a>
            </div>
        </div>
    </div>

    <script type="text/javascript">
        (function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(d.getElementById(id))return;js=d.createElement(s);js.id=id;js.src="https://checkout.freemius.com/checkout.min.js";fjs.parentNode.insertBefore(js,fjs);}(document,'script','freemius-checkout-js'));

        var fs_checkout_handler = null;
        
        // Pre-initialize Freemius Checkout to reduce popup load time
        function init_freemius_handler() {
            if (typeof FS !== 'undefined' && typeof FS.Checkout !== 'undefined' && !fs_checkout_handler) {
                fs_checkout_handler = FS.Checkout.configure({
                    plugin_id:  '23268',
                    public_key: 'pk_22da665e521f5fdea813737e64420',
                    locale:     '<?php 
        echo esc_js( $lang );
        ?>'
                });
            }
        }

        // Try initializing when window loads
        window.addEventListener('load', function() {
            setTimeout(init_freemius_handler, 500);
        });

        function open_checkout() {
            var btn = document.getElementById('ts-upgrade-btn');
            var originalText = btn.innerHTML;
            
            // Show loading state immediately to improve perceived performance
            btn.innerHTML = '<?php 
        /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
        echo esc_js( ts_t( "Loading..." ) );
        ?> <span class="dashicons dashicons-update" style="animation: ts-spin 1s linear infinite; vertical-align: middle;"></span>';
            btn.style.opacity = '0.8';
            btn.style.pointerEvents = 'none';

            var is_yearly = document.getElementById('billing-toggle').checked;
            
            // Fallback initialization if it hasn't happened yet
            init_freemius_handler();
            
            if ( fs_checkout_handler ) {
                fs_checkout_handler.open({
                    name     : 'SahlDesk Pro',
                    plan_id  : '<?php 
        echo esc_js( $pricing['plan_id'] );
        ?>',
                    licenses : 1,
                    billing_cycle: is_yearly ? 'annual' : 'monthly',
                    <?php 
        if ( function_exists( 'sahldesk_fs' ) && sahldesk_fs()->is_registered() ) {
            ?>
                    user_email: '<?php 
            echo esc_js( sahldesk_fs()->get_user()->email );
            ?>',
                    user_firstname: '<?php 
            echo esc_js( sahldesk_fs()->get_user()->first );
            ?>',
                    user_lastname: '<?php 
            echo esc_js( sahldesk_fs()->get_user()->last );
            ?>',
                    user_id  : '<?php 
            echo esc_js( sahldesk_fs()->get_user()->id );
            ?>',
                    site_id  : '<?php 
            echo esc_js( sahldesk_fs()->get_site()->id );
            ?>',
                    
                    <?php 
            if ( class_exists( 'FS_Security' ) ) {
                $timestamp = time();
                $site = sahldesk_fs()->get_site();
                echo "s_ctx_type: '" . esc_js( $site->get_type() ) . "',\n";
                echo "s_ctx_id: '" . esc_js( $site->id ) . "',\n";
                echo "s_ctx_ts: '" . esc_js( $timestamp ) . "',\n";
                echo "s_ctx_secure: '" . esc_js( FS_Security::instance()->get_secure_token( $site, $timestamp, 'checkout' ) ) . "',\n";
            }
            ?>
                    <?php 
        }
        ?>
                    success  : function (response) {
                        // LOG THE RESPONSE FOR DEBUGGING (BLOCK UNTIL DONE)
                        jQuery.post(ajaxurl, {
                            action: 'ts_log_freemius_response',
                            response: JSON.stringify(response)
                        }).always(function() {
                            <?php 
        $install_url = '';
        $sync_url = '';
        $account_sync_url = '';
        if ( function_exists( 'sahldesk_fs' ) ) {
            $install_url = fs_nonce_url( add_query_arg( array(
                'fs_action' => sahldesk_fs()->get_unique_affix() . '_activate_new',
                'plugin_id' => sahldesk_fs()->get_id(),
            ), admin_url( 'admin.php?page=ts_settings_page' ) ), sahldesk_fs()->get_unique_affix() . '_activate_new' );
            $sync_url = fs_nonce_url( add_query_arg( array(
                'fs_action' => sahldesk_fs()->get_unique_affix() . '_sync_license',
            ), admin_url( 'admin.php?page=ts_settings_page' ) ), sahldesk_fs()->get_unique_affix() . '_sync_license' );
            $account_sync_url = fs_nonce_url( add_query_arg( array(
                'fs_action' => sahldesk_fs()->get_unique_affix() . '_sync_license',
            ), sahldesk_fs()->get_account_url() ), sahldesk_fs()->get_unique_affix() . '_sync_license' );
        }
        ?>
                            var installUrl = '<?php 
        echo esc_url_raw( $install_url );
        ?>';
                            var accountSyncUrl = '<?php 
        echo esc_url_raw( $account_sync_url );
        ?>';
                            var isRegistered = <?php 
        /* phpcs:ignore WordPress.Security.EscapeOutput, WordPress.Security.EscapeOutput.OutputNotEscaped */
        echo ( function_exists( 'sahldesk_fs' ) && sahldesk_fs()->is_registered() ? 'true' : 'false' );
        ?>;
                            
                            // Decode stray HTML entities
                            var txt = document.createElement("textarea");
                            txt.innerHTML = installUrl;
                            installUrl = txt.value;
                            txt.innerHTML = syncUrl;
                            syncUrl = txt.value;
                            txt.innerHTML = accountSyncUrl;
                            accountSyncUrl = txt.value;
                            

                            var tsShowLoader = function() {
                                var overlay = document.createElement("div");
                                overlay.style.position = "fixed";
                                overlay.style.top = "0";
                                overlay.style.left = "0";
                                overlay.style.width = "100%";
                                overlay.style.height = "100%";
                                overlay.style.backgroundColor = "rgba(255, 255, 255, 0.95)";
                                overlay.style.zIndex = "999999";
                                overlay.style.display = "flex";
                                overlay.style.flexDirection = "column";
                                overlay.style.justifyContent = "center";
                                overlay.style.alignItems = "center";
                                
                                var spinner = document.createElement("div");
                                spinner.style.width = "60px";
                                spinner.style.height = "60px";
                                spinner.style.border = "5px solid #f3f3f3";
                                spinner.style.borderTop = "5px solid #2563eb";
                                spinner.style.borderRadius = "50%";
                                spinner.style.animation = "ts-spin 1s linear infinite";
                                
                                var text = document.createElement("h2");
                                text.innerText = "<?php 
        /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
        echo esc_js( ts_t( 'Activating SahlDesk Pro...' ) );
        ?>";
                                text.style.marginTop = "25px";
                                text.style.fontFamily = "Inter, sans-serif";
                                text.style.color = "#1e293b";
                                text.style.fontWeight = "700";
                                
                                var subtext = document.createElement("p");
                                subtext.innerText = "<?php 
        /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
        echo esc_js( ts_t( 'Please wait while we securely install your premium features. This may take a few seconds.' ) );
        ?>";
                                subtext.style.color = "#64748b";
                                subtext.style.marginTop = "10px";
                                subtext.style.fontFamily = "Inter, sans-serif";
                                
                                var style = document.createElement("style");
                                style.innerHTML = "@keyframes ts-spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }";
                                
                                document.head.appendChild(style);
                                overlay.appendChild(spinner);
                                overlay.appendChild(text);
                                overlay.appendChild(subtext);
                                document.body.appendChild(overlay);
                            };
                            
                            if (installUrl && response && response.user && response.install) {
                                function silentInstallAndRedirect() {
                                    var installData = {
                                        action: '<?php 
        echo esc_attr( sahldesk_fs()->get_ajax_action( "install_premium_version" ) );
        ?>',
                                        security: '<?php 
        echo esc_attr( sahldesk_fs()->get_ajax_security( "install_premium_version" ) );
        ?>',
                                        module_id: '<?php 
        echo esc_attr( sahldesk_fs()->get_id() );
        ?>',
                                        target_module_id: '<?php 
        echo esc_attr( sahldesk_fs()->get_id() );
        ?>'
                                    };
                                    jQuery.post(ajaxurl, installData, function(res) {
                                        var isError = false;
                                        var errMsg = "";
                                        if (typeof res === 'string') {
                                            var jsonMatch = res.match(/\{.*\}/s);
                                            if (jsonMatch) {
                                                try {
                                                    var parsed = JSON.parse(jsonMatch[0]);
                                                    if (parsed && parsed.success === false) {
                                                        isError = true;
                                                        errMsg = parsed.error ? parsed.error.message : JSON.stringify(parsed);
                                                    }
                                                } catch(e) {}
                                            } else {
                                                isError = true;
                                                errMsg = res.replace(/(<([^>]+)>)/gi, "").substring(0, 500);
                                            }
                                        } else if (res && res.success === false) {
                                            isError = true;
                                            errMsg = res.error ? res.error.message : JSON.stringify(res);
                                        }
                                        jQuery.post(ajaxurl, { action: 'ts_log_install_result', log: 'Install response: ' + (typeof res === 'string' ? res : JSON.stringify(res)) }).always(function() {
											  if (isError) {
                                            alert("Auto-install failed. Please contact support with this error:\n\n" + errMsg);
                                        }
                                        window.location.href = accountSyncUrl;
										  });
                                    }).fail(function(xhr) {
                                        jQuery.post(ajaxurl, { action: 'ts_log_install_result', log: 'FAIL from Freemius install_premium_version: ' + xhr.statusText }).always(function() {
											  alert("Installation AJAX request failed: " + xhr.statusText);
                                        window.location.href = accountSyncUrl;
										  });
                                    });
                                }

                                if (!isRegistered) {
                                    tsShowLoader();
                                    
                                    var data = {
                                        user_id           : response.user.id,
                                        user_secret_key   : response.user.secret_key,
                                        user_public_key   : response.user.public_key,
                                        install_id        : response.install.id,
                                        install_secret_key: response.install.secret_key,
                                        install_public_key: response.install.public_key,
                                        auto_install      : 'true'
                                    };
                                    
                                    // 1. Pair the site with Freemius
                                    jQuery.post(installUrl, data).always(function() {
                                        // 2. Sync license to flush cache and update local DB to Pro
                                        jQuery.ajax({ url: accountSyncUrl, type: 'GET', cache: false }).always(function() {
                                            // 3. Silently install the Pro plugin via AJAX
                                            silentInstallAndRedirect();
                                        });
                                    });
                                } else {
                                    tsShowLoader();
                                    // 1. Sync license via fetch to flush cache.
                                    jQuery.ajax({ url: accountSyncUrl, type: 'GET', cache: false }).always(function() {
                                        // 2. Silently install the Pro plugin via AJAX
                                        silentInstallAndRedirect();
                                    });
                                }
                            } else if (syncUrl) {
                                // Since response.install is stripped by Freemius for security, but the purchase was
                                // successfully linked to our install on their backend, we just need to force WordPress
                                // to bypass its local 1-hour cache and fetch the newly purchased license immediately.
                                tsShowLoader(); window.location.href = syncUrl;
                            } else {
                                window.location.reload();
                            }
                        });
                    },
                    cancel: function() {
                        // Reset button if popup is closed manually
                        btn.innerHTML = originalText;
                        btn.style.opacity = '1';
                        btn.style.pointerEvents = 'auto';
                    }
                });
                
                // Freemius handles its own overlay loader after a moment, so we restore the button shortly
                setTimeout(function() {
                    btn.innerHTML = originalText;
                    btn.style.opacity = '1';
                    btn.style.pointerEvents = 'auto';
                }, 2500);
            } else {
                // If it completely failed to load
                btn.innerHTML = originalText;
                btn.style.opacity = '1';
                btn.style.pointerEvents = 'auto';
                alert('<?php 
        /* phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped */
        echo esc_js( ts_t( "Checkout is still loading, please try again in a moment." ) );
        ?>');
            }
        }
    </script>

    <style>
        @keyframes ts-spin { 100% { transform: rotate(360deg); } }
        @keyframes float {
            0% { transform: translateY(0px); }
            50% { transform: translateY(-10px); }
            100% { transform: translateY(0px); }
        }
        .ts-upgrade-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 15px 25px rgba(59,130,246,0.4) !important;
            color: white !important;
        }
        .ts-pricing-card {
            transition: transform 0.3s ease;
        }
        .ts-pricing-card:hover {
            transform: translateY(-5px);
        }
        
        /* Toggle Switch Styles */
        .ts-switch {
            position: relative;
            display: inline-block;
            width: 60px;
            height: 34px;
        }
        .ts-switch input { 
            opacity: 0;
            width: 0;
            height: 0;
        }
        .ts-slider {
            position: absolute;
            cursor: pointer;
            top: 0; left: 0; right: 0; bottom: 0;
            background-color: #cbd5e1;
            transition: .4s;
        }
        .ts-slider:before {
            position: absolute;
            content: "";
            height: 26px;
            width: 26px;
            left: 4px;
            bottom: 4px;
            background-color: white;
            transition: .4s;
        }
        input:checked + .ts-slider {
            background-color: #3b82f6;
        }
        input:focus + .ts-slider {
            box-shadow: 0 0 1px #3b82f6;
        }
        <?php 
        if ( is_rtl() ) {
            ?>
        .ts-slider:before {
            right: 4px;
            left: auto;
        }
        input:checked + .ts-slider:before {
            transform: translateX(-26px);
        }
        <?php 
        } else {
            ?>
        input:checked + .ts-slider:before {
            transform: translateX(26px);
        }
        <?php 
        }
        ?>
        .ts-slider.ts-round {
            border-radius: 34px;
        }
        .ts-slider.ts-round:before {
            border-radius: 50%;
        }
    </style>

    
    <?php 
    }

}
// =================================================================
// AJAX Magic Link Handler (Bypasses Page Caching)
// =================================================================
add_action( 'wp_head', 'ts_magic_link_js_handler', 1 );
if ( !function_exists( 'ts_magic_link_js_handler' ) ) {
    function ts_magic_link_js_handler() {
        ?>
    <?php 
    }

}
add_action( 'wp_ajax_nopriv_ts_process_magic_link', 'ts_ajax_process_magic_link' );
add_action( 'wp_ajax_ts_process_magic_link', 'ts_ajax_process_magic_link' );
if ( !function_exists( 'ts_ajax_process_magic_link' ) ) {
    function ts_ajax_process_magic_link() {
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        if ( !isset( $_POST['magic_token'] ) ) {
            wp_send_json_error( 'No token provided' );
        }
        // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
        $magic_token = sanitize_text_field( wp_unslash( $_POST['magic_token'] ) );
        $api_url = TS_API_BASE_URL . '/users/magic-login';
        $api_key = get_option( 'ts_tenant_api_key', '' );
        $domain = get_option( 'ts_tenant_domain', '' );
        $response = wp_remote_post( $api_url, [
            'headers'     => [
                'Content-Type'    => 'application/json',
                'X-Api-Key'       => $api_key,
                'X-Client-Domain' => $domain,
            ],
            'body'        => json_encode( [
                'Token' => $magic_token,
            ] ),
            'data_format' => 'body',
            'timeout'     => 15,
        ] );
        if ( !is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) == 200 ) {
            $body = json_decode( wp_remote_retrieve_body( $response ), true );
            if ( isset( $body['token'] ) ) {
                if ( !session_id() ) {
                    session_start();
                }
                $_SESSION['ts_auth_token'] = $body['token'];
                $_SESSION['ts_user_role'] = $body['role'];
                $_SESSION['ts_user_name'] = $body['name'];
                session_write_close();
                // Set cookies to survive edge caching stripping PHPSESSID
                setcookie(
                    'wordpress_logged_in_ts_auth_token',
                    $body['token'],
                    time() + 86400 * 7,
                    COOKIEPATH,
                    COOKIE_DOMAIN,
                    is_ssl(),
                    true
                );
                setcookie(
                    'wordpress_logged_in_ts_user_role',
                    $body['role'],
                    time() + 86400 * 7,
                    COOKIEPATH,
                    COOKIE_DOMAIN,
                    is_ssl(),
                    true
                );
                if ( isset( $body['name'] ) ) {
                    setcookie(
                        'wordpress_logged_in_ts_user_name',
                        $body['name'],
                        time() + 86400 * 7,
                        COOKIEPATH,
                        COOKIE_DOMAIN,
                        is_ssl(),
                        true
                    );
                }
                $lang = get_locale();
                $dash_url = ( strpos( $lang, 'ar' ) === 0 ? ts_get_page_url( 'support-dashboard-ar', 'Support Dashboard AR' ) : ts_get_page_url( 'support-dashboard', 'Support Dashboard' ) );
                wp_send_json_success( [
                    'token'        => $body['token'],
                    'role'         => $body['role'],
                    'name'         => ( isset( $body['name'] ) ? $body['name'] : '' ),
                    'redirect_url' => $dash_url,
                ] );
            } else {
                wp_send_json_error( 'Invalid response format' );
            }
        } else {
            $error_msg = ( is_wp_error( $response ) ? $response->get_error_message() : wp_remote_retrieve_body( $response ) );
            wp_send_json_error( $error_msg );
        }
    }

}
// Notification for Pending Activation
add_action( 'admin_notices', 'ts_pending_activation_notice' );
if ( !function_exists( 'ts_pending_activation_notice' ) ) {
    function ts_pending_activation_notice() {
        $is_pending = false;
        if ( function_exists( 'sahldesk_fs' ) ) {
            if ( sahldesk_fs()->is_pending_activation() ) {
                $is_pending = true;
            } else {
                // Check Freemius sticky notices directly from DB since it clears the runtime flag
                $fs_options = get_option( 'fs_options' );
                if ( is_array( $fs_options ) && isset( $fs_options['admin_notices'] ) && isset( $fs_options['admin_notices']['activation_pending'] ) ) {
                    $is_pending = true;
                }
            }
        }
        if ( $is_pending ) {
            ?>
            <div class="notice notice-warning ts-pending-notice" style="background: #fff3cd !important; border-left: 4px solid #f59e0b !important; padding: 12px !important; margin: 15px 15px 15px 0 !important; box-shadow: 0 1px 1px rgba(0,0,0,.04) !important; display: block !important; opacity: 1 !important; visibility: visible !important; position: relative;">
                <p><strong><?php 
            echo esc_html( ts_t( 'SahlDesk:' ) );
            ?></strong> <?php 
            echo esc_html( ts_t( 'Please check your email from SahlDesk (and your spam folder) to complete your opt-in for Freemius.' ) );
            ?></p>
                <button type="button" class="notice-dismiss" onclick="this.parentElement.style.display='none';"><span class="screen-reader-text">Dismiss this notice.</span></button>
            </div>
            <?php 
        }
    }

}