<?php

namespace Kylin\AntiAddiction\Http\Controllers;

use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Kylin\AntiAddiction\Enums\AgeGroup;
use Kylin\AntiAddiction\Models\AntiAddictionRecord;
use Kylin\AntiAddiction\Services\AntiAddictionService;
use Kylin\AntiAddiction\Services\BehaviorAnalysisService;
use Kylin\AntiAddiction\Services\FaceVerifyService;
use Kylin\AntiAddiction\Services\HolidayService;
use Kylin\AntiAddiction\Services\RealNameVerifyService;
use Kylin\Core\ApiResponse;
use Kylin\Core\Controllers\BaseController;

/**
 * 防沉迷控制器
 */
class AntiAddictionController extends BaseController
{
    public function __construct(
        private readonly AntiAddictionService $antiAddictionService,
        private readonly RealNameVerifyService $realNameVerifyService,
        private readonly FaceVerifyService $faceVerifyService,
        private readonly BehaviorAnalysisService $behaviorAnalysisService,
        private readonly HolidayService $holidayService,
    ) {}

    /**
     * 防沉迷检查
     *
     * GET /kylin/anti-addiction/check?game_id=1
     */
    public function check(Request $request): JsonResponse
    {
        $request->validate(['game_id' => 'required|integer']);

        $userId = $request->user()->id;
        $gameId = (int) $request->input('game_id');

        $result = $this->antiAddictionService->check($userId, $gameId);

        return ApiResponse::success($result);
    }

    /**
     * 心跳上报
     *
     * POST /kylin/anti-addiction/heartbeat
     */
    public function heartbeat(Request $request): JsonResponse
    {
        $request->validate([
            'play_time' => 'required|integer|min:1', // 本次上报的游戏时长（秒）
        ]);

        $userId = $request->user()->id;
        $playTime = (int) $request->input('play_time');

        $result = $this->antiAddictionService->heartbeat($userId, $playTime);

        return ApiResponse::success($result);
    }

    /**
     * 消费限额检查
     *
     * POST /kylin/anti-addiction/spending-check
     */
    public function spendingCheck(Request $request): JsonResponse
    {
        $request->validate([
            'amount_cents' => 'required|integer|min:1', // 充值金额（分）
        ]);

        $userId = $request->user()->id;
        $amountCents = (int) $request->input('amount_cents');

        $result = $this->antiAddictionService->checkSpending($userId, $amountCents);

        return ApiResponse::success($result);
    }

    /**
     * 记录消费（防沉迷统计）
     *
     * 客户端购买商品后上报消费记录，服务端校验限额并记录。
     * 用于防沉迷月度消费统计，不做实际支付。
     *
     * POST /kylin/anti-addiction/record-spending
     */
    public function recordSpending(Request $request): JsonResponse
    {
        $request->validate([
            'amount_cents' => 'required|integer|min:1',
            'item_id' => 'sometimes|string|max:100',
            'subject' => 'sometimes|string|max:200',
        ]);

        $userId = $request->user()->id;
        $amountCents = (int) $request->input('amount_cents');
        $itemId = $request->input('item_id', '');
        $subject = $request->input('subject', '游戏消费');

        try {
            // 防沉迷限额校验
            $checkResult = $this->antiAddictionService->checkSpending($userId, $amountCents);

            // 记录消费
            $ageGroup = $this->antiAddictionService->resolveAgeGroup($userId);
            $spendingRecord = \Kylin\AntiAddiction\Models\SpendingRecord::create([
                'user_id' => $userId,
                'game_id' => 1,
                'amount_cents' => $amountCents,
                'order_no' => 'SPEND' . date('YmdHis') . \Illuminate\Support\Str::random(6),
                'status' => 'success',
                'age_group_at_time' => $ageGroup,
            ]);

            return ApiResponse::success([
                'allowed' => true,
                'record_id' => $spendingRecord->id,
                'age_group' => $ageGroup,
                'monthly_used' => \Kylin\AntiAddiction\Models\SpendingRecord::monthlyTotal($userId),
            ], '消费记录已保存');
        } catch (\Kylin\AntiAddiction\Exceptions\AntiAddictionException $e) {
            return ApiResponse::error($e->errorCode()->value, $e->getMessage(), 422);
        }
    }

