<?php

declare(strict_types=1);

namespace App\Http\Controllers\Api\App;

use App\Http\Controllers\Controller;
use App\Models\SchoolClass;
use App\Models\WrongQuestion;
use App\Services\LearningAccessService;
use App\Support\ApiResponse;
use hg\apidoc\annotation as Apidoc;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

#[Apidoc\Group('用户端')]
#[Apidoc\Title('班级学习入口')]
#[Apidoc\RouteMiddleware(['jwt.auth'])]
final class ClassroomController extends Controller
{
    #[Apidoc\Title('我的班级')]
    #[Apidoc\Url('/app/classes')]
    #[Apidoc\Method('GET')]
    public function myClasses(Request $request): JsonResponse
    {
        return ApiResponse::success(
            SchoolClass::query()
                ->whereHas('members', fn ($query) => $query->where('users.id', $request->user()->id))
                ->withCount('members')
                ->get(),
        );
    }

    #[Apidoc\Title('通过班级码加入')]
    #[Apidoc\Url('/app/classes/join')]
    #[Apidoc\Method('POST')]
    public function join(Request $request): JsonResponse
    {
        $data = $request->validate(['join_code' => ['required', 'string']]);
        $class = SchoolClass::query()->where('join_code', strtoupper($data['join_code']))->where('is_active', true)->firstOrFail();
        $class->members()->syncWithoutDetaching([$request->user()->id => ['role' => 'student']]);

        return ApiResponse::success($class, '已加入班级');
    }

    #[Apidoc\Title('可学习资源')]
    #[Apidoc\Url('/app/resources')]
    #[Apidoc\Method('GET')]
    public function resources(Request $request, LearningAccessService $access): JsonResponse
    {
        $banks = $access->visibleBanksQuery($request->user())
            ->withCount('questions')
            ->get();

        $wrongCounts = WrongQuestion::query()
            ->where('user_id', $request->user()->id)
            ->whereNull('mastered_at')
            ->join('questions', 'questions.id', '=', 'wrong_questions.question_id')
            ->selectRaw('questions.question_bank_id, count(*) as total')
            ->groupBy('questions.question_bank_id')
            ->pluck('total', 'question_bank_id');

        $banks->each(fn ($bank) => $bank->setAttribute('wrong_questions_count', (int) ($wrongCounts[$bank->id] ?? 0)));

        $papers = $access->visiblePapersQuery($request->user())
            ->withCount('questions')
            ->latest()
            ->get();

        return ApiResponse::success(['banks' => $banks, 'papers' => $papers]);
    }
}
