<?php

declare(strict_types=1);

namespace App\Http\Controllers\Api\Admin;

use App\Http\Controllers\Api\Admin\Concerns\AuthorizesOwnedResources;
use App\Http\Controllers\Controller;
use App\Models\ExportJob;
use App\Models\OperationLog;
use App\Models\QuestionBank;
use App\Support\ApiResponse;
use hg\apidoc\annotation as Apidoc;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;

#[Apidoc\Group('后台')]
#[Apidoc\Title('题库管理')]
#[Apidoc\RouteMiddleware(['jwt.auth'])]
final class QuestionBankController extends Controller
{
    use AuthorizesOwnedResources;

    #[Apidoc\Title('题库列表')]
    #[Apidoc\Url('/admin/banks')]
    #[Apidoc\Method('GET')]
    #[Apidoc\RouteMiddleware(['permission:banks'])]
    public function index(Request $request): JsonResponse
    {
        $query = $this->ownedBanksQuery($request)->withCount('questions')->latest();
        if ($keyword = $request->query('keyword')) {
            $query->where('name', 'like', '%'.$keyword.'%');
        }

        return ApiResponse::page($query->paginate((int) $request->query('per_page', 20)));
    }

    #[Apidoc\Title('创建题库')]
    #[Apidoc\Url('/admin/banks')]
    #[Apidoc\Method('POST')]
    #[Apidoc\RouteMiddleware(['permission:banks.create'])]
    public function store(Request $request): JsonResponse
    {
        $data = $request->validate([
            'name' => ['required', 'string', 'max:120'],
            'description' => ['nullable', 'string'],
            'visibility' => ['required', 'in:public,private,assigned'],
        ]);

        $bank = QuestionBank::create($data + ['owner_id' => $request->user()->id, 'is_active' => true]);
        OperationLog::create([
            'user_id' => $request->user()->id,
            'action' => 'bank.created',
            'target_type' => QuestionBank::class,
            'target_id' => $bank->id,
            'ip' => $request->ip(),
            'payload' => ['name' => $bank->name],
        ]);

        return ApiResponse::success($bank, '题库已创建');
    }

    #[Apidoc\Title('更新题库')]
    #[Apidoc\Url('/admin/banks/{bank}')]
    #[Apidoc\Method('PUT')]
    #[Apidoc\RouteMiddleware(['permission:banks.update'])]
    public function update(Request $request, mixed $bank): JsonResponse
    {
        $bank = $this->resolveBank($bank);
        $this->authorizeBankOwner($request, $bank);
        $data = $request->validate([
            'name' => ['sometimes', 'string', 'max:120'],
            'description' => ['nullable', 'string'],
            'visibility' => ['sometimes', 'in:public,private,assigned'],
            'is_active' => ['sometimes', 'boolean'],
        ]);

        $bank->update($data);

        return ApiResponse::success($bank->fresh(), '题库已更新');
    }

    #[Apidoc\Title('删除题库')]
    #[Apidoc\Url('/admin/banks/{bank}')]
    #[Apidoc\Method('DELETE')]
    #[Apidoc\RouteMiddleware(['permission:banks.delete'])]
    public function destroy(Request $request, mixed $bank): JsonResponse
    {
        $bank = $this->resolveBank($bank);
        $this->authorizeBankOwner($request, $bank);
        $bank->delete();
        OperationLog::create([
            'user_id' => $request->user()->id,
            'action' => 'bank.deleted',
            'target_type' => QuestionBank::class,
            'target_id' => $bank->id,
            'ip' => $request->ip(),
        ]);

        return ApiResponse::success(null, '题库已删除');
    }

    #[Apidoc\Title('题库授权')]
    #[Apidoc\Url('/admin/banks/{bank}/shares')]
    #[Apidoc\Method('POST')]
    #[Apidoc\RouteMiddleware(['permission:banks.share'])]
    public function share(Request $request, mixed $bank): JsonResponse
    {
        $bank = $this->resolveBank($bank);
        $this->authorizeBankOwner($request, $bank);
        $data = $request->validate([
            'targets' => ['array'],
            'targets.*.type' => ['required', 'in:user,class'],
            'targets.*.id' => ['required', 'integer'],
        ]);

        DB::table('bank_shares')->where('question_bank_id', $bank->id)->delete();
        foreach ($data['targets'] ?? [] as $target) {
            DB::table('bank_shares')->insert([
                'question_bank_id' => $bank->id,
                'target_type' => $target['type'],
                'target_id' => $target['id'],
                'created_at' => now(),
                'updated_at' => now(),
            ]);
        }

        $bank->update(['visibility' => ($data['targets'] ?? []) === [] ? $bank->visibility : 'assigned']);

        return ApiResponse::success(null, '授权已保存');
    }

    #[Apidoc\Title('题库导出')]
    #[Apidoc\Url('/admin/banks/{bank}/export')]
    #[Apidoc\Method('POST')]
    #[Apidoc\RouteMiddleware(['permission:questions.export'])]
    public function export(Request $request, mixed $bank): JsonResponse
    {
        $bank = $this->resolveBank($bank);
        $this->authorizeBankOwner($request, $bank);
        $payload = $bank->load('questions.options', 'categories', 'tags')->toArray();
        $path = 'exports/bank-'.$bank->id.'-'.now()->format('YmdHis').'.json';
        Storage::put($path, json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));

        $job = ExportJob::create([
            'user_id' => $request->user()->id,
            'type' => 'question_bank',
            'file_path' => $path,
            'payload' => ['question_bank_id' => $bank->id],
        ]);

        return ApiResponse::success($job, '题库已导出');
    }

    private function resolveBank(mixed $bank): QuestionBank
    {
        if ($bank instanceof QuestionBank && $bank->exists) {
            return $bank;
        }

        return QuestionBank::query()->findOrFail((int) $bank);
    }
}
