<?php

namespace XZD\AI\V5\REST\Controllers;

use XZD\AI\V5\REST\BaseController;
use XZD\AI\V5\Analytics\CostTracker;
use XZD\AI\V5\Agents\MonitorAgent;
use XZD\AI\V5\Tools\SiteTypeDetector;
use XZD\AI\V5\Tools\LearningEngine;
use XZD\AI\V5\Analytics\WorkerMonitor;
use XZD\AI\V5\Core\Config;
use WP_REST_Request;

/**
 * 分析与监控 REST 端点
 */
class AnalyticsController extends BaseController
{
    public function registerRoutes(): void
    {
        $this->registerGet('/analytics/cost', [$this, 'cost'], 'manage_options');
        $this->registerGet('/analytics/monitor', [$this, 'monitor'], 'manage_options');
        $this->registerGet('/analytics/monitor/suggestions', [$this, 'suggestions'], 'manage_options');
        $this->registerPost('/analytics/monitor/scan', [$this, 'fullScan'], 'manage_options');
        $this->registerGetPublic('/site-type', [$this, 'getSiteType']);
        // V3.2: 重新学习关键页面 + 立即学习
        $this->registerPost('/analytics/learning/reset-key-pages', [$this, 'resetKeyPages'], 'manage_options');
        $this->registerPost('/analytics/learning/run-now', [$this, 'runLearningNow'], 'manage_options');
        $this->registerPost('/site-type', [$this, 'setSiteType'], 'manage_options');
        $this->registerGet('/analytics/learning/status', [$this, 'learningStatus'], 'manage_options');
        $this->registerGet('/analytics/learning/logs', [$this, 'learningLogs'], 'manage_options');
        $this->registerGet('/analytics/learning/trend', [$this, 'learningTrend'], 'manage_options');
        $this->registerPost('/analytics/learning/trigger', [$this, 'triggerLearning'], 'manage_options');
        $this->registerGet('/analytics/worker/status', [$this, 'workerStatus'], 'manage_options');
        $this->registerGet('/analytics/worker/heartbeat', [$this, 'workerHeartbeat'], 'manage_options');
    }

    // ====== 成本 ======

    public function cost(WP_REST_Request $request): \WP_REST_Response
    {
        if ($err = $this->guardLicense('free')) return $err;
        $filters = [];
        $dateFrom = $this->getParam($request, 'date_from', '');
        $dateTo   = $this->getParam($request, 'date_to', '');
        $provider = $this->getParam($request, 'provider', '');
        $model    = $this->getParam($request, 'model', '');

        if ($dateFrom) {
            $filters['date_from'] = $dateFrom;
        }
        if ($dateTo) {
            $filters['date_to'] = $dateTo;
        }
        if ($provider) {
            $filters['provider'] = $provider;
        }
        if ($model) {
            $filters['model'] = $model;
        }

        $tracker = CostTracker::instance();
        $stats   = $tracker->getStats($filters);
        $month   = $tracker->getMonthSummary();
        $pricing = $tracker->getPricing();

        // 获取主备模型信息
        $connections = \XZD\AI\V5\Core\Config::instance()->get('connections.text', []);
        $primaryModel = '';
        $backupModels = [];
        foreach ($connections as $conn) {
            $model = $conn['model'] ?? '';
            if (empty($model)) continue;
            $isPrimary = ($conn['is_primary'] ?? false) || ($conn['role'] ?? '') === 'primary';
            $isEnabled = $conn['is_enabled'] ?? true;
            if (!$isEnabled) continue;
            if ($isPrimary && empty($primaryModel)) {
                $primaryModel = $model;
            } elseif ($isEnabled && $model !== $primaryModel) {
                $backupModels[] = $model;
            }
        }
        // 如果没标记主用，第一个启用的就是主用
        if (empty($primaryModel)) {
            foreach ($connections as $conn) {
                if (!empty($conn['model']) && ($conn['is_enabled'] ?? true)) {
                    $primaryModel = $conn['model'];
                    break;
                }
            }
            $backupModels = array_filter(array_map(fn($c) => $c['model'] ?? '', $connections), fn($m) => $m && $m !== $primaryModel && ($c['is_enabled'] ?? true));
        }

        // 分离主用/备用模型成本
        $primaryCost = ['model' => $primaryModel, 'calls' => 0, 'cost' => 0, 'input_tokens' => 0, 'output_tokens' => 0];
        $backupCosts = [];
        foreach ($stats['by_model'] ?? [] as $m) {
            if ($m['model'] === $primaryModel) {
                $primaryCost = $m;
            } elseif (in_array($m['model'], $backupModels)) {
                $backupCosts[] = $m;
            }
        }

        // 备用模型汇总
        $backupTotalCalls = array_sum(array_column($backupCosts, 'calls'));
        $backupTotalCost = array_sum(array_column($backupCosts, 'cost'));

        return $this->success([
            'stats'   => $stats,
            'month'   => $month,
            'pricing' => $pricing,
            'models'  => [
                'primary'       => $primaryCost,
                'backups'       => $backupCosts,
                'backup_total'  => ['calls' => $backupTotalCalls, 'cost' => round($backupTotalCost, 4)],
                'has_failover'  => $backupTotalCalls > 0,
            ],
        ]);
    }

