<?php

declare(strict_types=1);

namespace Kylin\RiskEngine\Http\Controllers;

use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Kylin\Core\ApiResponse;
use Kylin\Core\Controllers\BaseController;
use Kylin\RiskEngine\Models\BlackWhiteList;
use Kylin\RiskEngine\Services\FaceVerificationService;
use Kylin\RiskEngine\Services\RiskEngineService;

/**
 * 风控引擎控制器
 *
 * 提供风险评估、黑白名单管理、人脸复核等 HTTP 接口。
 *
 * 法律合规：
 *  - 《未成年人保护法》第七十六条：建立未成年人保护风控机制
 *  - 《个人信息保护法》第二十八条：人脸信息为敏感个人信息
 *  - 等保 2.0 8.1.4.6：风控决策审计日志
 */
class RiskEngineController extends BaseController
{
    public function __construct(
        private readonly RiskEngineService $riskEngine,
        private readonly FaceVerificationService $faceService,
    ) {}

    /**
     * 风险评估
     */
    public function evaluate(Request $request): JsonResponse
    {
        $data = $request->validate([
            'user_id' => 'required|integer|min:1',
            'tenant_id' => 'nullable|integer|min:1',
            'signals' => 'required|array',
            'context' => 'nullable|array',
        ]);

        $result = $this->riskEngine->evaluate(
            (int) $data['user_id'],
            (int) ($data['tenant_id'] ?? 0),
            $data['signals'],
            $data['context'] ?? [],
        );

        return ApiResponse::success($result);
    }

    /**
     * 获取缓存的风险评分
     */
    public function cachedScore(Request $request): JsonResponse
    {
        $data = $request->validate(['user_id' => 'required|integer|min:1']);
        $score = $this->riskEngine->getCachedScore((int) $data['user_id']);
        $decision = $this->riskEngine->getCachedDecision((int) $data['user_id']);

        return ApiResponse::success([
            'score' => $score,
            'decision' => $decision?->value,
        ]);
    }

    /**
     * 人脸复核
     *
     * 依据《个人信息保护法》第二十八条，人脸信息为敏感个人信息，
     * 需用户单独同意。前端调用前需取得用户授权。
     */
    public function faceVerify(Request $request): JsonResponse
    {
        $data = $request->validate([
            'user_id' => 'required|integer|min:1',
            'reference_image' => 'required|string',
            'live_image' => 'required|string',
            'check_liveness' => 'nullable|boolean',
        ]);

        $result = $this->faceService->verify(
            (int) $data['user_id'],
            $data['reference_image'],
            $data['live_image'],
            (bool) ($data['check_liveness'] ?? true),
        );

        if ($result['passed']) {
            $this->faceService->markVerified((int) $data['user_id']);
        }

        return ApiResponse::success($result);
    }

    /**
     * 检查用户是否已完成人脸复核
     */
    public function faceStatus(Request $request): JsonResponse
    {
        $data = $request->validate(['user_id' => 'required|integer|min:1']);
        return ApiResponse::success([
            'verified' => $this->faceService->hasVerified((int) $data['user_id']),
        ]);
    }

    /**
     * 黑白名单查询
     */
    public function listQuery(Request $request): JsonResponse
    {
        $data = $request->validate([
            'type' => 'nullable|string|in:black,white',
            'dimension' => 'nullable|string|in:user,ip,device,fingerprint',
            'value' => 'nullable|string|max:255',
        ]);

        $query = BlackWhiteList::query();
        if (!empty($data['type'])) {
            $query->where('type', $data['type']);
        }
        if (!empty($data['dimension'])) {
            $query->where('dimension', $data['dimension']);
        }
        if (!empty($data['value'])) {
            $query->where('value', $data['value']);
        }

        return ApiResponse::success($query->orderByDesc('id')->paginate(20));
    }

    /**
     * 添加黑白名单
     */
    public function listCreate(Request $request): JsonResponse
    {
        $data = $request->validate([
            'type' => 'required|string|in:black,white',
            'dimension' => 'required|string|in:user,ip,device,fingerprint',
            'value' => 'required|string|max:255',
            'reason' => 'nullable|string|max:500',
            'expires_at' => 'nullable|date|after:now',
        ]);

        $entry = BlackWhiteList::create($data);

        return ApiResponse::success($entry, '已添加', 201);
    }

    /**
     * 删除黑白名单条目
     */
    public function listDelete(int $id): JsonResponse
    {
        $entry = BlackWhiteList::find($id);
        if (! $entry) {
            return ApiResponse::error('条目不存在', 404);
        }

        $entry->delete();
        return ApiResponse::success(null, '已删除');
    }
}
