<?php

namespace FleekDash\Controllers;

use WP_REST_Request;
use WP_REST_Response;
use WP_Error;
use FleekDash\Services\PerformanceAuditService;
use FleekDash\Core\AuthMiddleware;

/**
 * Performance Audit Controller
 *
 * Exposes performance audit data via REST API
 * Enables real-time bottleneck monitoring
 */
class PerformanceAuditController
{
    private PerformanceAuditService $auditService;

    public function __construct()
    {
        $this->auditService = new PerformanceAuditService();
    }

    /**
     * Get current performance report
     *
     * @param WP_REST_Request $_request REST callback signature - unused for GET
     */
    public function getPerformanceReport(WP_REST_Request $_request) // NOSONAR php:S1172 - WP REST callback
    {
        try {
            $auth = $this->checkAuth();

            $report = $this->auditService->getPerformanceReport();

            return new WP_REST_Response([
                'success' => true,
                'data' => $report,
                'timestamp' => \current_time('mysql'),
                'auth_status' => [
                    'authenticated' => $auth['authenticated'],
                    'fallback' => $auth['fallback']
                ]
            ], 200);

        } catch (\Exception $e) {
            return new WP_Error('audit_error', $e->getMessage(), ['status' => 500]);
        }
    }

    /**
     * Get detailed performance report
     *
     * @param WP_REST_Request $_request REST callback signature - unused for GET
     */
    public function getDetailedReport(WP_REST_Request $_request) // NOSONAR php:S1172 - WP REST callback
    {
        try {
            $auth = $this->checkAuth();

            $report = $this->auditService->exportDetailedReport();

            return new WP_REST_Response([
                'success' => true,
                'data' => $report,
                'timestamp' => \current_time('mysql'),
                'auth_status' => [
                    'authenticated' => $auth['authenticated'],
                    'fallback' => $auth['fallback']
                ]
            ], 200);

        } catch (\Exception $e) {
            return new WP_Error('audit_error', $e->getMessage(), ['status' => 500]);
        }
    }

    /**
     * Analyze specific endpoint performance
     */
    public function analyzeEndpoint(WP_REST_Request $request)
    {
        $endpoint = $request->get_param('endpoint');
        $result = null;

        if (!$endpoint) {
            $result = new WP_Error('missing_endpoint', 'Endpoint parameter is required', ['status' => 400]);
        } else {
            try {
                $auth = $this->checkAuth();
                $analysis = $this->auditService->analyzeEndpoint($endpoint);
                if (!$analysis) {
                    $result = new WP_Error(
                        'no_data',
                        'No performance data found for endpoint: ' . $endpoint,
                        ['status' => 404]
                    );
                } else {
                    $result = new WP_REST_Response([
                        'success' => true,
                        'data' => $analysis,
                        'timestamp' => \current_time('mysql'),
                        'auth_status' => [
                            'authenticated' => $auth['authenticated'],
                            'fallback' => $auth['fallback']
                        ]
                    ], 200);
                }
            } catch (\Exception $e) {
                $result = new WP_Error('audit_error', $e->getMessage(), ['status' => 500]);
            }
        }

        return $result;
    }

    /**
     * Reset audit data
     *
     * @param WP_REST_Request $_request REST callback signature - unused for POST
     */
    public function resetAudit(WP_REST_Request $_request) // NOSONAR php:S1172 - WP REST callback
    {
        try {
            $auth = $this->checkAuth();

            $this->auditService->reset();

            return new WP_REST_Response([
                'success' => true,
                'message' => 'Audit data reset successfully',
                'timestamp' => \current_time('mysql'),
                'auth_status' => [
                    'authenticated' => $auth['authenticated'],
                    'fallback' => $auth['fallback']
                ]
            ], 200);

        } catch (\Exception $e) {
            return new WP_Error('audit_error', $e->getMessage(), ['status' => 500]);
        }
    }

    /**
     * Get performance recommendations
     *
     * @param WP_REST_Request $_request REST callback signature - unused for GET
     */
    public function getRecommendations(WP_REST_Request $_request) // NOSONAR php:S1172 - WP REST callback
    {
        try {
            $auth = $this->checkAuth();

            $report = $this->auditService->getPerformanceReport();
            $recommendations = $report['recommendations'] ?? [];

            // Add system-specific recommendations
            $systemRecommendations = $this->getSystemRecommendations();
            $recommendations = array_merge($recommendations, $systemRecommendations);

            return new WP_REST_Response([
                'success' => true,
                'data' => [
                    'recommendations' => $recommendations,
                    'priority_order' => $this->getPriorityOrder($recommendations)
                ],
                'timestamp' => \current_time('mysql'),
                'auth_status' => [
                    'authenticated' => $auth['authenticated'],
                    'fallback' => $auth['fallback']
                ]
            ], 200);

        } catch (\Exception $e) {
            return new WP_Error('audit_error', $e->getMessage(), ['status' => 500]);
        }
    }