    /**
     * 实名认证
     *
     * POST /kylin/anti-addiction/real-name-verify
     */
    public function realNameVerify(Request $request): JsonResponse
    {
        $request->validate([
            'real_name' => 'required|string|min:2|max:20',
            'id_card' => 'required|string|size:18',
        ]);

        $userId = $request->user()->id;
        $realName = $request->input('real_name');
        $idCard = $request->input('id_card');

        $result = $this->realNameVerifyService->verify($userId, $realName, $idCard);

        return ApiResponse::success($result, '实名认证完成');
    }

    /**
     * 人脸验证
     *
     * POST /kylin/anti-addiction/face-verify
     */
    public function faceVerify(Request $request): JsonResponse
    {
        $request->validate([
            'image_base64' => 'required|string',
            'id_card' => 'required|string|size:18',
            'real_name' => 'required|string|min:2|max:20',
        ]);

        $userId = $request->user()->id;
        $imageBase64 = $request->input('image_base64');
        $idCard = $request->input('id_card');
        $realName = $request->input('real_name');

        $result = $this->faceVerifyService->verify($userId, $imageBase64, $idCard, $realName);

        return ApiResponse::success($result);
    }

    /**
     * AI 行为分析
     *
     * POST /kylin/anti-addiction/analyze-behavior
     */
    public function analyzeBehavior(Request $request): JsonResponse
    {
        $userId = $request->user()->id;

        $result = $this->behaviorAnalysisService->analyze($userId);

        return ApiResponse::success($result);
    }

    /**
     * 节假日列表
     *
     * GET /kylin/anti-addiction/holidays?year=2026
     */
    public function holidays(Request $request): JsonResponse
    {
        $year = (int) $request->input('year', now()->year);
        $country = $request->input('country', 'CN');

        $holidays = $this->holidayService->getHolidaysByYear($year, $country);

        return ApiResponse::success($holidays);
    }

    /**
     * 防沉迷记录
     *
     * GET /kylin/anti-addiction/records
     */
    public function records(Request $request): JsonResponse
    {
        $userId = $request->user()->id;

        $record = AntiAddictionRecord::where('user_id', $userId)->first();

        if (! $record) {
            // 无记录时仍返回动态计算的年龄分组
            $ageGroup = $this->antiAddictionService->resolveAgeGroup($userId);
            return ApiResponse::success([
                'user_id' => $userId,
                'age_group' => $ageGroup,
                'age_group_label' => $ageGroup->label(),
                'is_minor' => $ageGroup->isMinor(),
                'daily_play_time' => 0,
                'daily_play_time_minutes' => 0,
                'total_play_time' => 0,
                'last_play_date' => null,
                'session_count' => 0,
            ]);
        }

        // 同步最新的年龄分组
        $currentAgeGroup = $this->antiAddictionService->resolveAgeGroup($userId);
        if ($record->age_group !== $currentAgeGroup) {
            $record->age_group = $currentAgeGroup;
            $record->save();
        }

        return ApiResponse::success([
            'user_id' => $record->user_id,
            'age_group' => $record->age_group,
            'age_group_label' => $record->age_group->label(),
            'is_minor' => $record->age_group->isMinor(),
            'daily_play_time' => $record->daily_play_time,
            'daily_play_time_minutes' => $record->dailyPlayTimeInMinutes(),
            'total_play_time' => $record->total_play_time,
            'last_play_date' => $record->last_play_date?->format('Y-m-d'),
            'session_count' => $record->session_count,
        ]);
    }
}
