<?php

namespace Kylin\AntiAddiction\Services;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Kylin\AntiAddiction\Enums\AntiAddictionErrorCode;
use Kylin\AntiAddiction\Exceptions\AntiAddictionException;

/**
 * 人脸识别服务
 *
 * 对接第三方人脸识别 SDK（腾讯云/阿里云/百度云），
 * 用于验证当前操作者是否为实名认证本人。
 *
 * 触发场景：
 * 1. 游戏时长异常（疑似未成年人冒用成年人账号）
 * 2. 新设备登录
 * 3. 消费行为异常
 * 4. 定期随机抽检
 */
class FaceVerifyService
{
    /**
     * 发起人脸验证
     *
     * @param int    $userId    用户 ID
     * @param string $imageBase64 人脸照片 Base64
     * @param string $idCard    身份证号（用于与公安照片比对）
     * @param string $realName  真实姓名
     * @return array{passed: bool, confidence: float, message: string}
     *
     * @throws AntiAddictionException
     */
    public function verify(int $userId, string $imageBase64, string $idCard, string $realName): array
    {
        if (! config('kylin-anti-addiction.face_verify.enabled', true)) {
            return ['passed' => true, 'confidence' => 1.0, 'message' => '人脸验证未启用'];
        }

        $provider = config('kylin-anti-addiction.face_verify.provider', 'tencent');

        try {
            $result = match ($provider) {
                'tencent' => $this->verifyViaTencent($imageBase64, $idCard, $realName),
                'aliyun' => $this->verifyViaAliyun($imageBase64, $idCard, $realName),
                'baidu' => $this->verifyViaBaidu($imageBase64, $idCard, $realName),
                default => $this->verifyViaTencent($imageBase64, $idCard, $realName),
            };

            if (! $result['passed']) {
                throw new AntiAddictionException(AntiAddictionErrorCode::FaceVerifyFailed);
            }

            return $result;
        } catch (AntiAddictionException $e) {
            throw $e;
        } catch (\Throwable $e) {
            Log::error('人脸验证异常', [
                'user_id' => $userId,
                'provider' => $provider,
                'message' => $e->getMessage(),
            ]);

            throw new AntiAddictionException(AntiAddictionErrorCode::FaceVerifyFailed);
        }
    }

    /**
     * 判断是否需要触发人脸验证
     *
     * @param int   $userId     用户 ID
     * @param int   $dailyPlayTime 当日游戏时长（秒）
     * @param bool  $isNewDevice 是否新设备
     * @param bool  $spendingAnomaly 消费是否异常
     * @return bool
     */
    public function shouldTrigger(int $userId, int $dailyPlayTime, bool $isNewDevice = false, bool $spendingAnomaly = false): bool
    {
        if (! config('kylin-anti-addiction.face_verify.enabled', true)) {
            return false;
        }

        $trigger = config('kylin-anti-addiction.face_verify.trigger', []);

        // 游戏时长异常
        $threshold = $trigger['play_time_threshold'] ?? 7200;
        if ($dailyPlayTime >= $threshold) {
            return true;
        }

        // 新设备登录
        if ($trigger['new_device'] ?? false && $isNewDevice) {
            return true;
        }

        // 消费异常
        if ($trigger['spending_anomaly'] ?? false && $spendingAnomaly) {
            return true;
        }

        // 随机抽检
        $rate = $trigger['random_check_rate'] ?? 0.05;
        if (mt_rand() / mt_getrandmax() < $rate) {
            return true;
        }

        return false;
    }

    // ─── 第三方 SDK 对接 ────────────────────────────────────────

    /**
     * 腾讯云人脸核身
     */
    private function verifyViaTencent(string $imageBase64, string $idCard, string $realName): array
    {
        $config = config('kylin-anti-addiction.face_verify.sdk.tencent', []);

        // 实际对接腾讯云 FaceId API
        // 此处为接口骨架，需根据腾讯云 SDK 文档完善
        $response = Http::withHeaders([
            'Authorization' => "TC3-HMAC-SHA256 Credential={$config['secret_id']}",
        ])->post('https://faceid.tencentcloudapi.com/', [
            'IdCard' => $idCard,
            'Name' => $realName,
            'ImageBase64' => $imageBase64,
        ]);

        if (! $response->successful()) {
            Log::error('腾讯云人脸核身请求失败', [
                'status' => $response->status(),
                'body' => $response->body(),
            ]);

            return ['passed' => false, 'confidence' => 0.0, 'message' => '人脸验证服务异常'];
        }

        $result = $response->json();
        $similarity = (float) ($result['Simility'] ?? 0);

        return [
            'passed' => $similarity >= 80.0,
            'confidence' => $similarity / 100,
            'message' => $similarity >= 80.0 ? '人脸验证通过' : '人脸验证未通过',
        ];
    }

    /**
     * 阿里云人脸核身
     */
    private function verifyViaAliyun(string $imageBase64, string $idCard, string $realName): array
    {
        $config = config('kylin-anti-addiction.face_verify.sdk.aliyun', []);

        // 实际对接阿里云金融级实人认证 API
        // 此处为接口骨架，需根据阿里云 SDK 文档完善
        $response = Http::withHeaders([
            'Authorization' => "ACS {$config['access_key_id']}:{$config['access_key_secret']}",
        ])->post($config['endpoint'] ?? 'https://facebody.cn-shanghai.aliyuncs.com', [
            'IdCard' => $idCard,
            'Name' => $realName,
            'ImageBase64' => $imageBase64,
        ]);

        if (! $response->successful()) {
            return ['passed' => false, 'confidence' => 0.0, 'message' => '人脸验证服务异常'];
        }

        $result = $response->json();
        $passed = ($result['Data']['Passed'] ?? 'F') === 'T';

        return [
            'passed' => $passed,
            'confidence' => (float) ($result['Data']['Confidence'] ?? 0) / 100,
            'message' => $passed ? '人脸验证通过' : '人脸验证未通过',
        ];
    }

    /**
     * 百度云人脸核身
     */
    private function verifyViaBaidu(string $imageBase64, string $idCard, string $realName): array
    {
        $config = config('kylin-anti-addiction.face_verify.sdk.baidu', []);

        // 实际对接百度云人脸识别 API
        // 此处为接口骨架，需根据百度云 SDK 文档完善
        $response = Http::post('https://aip.baidubce.com/rest/2.0/face/v3/person/verify', [
            'image' => $imageBase64,
            'image_type' => 'BASE64',
            'id_card_number' => $idCard,
            'name' => $realName,
        ]);

        if (! $response->successful()) {
            return ['passed' => false, 'confidence' => 0.0, 'message' => '人脸验证服务异常'];
        }

        $result = $response->json();
        $score = (float) ($result['result']['score'] ?? 0);

        return [
            'passed' => $score >= 80.0,
            'confidence' => $score / 100,
            'message' => $score >= 80.0 ? '人脸验证通过' : '人脸验证未通过',
        ];
    }
}
