<?php

declare(strict_types=1);


namespace ProRank\SEO\Core\RestApi;

use WP_REST_Controller;
use WP_REST_Server;
use WP_REST_Response;
use WP_Error;

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




class CdnSetupController extends WP_REST_Controller {
    protected $namespace = 'prorank-seo/v1';
    protected $rest_base = 'cdn-setup';

    public function register_routes() {
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/check',
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [ $this, 'check' ],
                'permission_callback' => [ $this, 'permissions_check' ],
            ]
        );
    }

    public function permissions_check() {
        if ( ! current_user_can( 'manage_options' ) ) {
            return new WP_Error( 'rest_forbidden', __( 'You do not have permission to check CDN setup.', 'prorank-seo' ), [ 'status' => 403 ] );
        }
        return true;
    }

    public function check() {
        try {
            $url = home_url( '/' );
            $response = wp_remote_get( $url, [ 'timeout' => 10 ] );

            if ( is_wp_error( $response ) ) {
                return new WP_Error(
                    'cdn_setup_failed',
/* translators: %1$: value */
                    sprintf( __( 'CDN edge check failed: %1$s', 'prorank-seo' ), $response->get_error_message() ),
                    [ 'status' => 502 ]
                );
            }

            $headers = wp_remote_retrieve_headers( $response );
            $status  = wp_remote_retrieve_response_code( $response );

            $summary = [
                'url' => $url,
                'status' => $status,
                'cache_status' => $headers['cf-cache-status'] ?? $headers['x-cache'] ?? null,
                'server' => $headers['server'] ?? null,
                'brotli' => isset( $headers['content-encoding'] ) && $headers['content-encoding'] === 'br',
                'http3' => isset( $headers['alt-svc'] ) && strpos( $headers['alt-svc'], 'h3' ) !== false,
                'ray' => $headers['cf-ray'] ?? null,
                'warnings' => $this->build_warnings( $headers ),
                'timing_ms' => $this->extract_timing( $response ),
            ];

            return new WP_REST_Response( [ 'success' => true, 'summary' => $summary ], 200 );
        } catch ( \Throwable $e ) {
            prorank_log( 'ProRank CDN setup check exception: ' . $e->getMessage() );
            return new WP_Error(
                'cdn_setup_exception',
/* translators: %1$: value */
                sprintf( __( 'CDN setup check failed: %1$s', 'prorank-seo' ), $e->getMessage() ),
                [ 'status' => 500 ]
            );
        }
    }

    private function build_warnings( $headers ): array {
        $warnings = [];
        if ( empty( $headers['cf-cache-status'] ) && empty( $headers['x-cache'] ) ) {
            $warnings[] = __( 'No cache status header detected. CDN may be bypassed.', 'prorank-seo' );
        }
        if ( isset( $headers['content-encoding'] ) && $headers['content-encoding'] !== 'br' ) {
            $warnings[] = __( 'Brotli not detected. Consider enabling br compression.', 'prorank-seo' );
        }
        if ( empty( $headers['alt-svc'] ) || strpos( $headers['alt-svc'], 'h3' ) === false ) {
            $warnings[] = __( 'HTTP/3 not detected. Enable HTTP/3/QUIC on CDN.', 'prorank-seo' );
        }
        return $warnings;
    }

    /**
     * Extract timing (ms) from response if available
     */
    private function extract_timing( $response ): ?float {
        // Prefer X-Response-Time header if present
        $header_time = wp_remote_retrieve_header( $response, 'x-response-time' );
        if ( $header_time ) {
            $numeric = floatval( preg_replace( '/[^0-9.]/', '', (string) $header_time ) );
            return $numeric > 0 ? $numeric : null;
        }

        // Fallback to Requests total_time if available
        if ( isset( $response['http_response'] ) && is_object( $response['http_response'] ) ) {
            $raw = $response['http_response']->get_response_object();
            if ( isset( $raw->info['total_time'] ) ) {
                return round( floatval( $raw->info['total_time'] ) * 1000, 2 );
            }
        }

        return null;
    }
}