    /**
     * Check authentication
     */
    private function checkAuth($requiredLevel = 'authenticated')
    {
        try {
            $auth_check = AuthMiddleware::check($requiredLevel);
            if (!$auth_check['authenticated']) {
                return [
                    'authenticated' => false,
                    'user_id' => 0,
                    'fallback' => true,
                    'reason' => $auth_check['reason']
                ];
            }

            return [
                'authenticated' => true,
                'user_id' => $auth_check['user_id'],
                'fallback' => false
            ];

        } catch (\Exception $e) {
            return [
                'authenticated' => false,
                'user_id' => 0,
                'fallback' => true,
                'reason' => 'auth_middleware_error'
            ];
        }
    }

    /**
     * Get system-specific recommendations
     */
    private function getSystemRecommendations()
    {
        $recommendations = [];

        // Check database indexes
        $missing_indexes = $this->checkMissingIndexes();
        if (!empty($missing_indexes)) {
            $recommendations[] = [
                'type' => 'critical',
                'message' => 'Missing database indexes detected',
                'action' => 'Add indexes for: ' . implode(', ', $missing_indexes),
                'priority' => 'high'
            ];
        }

        // Check cache configuration
        $cache_issues = $this->checkCacheConfiguration();
        if (!empty($cache_issues)) {
            $recommendations[] = [
                'type' => 'warning',
                'message' => 'Cache configuration issues detected',
                'action' => $cache_issues,
                'priority' => 'medium'
            ];
        }

        // Check memory limits
        $memory_issues = $this->checkMemoryLimits();
        if (!empty($memory_issues)) {
            $recommendations[] = [
                'type' => 'warning',
                'message' => 'Memory limit issues detected',
                'action' => $memory_issues,
                'priority' => 'medium'
            ];
        }

        return $recommendations;
    }

    /**
     * Check for missing database indexes
     */
    private function checkMissingIndexes()
    {
        global $wpdb;

        $missing_indexes = [];

        // Check analytics tables
        $analytics_tables = [
            $wpdb->prefix . 'fleekdash_pageviews',
            $wpdb->prefix . 'fleekdash_sessions',
            $wpdb->prefix . 'fleekdash_analytics_daily'
        ];

        foreach ($analytics_tables as $table) {
            $table_exists = $wpdb->get_var("SHOW TABLES LIKE '$table'") === $table;
            if (!$table_exists) {
                $missing_indexes[] = $table;
            }
        }

        return $missing_indexes;
    }

    /**
     * Check cache configuration
     */
    private function checkCacheConfiguration()
    {
        $issues = [];

        // Check if object cache is available
        if (!wp_using_ext_object_cache()) {
            $issues[] = 'Consider enabling object cache (Redis/Memcached)';
        }

        // Check transient cache
        $test_key = 'fleekdash_cache_test_' . time();
        \set_transient($test_key, 'test', 60);
        $test_result = \get_transient($test_key);
        \delete_transient($test_key);

        if ($test_result !== 'test') {
            $issues[] = 'Transient cache may not be working properly';
        }

        return empty($issues) ? null : implode('; ', $issues);
    }

    /**
     * Check memory limits
     */
    private function checkMemoryLimits()
    {
        $issues = [];

        $memory_limit = ini_get('memory_limit');
        $memory_limit_bytes = $this->returnBytes($memory_limit);

        if ($memory_limit_bytes < 256 * 1024 * 1024) { // Less than 256MB
            $issues[] = 'Memory limit is low: ' . $memory_limit . ' (recommended: 256M+)';
        }

        $max_execution_time = ini_get('max_execution_time');
        if ($max_execution_time > 0 && $max_execution_time < 30) {
            $issues[] = 'Max execution time is low: ' . $max_execution_time . 's (recommended: 30s+)';
        }

        return empty($issues) ? null : implode('; ', $issues);
    }

    /**
     * Convert memory limit string to bytes.
     */
    private function returnBytes(string|false $val): int
    {
        if ($val === false || $val === '') {
            return 0;
        }

        $val = trim($val);
        $last = strtolower($val[strlen($val) - 1] ?? '');
        $val = (int) $val;

        switch ($last) {
            case 'g':
                $val *= 1024 * 1024 * 1024;
                break;
            case 'm':
                $val *= 1024 * 1024;
                break;
            case 'k':
                $val *= 1024;
                break;
            default:
                break;
        }

        return $val;
    }

    /**
     * Get priority order for recommendations.
     *
     * @param list<array<string, mixed>> $recommendations
     * @return list<array<string, mixed>>
     */
    private function getPriorityOrder(array $recommendations): array
    {
        $priority_map = [
            'critical' => 1,
            'warning' => 2,
            'info' => 3
        ];

        usort($recommendations, function($a, $b) use ($priority_map) {
            $a_priority = $priority_map[$a['type']] ?? 4;
            $b_priority = $priority_map[$b['type']] ?? 4;

            if ($a_priority !== $b_priority) {
                return $a_priority - $b_priority;
            }

            // If same type, check explicit priority
            $a_explicit = $a['priority'] ?? 'medium';
            $b_explicit = $b['priority'] ?? 'medium';

            $explicit_priority = ['high' => 1, 'medium' => 2, 'low' => 3];
            return ($explicit_priority[$a_explicit] ?? 4) - ($explicit_priority[$b_explicit] ?? 4);
        });

        return $recommendations;
    }
}
