<?php
// phpcs:disable WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class YATOON_Performance {
    private static $started_at = 0;
    private static $action = '';

    public static function init() {
        self::install_schema();
        add_action( 'init', array( __CLASS__, 'begin_request' ), 1 );
        add_action( 'admin_menu', array( __CLASS__, 'add_menu' ), 23 );
        add_action( 'yatoon_cleanup_performance', array( __CLASS__, 'cleanup' ) );
        if ( ! wp_next_scheduled( 'yatoon_cleanup_performance' ) ) {
            wp_schedule_event( time() + DAY_IN_SECONDS, 'daily', 'yatoon_cleanup_performance' );
        }
    }

    private static function install_schema() {
        global $wpdb;
        if ( get_option( 'yatoon_performance_schema', '' ) === YATOON_DB_VERSION ) return;
        require_once ABSPATH . 'wp-admin/includes/upgrade.php';
        $charset = $wpdb->get_charset_collate();
        dbDelta( "CREATE TABLE {$wpdb->prefix}yatoon_performance (
            id bigint(20) NOT NULL AUTO_INCREMENT,
            action_name varchar(80) NOT NULL,
            duration_ms int(11) NOT NULL,
            memory_mb decimal(8,2) DEFAULT 0,
            response_code int(11) DEFAULT 200,
            created_at datetime DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            KEY action_created (action_name,created_at)
        ) {$charset};" );
        update_option( 'yatoon_performance_schema', YATOON_DB_VERSION, false );
    }

    public static function begin_request() {
        $action = isset( $_REQUEST['action'] ) ? sanitize_key( wp_unslash( $_REQUEST['action'] ) ) : '';
        $tracked = array( 'yatoon_create_booking', 'yatoon_upload_design_reference', 'yatoon_get_available_times', 'yatoon_get_available_staff', 'yatoon_get_service_options' );
        if ( ! in_array( $action, $tracked, true ) ) return;
        self::$started_at = microtime( true );
        self::$action = $action;
        register_shutdown_function( array( __CLASS__, 'finish_request' ) );
    }

    public static function finish_request() {
        if ( ! self::$started_at || ! self::$action ) return;
        global $wpdb;
        $wpdb->insert(
            $wpdb->prefix . 'yatoon_performance',
            array(
                'action_name' => self::$action,
                'duration_ms' => (int) round( ( microtime( true ) - self::$started_at ) * 1000 ),
                'memory_mb' => round( memory_get_peak_usage( true ) / 1048576, 2 ),
                'response_code' => http_response_code() ?: 200,
                'created_at' => current_time( 'mysql', true ),
            ),
            array( '%s', '%d', '%f', '%d', '%s' )
        );
    }

    public static function cleanup() {
        global $wpdb;
        $wpdb->query(
            "DELETE FROM {$wpdb->prefix}yatoon_performance
             WHERE created_at < UTC_TIMESTAMP() - INTERVAL 90 DAY"
        );
    }

    public static function add_menu() {
        add_submenu_page( 'yatoon-booking-system', 'Performance', 'Performance', 'manage_options', 'yatoon-performance', array( __CLASS__, 'render' ) );
    }

    public static function render() {
        global $wpdb;
        $stats = $wpdb->get_results(
            "SELECT action_name, COUNT(*) requests, ROUND(AVG(duration_ms)) average_ms,
             MAX(duration_ms) slowest_ms,
             SUM(CASE WHEN duration_ms >= 5000 THEN 1 ELSE 0 END) slow_requests
             FROM {$wpdb->prefix}yatoon_performance
             WHERE created_at >= UTC_TIMESTAMP() - INTERVAL 30 DAY
             GROUP BY action_name ORDER BY average_ms DESC"
        );
        $jobs = $wpdb->get_results(
            "SELECT * FROM {$wpdb->prefix}yatoon_jobs WHERE status IN ('failed','retry','running') ORDER BY id DESC LIMIT 50"
        );
        ?>
        <div class="wrap"><h1>Performance & Reliability</h1><p>Real request timings from the last 30 days. Use this page to find whether delays come from image upload, availability, or final confirmation.</p>
        <table class="widefat striped"><thead><tr><th>Request</th><th>Runs</th><th>Average</th><th>Slowest</th><th>Over 5 seconds</th></tr></thead><tbody>
        <?php if ( ! $stats ) : ?><tr><td colspan="5">No production timings recorded yet.</td></tr><?php endif; ?>
        <?php foreach ( $stats as $row ) : ?><tr><td><?php echo esc_html( str_replace( 'yatoon_', '', $row->action_name ) ); ?></td><td><?php echo absint( $row->requests ); ?></td><td><?php echo esc_html( number_format( $row->average_ms / 1000, 2 ) ); ?>s</td><td><?php echo esc_html( number_format( $row->slowest_ms / 1000, 2 ) ); ?>s</td><td><?php echo absint( $row->slow_requests ); ?></td></tr><?php endforeach; ?>
        </tbody></table><h2 style="margin-top:28px">Jobs needing attention</h2><table class="widefat striped"><thead><tr><th>ID</th><th>Type</th><th>Status</th><th>Attempts</th><th>Error</th><th></th></tr></thead><tbody>
        <?php if ( ! $jobs ) : ?><tr><td colspan="6">No failed or delayed background jobs.</td></tr><?php endif; ?>
        <?php foreach ( $jobs as $job ) : ?><tr><td>#<?php echo absint( $job->id ); ?></td><td><?php echo esc_html( $job->job_type ); ?></td><td><?php echo esc_html( $job->status ); ?></td><td><?php echo absint( $job->attempts ); ?></td><td><?php echo esc_html( $job->last_error ); ?></td><td><a class="button" href="<?php echo esc_url( wp_nonce_url( admin_url( 'admin-post.php?action=yatoon_retry_job&job_id=' . absint( $job->id ) ), 'yatoon_retry_job' ) ); ?>">Retry</a></td></tr><?php endforeach; ?>
        </tbody></table></div>
        <?php
    }
}
