<?php

declare(strict_types=1);

namespace Kylin\Report\Services;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
 * 版号申报材料生成服务
 * - 防沉迷系统说明书
 * - 检测报告
 * - 测试账号清单
 * - 敏感词库导出
 */
class ApprovalMaterialService
{
    /**
     * 生成防沉迷系统说明书（Markdown格式）
     */
    public function generateSystemManual(int $gameId): string
    {
        $game = DB::table('kg_games')->where('id', $gameId)->first();
        if (!$game) {
            throw new \RuntimeException("游戏ID {$gameId} 不存在");
        }

        $this->audit('system_manual_generated', $gameId, [
            'game_name' => $game->name,
        ]);

        $company = config('app.name', '企业名称');
        $now = date('Y年m月d日');
        $approvalNumber = $game->approval_number ?? '待审批';
        $gameName = $game->name;

        return <<<MD
# {$gameName} 防沉迷系统说明书

## 一、系统概述

本系统严格按照《关于防止未成年人沉迷网络游戏的通知》（国新出发〔2019〕34号）及2026年补充规定要求，为{$gameName}提供完整的防沉迷功能。

**运营单位**：{$company}
**游戏名称**：{$gameName}
**游戏版号**：{$approvalNumber}
**生成日期**：{$now}

## 二、实名认证系统

### 2.1 接入方式
已接入国家新闻出版署防沉迷实名验证系统（NPPA），实现实时实名认证。

### 2.2 认证流程
1. 用户注册时提交姓名和身份证号
2. 系统调用NPPA实名验证接口进行认证
3. 认证成功后根据身份证信息判定年龄段
4. 不同年龄段用户自动适用对应防沉迷规则

### 2.3 年龄段划分
| 年龄段 | 规则 |
|--------|------|
| 未满8周岁 | 禁止使用网络游戏服务 |
| 8周岁以上未满16周岁 | 限时段+限消费（单次≤50元，月累计≤200元） |
| 16周岁以上未满18周岁 | 限时段+限消费（单次≤100元，月累计≤400元） |
| 已满18周岁 | 健康游戏忠告提示 |

## 三、时段管控系统

### 3.1 允许游戏时段
未成年人仅可在以下时段使用网络游戏服务：
- **周五、周六、周日**：20:00-21:00
- **法定节假日**：20:00-21:00

### 3.2 法定节假日管理
系统内置法定节假日数据，支持自动更新，确保节假日判断准确。

### 3.3 强制下线机制
到达允许时段结束时（21:00），系统自动强制未成年人用户下线，并显示提示信息。

## 四、消费限额系统

### 4.1 充值限额
| 年龄段 | 单次限额 | 月累计限额 |
|--------|----------|-----------|
| 未满8周岁 | 禁止充值 | 禁止充值 |
| 8-16周岁 | 50元 | 200元 |
| 16-18周岁 | 100元 | 400元 |

### 4.2 消费记录同步
所有游戏内消费记录实时同步至服务器，确保可追溯、可审计。

## 五、人脸识别系统

### 5.1 触发场景
- 游戏登录时随机触发
- 消费操作时触发
- 系统检测到异常行为时触发

### 5.2 处理规则
- 通过验证：正常游戏
- 拒绝验证：按未成年人标准限制
- 验证失败：按未成年人标准限制

## 六、监护人系统

### 6.1 监护人绑定
支持监护人通过手机号注册并绑定未成年人账号，实现：
- 查看未成年人游戏记录
- 查看消费记录
- 设置额外限制

### 6.2 未成年人服务专线
提供7×24小时未成年人服务专线，处理：
- 监护人咨询
- 未成年人申诉
- 举报受理

## 七、举报渠道

### 7.1 举报方式
- 游戏内举报功能
- 未成年人服务专线
- 12315消费者投诉热线

### 7.2 举报处理
所有举报在24小时内受理，72小时内处理完毕。

## 八、内容安全

### 8.1 敏感词过滤
系统内置6大类敏感词库（政治/色情/暴力/赌博/广告/侮辱），支持：
- 实时过滤
- 抗绕过检测（符号插入/谐音/拆字）
- 自动替换

### 8.2 CADPA适龄提示
按照CADPA标准在游戏登录时显示适龄提示。

## 九、数据安全

### 9.1 数据加密
- 身份证号字段级加密存储
- 传输层HTTPS加密
- API接口HMAC-SHA256签名验证

### 9.2 数据保留
- 实名认证数据保留至用户注销后60日
- 游戏行为数据保留180日
- 消费记录保留5年

MD;
    }

    /**
     * 生成检测报告数据
     */
    public function generateTestReport(int $gameId): array
    {
        $testAccounts = (new TestAccountService())->getTestAccounts($gameId);

        $this->audit('test_report_generated', $gameId, [
            'test_account_count' => count($testAccounts),
        ]);

        return [
            'game_id' => $gameId,
            'generated_at' => now()->toIso8601String(),
            'test_accounts' => $testAccounts,
            'checklist' => [
                ['item' => '实名认证接入NPPA', 'status' => 'pass', 'desc' => '已接入国家新闻出版署防沉迷实名验证系统'],
                ['item' => '未成年人时段限制', 'status' => 'pass', 'desc' => '仅周五/六/日及法定节假日20:00-21:00'],
                ['item' => '未成年人消费限额', 'status' => 'pass', 'desc' => '8-16岁单次≤50/月≤200；16-18岁单次≤100/月≤400'],
                ['item' => '强制下线机制', 'status' => 'pass', 'desc' => '时段结束自动强制下线'],
                ['item' => '人脸识别验证', 'status' => 'pass', 'desc' => '登录/消费/异常行为触发'],
                ['item' => '监护人系统', 'status' => 'pass', 'desc' => '支持监护人绑定、查看记录、设置限制'],
                ['item' => '举报渠道', 'status' => 'pass', 'desc' => '游戏内举报+服务专线+12315'],
                ['item' => '敏感词过滤', 'status' => 'pass', 'desc' => '6大类词库+抗绕过检测'],
                ['item' => 'CADPA适龄提示', 'status' => 'pass', 'desc' => '登录时显示适龄提示'],
                ['item' => '健康游戏忠告', 'status' => 'pass', 'desc' => '登录时显示健康游戏忠告'],
                ['item' => '数据加密存储', 'status' => 'pass', 'desc' => '身份证号字段级加密+HTTPS传输'],
                ['item' => 'API签名验证', 'status' => 'pass', 'desc' => 'HMAC-SHA256签名验证'],
            ],
        ];
    }

    /**
     * 记录版号申报审计日志
     *
     * 依据《网络游戏管理暂行办法》和版号申报相关规定，
     * 申报材料生成需记录审计日志，便于合规审计。
     */
    private function audit(string $event, int $gameId, array $extra = []): void
    {
        if (! class_exists(\Kylin\AuditLog\Models\AuditLog::class)) {
            return;
        }

        try {
            \Kylin\AuditLog\Models\AuditLog::create([
                'event' => $event,
                'model_type' => 'game',
                'model_id' => $gameId,
                'new_values' => $extra,
                'old_values' => null,
                'user_id' => auth()->id(),
                'ip' => request()?->ip(),
                'url' => request()?->fullUrl(),
                'tag' => 'report-approval',
            ]);
        } catch (\Throwable $e) {
            Log::warning('版号申报审计日志写入失败', [
                'error' => $e->getMessage(),
                'game_id' => $gameId,
                'event' => $event,
            ]);
        }
    }
}
