<?php

namespace XZD\AI\V5\REST\Controllers;

use XZD\AI\V5\REST\BaseController;
use XZD\AI\V5\Theme\AdapterRegistry;
use WP_REST_Request;

/**
 * 主题适配 REST 端点
 *
 * GET  /theme/info          — 获取当前主题信息 + 能力矩阵
 * POST /theme/health-check  — 一键健康检查
 * GET  /theme/capabilities  — 获取能力矩阵
 */
class ThemeController extends BaseController
{
    public function registerRoutes(): void
    {
        $this->registerGet('/theme/info', [$this, 'info'], 'manage_options');
        $this->registerPost('/theme/health-check', [$this, 'healthCheck'], 'manage_options');
        $this->registerGet('/theme/capabilities', [$this, 'capabilities'], 'manage_options');
    }

    public function info(WP_REST_Request $request): \WP_REST_Response
    {
        if ($err = $this->guardLicense()) return $err;
        $detect = AdapterRegistry::detect();

        return $this->success([
            'theme' => [
                'name'     => $detect['name'],
                'version'  => $detect['version'],
                'template' => $detect['template'],
                'adapter'  => $detect['adapter'],
                'has_deep_adapter' => AdapterRegistry::isZibll(),
                'is_dark'  => $detect['is_dark'],
            ],
            'capabilities' => $detect['capabilities'],
            'colors'       => $detect['colors'],
            'bubble'       => $detect['bubble'],
        ]);
    }

    public function capabilities(WP_REST_Request $request): \WP_REST_Response
    {
        if ($err = $this->guardLicense()) return $err;
        $adapter = AdapterRegistry::getCurrent();
        $caps    = $adapter->getCapabilities();

        $available = 0;
        $total     = count($caps);
        foreach ($caps as $c) {
            if ($c['available']) { $available++; }
        }

        return $this->success([
            'capabilities'    => $caps,
            'available_count' => $available,
            'total_count'     => $total,
            'adapter_class'   => get_class($adapter),
        ]);
    }

    /**
     * 一键健康检查 — 遍历所有能力并根据声明状态进行测试
     *
     * 逻辑:
     *  - declared=available → 执行实际测试 → pass/fail
     *  - declared=unavailable → 跳过测试 → skipped
     */
    public function healthCheck(WP_REST_Request $request): \WP_REST_Response
    {
        if ($err = $this->guardLicense()) return $err;
        $adapter = AdapterRegistry::getCurrent();
        $caps    = $adapter->getCapabilities();

        $results = [];
        $pass    = 0;
        $fail    = 0;
        $skipped = 0;

        // 找一个真实用户用于测试
        $testUserId = 0;
        $users = get_users(['number' => 1, 'fields' => 'ID']);
        if (!empty($users)) {
            $testUserId = $users[0];
        }

        foreach ($caps as $key => $cap) {
            if (!$cap['available']) {
                // 能力声明为不可用 → 跳过
                $results[$key] = [
                    'name'     => $this->capLabel($key),
                    'declared' => false,
                    'tested'   => 'skipped',
                    'message'  => '已跳过: ' . ($cap['reason'] ?: '当前主题不支持'),
                    'source'   => $cap['source'],
                ];
                $skipped++;
                continue;
            }

            $testResult = $this->testCapability($adapter, $key, $testUserId);
            $results[$key] = [
                'name'     => $this->capLabel($key),
                'declared' => true,
                'tested'   => $testResult['ok'] ? 'pass' : 'fail',
                'message'  => $testResult['message'],
                'source'   => $cap['source'],
            ];
            if ($testResult['ok']) { $pass++; } else { $fail++; }
        }

        $total = $pass + $fail + $skipped;

        return $this->success([
            'timestamp'     => current_time('mysql'),
            'adapter'       => get_class($adapter),
            'test_user_id'  => $testUserId,
            'results'       => $results,
            'passed'        => $pass,
            'failed'        => $fail,
            'skipped'       => $skipped,
            'total'         => $total,
            'health_status' => $fail > 0 ? 'degraded' : ($skipped > 0 ? 'healthy' : 'healthy'),
            'summary'       => "{$pass} 通过 / {$skipped} 跳过 / {$fail} 失败 (共{$total}项)",
        ]);
    }

    private function testCapability($adapter, string $key, int $testUserId): array
    {
        try {
            return match ($key) {
                'points'       => ['ok' => true, 'message' => '积分=' . $adapter->getPoints($testUserId)],
                'balance'      => ['ok' => true, 'message' => '余额=' . $adapter->getBalance($testUserId)],
                'vip'          => ['ok' => true, 'message' => 'VIP等级=' . $adapter->getVipLevel($testUserId)],
                'blacklist'    => ['ok' => true, 'message' => '封禁=' . ($adapter->isBanned($testUserId) ? '是' : '否')],
                'medal'        => ['ok' => true, 'message' => '勋章数=' . count($adapter->getMedals($testUserId))],
                'notification' => $this->checkFunction('zib_send_message', '站内通知'),
                'checkin'      => $this->checkFunction('zib_user_is_checkined', '签到', function () use ($adapter, $testUserId) {
                    return json_encode($adapter->getCheckinStatus($testUserId));
                }),
                'invite'       => $this->checkFunction('zib_invite', '邀请', function () use ($adapter, $testUserId) {
                    return ($adapter->getInviteStats($testUserId)['invited_count'] ?? 0) . ' 人';
                }),
                'order'        => ['ok' => true, 'message' => '订单数=' . count($adapter->getOrders($testUserId, 5))],
                'bbs'          => $this->checkFunction('zib_bbs_get_topic', '论坛', function () use ($adapter, $testUserId) {
                    return count($adapter->getForumTopics($testUserId, 5)) . ' 篇';
                }),
                default        => ['ok' => false, 'message' => '未知能力'],
            };
        } catch (\Throwable $e) {
            return ['ok' => false, 'message' => '异常: ' . $e->getMessage()];
        }
    }

    /**
     * 检查函数是否存在并执行测试
     */
    private function checkFunction(string $funcName, string $label, ?callable $detailFn = null): array
    {
        if (!function_exists($funcName)) {
            return ['ok' => false, 'message' => "{$label}: 函数 {$funcName}() 不存在"];
        }
        $detail = $detailFn ? $detailFn() : '可用';
        return ['ok' => true, 'message' => "{$label}: {$detail}"];
    }

    private function capLabel(string $key): string
    {
        return match ($key) {
            'points'       => '积分系统',
            'balance'      => '余额系统',
            'vip'          => 'VIP会员',
            'blacklist'    => '黑名单',
            'medal'        => '勋章系统',
            'notification' => '站内通知',
            'checkin'      => '签到系统',
            'invite'       => '邀请系统',
            'order'        => '订单系统',
            'bbs'          => '论坛系统',
            default        => $key,
        };
    }
}