    // ====== 监控面板 ======

    public function monitor(WP_REST_Request $request): \WP_REST_Response
    {
        if ($err = $this->guardLicense('free')) return $err;
        global $wpdb;

        // SSE 连接数（通过 transient 扫描最近10分钟）
        $sseConnected = 0;
        if (function_exists('get_transient')) {
            foreach (range(1, 20) as $i) {
                if (get_transient("xzd_stream_active_{$i}")) {
                    $sseConnected++;
                }
            }
        }

        // 最近 24h API 调用统计
        $apiCalls24h = (int) $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) FROM {$wpdb->prefix}xzd_ai_cost_log
             WHERE created_at > %s",
            date('Y-m-d H:i:s', strtotime('-24 hours'))
        ));

        // 队列状态 — 从真实队列系统获取
        $queueStatus = ['queue_pending' => 0, 'as_pending' => 0, 'as_running' => 0, 'by_source' => []];
        if (class_exists(\XZD\AI\V5\Tools\QueueManager::class)) {
            $queueStatus = \XZD\AI\V5\Tools\QueueManager::getQueueStatus();
        }
        $pendingQueueSize = class_exists(\XZD\AI\V5\Core\PendingQueue::class)
            ? \XZD\AI\V5\Core\PendingQueue::size() : 0;
        $deferredCount = 0;
        if (function_exists('get_transient')) {
            $deferred = \XZD\AI\V5\Core\Config::getArrayTransient('xzd_deferred_queue');
            $deferredCount = count($deferred);
        }
        $queueTotal  = $queueStatus['queue_pending'] + $queueStatus['as_pending'] + $queueStatus['as_running'] + $pendingQueueSize + $deferredCount;
        $queuePending = $queueStatus['queue_pending'] + $queueStatus['as_pending'] + $pendingQueueSize;
        $queueProcessing = $queueStatus['as_running'];

        // 内存使用
        $memoryLimit = ini_get('memory_limit');
        $memoryUsage = memory_get_usage(true);
        $memoryPeak  = memory_get_peak_usage(true);
        $memoryLimitBytes = $this->parseMemoryLimit($memoryLimit);
        $memoryPct = $memoryLimitBytes > 0 ? round($memoryUsage / $memoryLimitBytes * 100, 1) : 0;

        // 磁盘空间
        $diskFree  = function_exists('disk_free_space') ? disk_free_space(ABSPATH) : 0;
        $diskTotal = function_exists('disk_total_space') ? disk_total_space(ABSPATH) : 0;
        $diskPct   = $diskTotal > 0 ? round((1 - $diskFree / $diskTotal) * 100, 1) : 0;

        // 操作统计
        $opsToday = (int) $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) FROM {$wpdb->prefix}xzd_ai_operation_log
             WHERE created_at > %s",
            date('Y-m-d 00:00:00')
        ));
        $errorsToday = (int) $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) FROM {$wpdb->prefix}xzd_ai_operation_log
             WHERE status != 'success' AND created_at > %s",
            date('Y-m-d 00:00:00')
        ));

        // 数据库大小
        $dbSize = 0;
        $rows = $wpdb->get_results("SHOW TABLE STATUS FROM `" . DB_NAME . "` WHERE Name LIKE '{$wpdb->prefix}xzd_ai%'");
        foreach ($rows as $row) {
            $dbSize += ($row->Data_length ?? 0) + ($row->Index_length ?? 0);
        }

        // AI 连接状态
        $connections = \XZD\AI\V5\Core\Config::instance()->get('connections.text', []);
        $activeConnections = count(array_filter($connections, fn($c) => !empty($c['api_key']) && ($c['is_enabled'] ?? true)));

        return $this->success([
            'sse' => [
                'connected'    => $sseConnected,
                'status'       => $sseConnected > 0 ? 'active' : 'idle',
            ],
            'api' => [
                'calls_24h'    => $apiCalls24h,
                'active_connections' => $activeConnections,
                'total_connections'  => count($connections),
            ],
            'queue' => [
                'total'        => $queueTotal,
                'pending'      => $queuePending,
                'processing'   => $queueProcessing,
                'worker_queue' => $queueStatus['queue_pending'] ?? 0,
                'as_pending'   => $queueStatus['as_pending'] ?? 0,
                'as_running'   => $queueStatus['as_running'] ?? 0,
                'pending_queue' => $pendingQueueSize,
                'deferred'     => $deferredCount,
                'status'       => $queuePending > 50 ? 'backlogged' : ($queuePending > 10 ? 'busy' : 'normal'),
            ],
            'memory' => [
                'usage'        => $this->formatBytes($memoryUsage),
                'peak'         => $this->formatBytes($memoryPeak),
                'limit'        => $memoryLimit,
                'percent'      => $memoryPct,
                'status'       => $memoryPct > 80 ? 'warning' : 'normal',
            ],
            'disk' => [
                'free'         => $diskFree > 0 ? $this->formatBytes($diskFree) : 'N/A',
                'total'        => $diskTotal > 0 ? $this->formatBytes($diskTotal) : 'N/A',
                'percent'      => $diskPct,
                'status'       => $diskPct > 85 ? 'warning' : 'normal',
            ],
            'operations' => [
                'today'        => $opsToday,
                'errors_today' => $errorsToday,
                'status'       => $errorsToday > 0 ? 'has_errors' : 'healthy',
            ],
            'database' => [
                'size'         => $dbSize > 0 ? $this->formatBytes($dbSize) : 'N/A',
                'tables_count' => count($rows),
            ],
            'timestamp' => current_time('mysql'),
        ]);
    }

    public function suggestions(WP_REST_Request $request): \WP_REST_Response
    {
        if ($err = $this->guardLicense('free')) return $err;
        $monitor = new MonitorAgent();
        $suggestions = $monitor->generateSuggestions();
        $health = $monitor->getHealthSummary();

        return $this->success([
            'suggestions' => $suggestions,
            'health'      => $health,
        ]);
    }

    public function fullScan(WP_REST_Request $request): \WP_REST_Response
    {
        if ($err = $this->guardLicense()) return $err;
        $monitor = new MonitorAgent();
        $result = $monitor->runFullScan();

        return $this->success($result);
    }

    // ====== 站点类型 ======

    public function getSiteType(WP_REST_Request $request): \WP_REST_Response
    {
        if ($err = $this->guardLicense('free')) return $err;
        $detector = SiteTypeDetector::instance();
        $result = $detector->detect();
        return $this->success($result);
    }

    public function setSiteType(WP_REST_Request $request): \WP_REST_Response
    {
        if ($err = $this->guardLicense()) return $err;
        $type = $request->get_param('type') ?: '';
        $detector = SiteTypeDetector::instance();

        if (empty($type)) {
            $detector->clearManual();
            return $this->success($detector->detect(), '已恢复自动检测');
        }

        if (!$detector->setManual($type)) {
            return $this->error('无效的站点类型', 'invalid_type');
        }

        return $this->success($detector->detect(), "站点类型已设置为 {$type}");
    }

    // ====== 学习引擎 ======

    public function learningStatus(WP_REST_Request $request): \WP_REST_Response
    {
        if ($err = $this->guardLicense('free')) return $err;
        $engine = LearningEngine::instance();
        return $this->success($engine->getStatus());
    }

    public function learningLogs(WP_REST_Request $request): \WP_REST_Response
    {
        if ($err = $this->guardLicense('free')) return $err;
        $page = $this->getIntParam($request, 'page', 1);
        $perPage = min($this->getIntParam($request, 'per_page', 20), 100);
        $engine = LearningEngine::instance();
        return $this->success($engine->getLogs($page, $perPage));
    }

    public function learningTrend(WP_REST_Request $request): \WP_REST_Response
    {
        if ($err = $this->guardLicense('free')) return $err;
        $days = min($this->getIntParam($request, 'days', 7), 30);
        $engine = LearningEngine::instance();
        return $this->success($engine->getTrend($days));
    }

    public function triggerLearning(WP_REST_Request $request): \WP_REST_Response
    {
        if ($err = $this->guardLicense()) return $err;
        $mode = $request->get_param('mode') ?: 'manual';
        if (!in_array($mode, ['incremental', 'full', 'manual'], true)) {
            return $this->error('无效的学习模式，可选: incremental, full, manual', 'invalid_mode');
        }

        // 防止并发
        $lock = get_transient('xzd_learning_lock');
        if ($lock) {
            return $this->error('学习任务正在执行中，请稍后再试', 'learning_in_progress', 409);
        }
        set_transient('xzd_learning_lock', time(), 300);

        try {
            $engine = LearningEngine::instance();
            $result = $engine->run($mode);
            delete_transient('xzd_learning_lock');
            return $this->success($result, $result['success'] ? '学习完成' : '学习失败');
        } catch (\Throwable $e) {
            delete_transient('xzd_learning_lock');
            return $this->error('学习异常: ' . $e->getMessage(), 'learning_error', 500);
        }
    }

    /**
     * V3.2: 重置关键页面学习标记 + 立即重新学习
     */
    public function resetKeyPages(WP_REST_Request $request): \WP_REST_Response
    {
        try {
            $engine = LearningEngine::instance();
            $result = $engine->resetKeyPages();
            return $this->success($result, $result['message'] ?? '已重置');
        } catch (\Throwable $e) {
            return $this->error('重置失败: ' . $e->getMessage(), 'reset_error', 500);
        }
    }

    /**
     * V3.2: 立即触发一次学习
     */
    public function runLearningNow(WP_REST_Request $request): \WP_REST_Response
    {
        try {
            $engine = LearningEngine::instance();
            $engine->runNow();
            return $this->success(['message' => '学习任务已加入队列，将在后台执行'], '已触发');
        } catch (\Throwable $e) {
            return $this->error('触发失败: ' . $e->getMessage(), 'run_error', 500);
        }
    }

    // ====== Worker 状态 ======

    public function workerStatus(WP_REST_Request $request): \WP_REST_Response
    {
        if ($err = $this->guardLicense('free')) return $err;
        return $this->success(WorkerMonitor::getStatus());
    }

    /**
     * 轻量心跳端点（仪表盘轮询）
     */
    public function workerHeartbeat(WP_REST_Request $request): \WP_REST_Response
    {
        if ($err = $this->guardLicense('free')) return $err;
        return $this->success(WorkerMonitor::getHeartbeat());
    }

    // ====== 工具方法 ======

    private function formatBytes(int $bytes): string
    {
        if ($bytes >= 1073741824) {
            return round($bytes / 1073741824, 1) . ' GB';
        }
        if ($bytes >= 1048576) {
            return round($bytes / 1048576, 1) . ' MB';
        }
        if ($bytes >= 1024) {
            return round($bytes / 1024, 1) . ' KB';
        }
        return $bytes . ' B';
    }

    private function parseMemoryLimit(string $limit): int
    {
        return Config::parseMemoryLimit($limit, 128 * 1024 * 1024);
    }
}
