<?php

namespace App\Http\Controllers\Api\Exams;

use App\Http\Controllers\Api\Core\BaseApiController;
use App\Http\Requests\Exams\ExamDraftAdminLegacyRequest;
use App\Http\Requests\Exams\ExamDraftAdminReviewRequest;
use App\Http\Requests\Exams\ExamDraftTeacherStoreRequest;
use App\Http\Resources\Exams\ExamDraftResource;
use App\Services\Exams\ExamDraftAdminService;
use App\Services\Exams\ExamDraftTeacherService;
use Illuminate\Http\JsonResponse;

class ExamDraftController extends BaseApiController
{
    public function __construct(
        private ExamDraftTeacherService $teacherService,
        private ExamDraftAdminService $adminService
    ) {
        parent::__construct();
    }

    public function teacherIndex(): JsonResponse
    {
        $guard = $this->authenticatedUserIdOrUnauthorized();
        if ($guard instanceof JsonResponse) {
            return $guard;
        }

        $data = $this->teacherService->listForTeacher($guard);

        return response()->json([
            'ok' => true,
            'assignments' => $data['assignments'],
            'drafts' => ExamDraftResource::collection($data['drafts']),
            'legacy_exams' => ExamDraftResource::collection($data['legacyExams']),
            'exam_types' => $data['examTypes'],
            'status_options' => $data['statusOptions'],
            'school_year' => $data['schoolYear'],
            'semester' => $data['semester'],
        ]);
    }

    public function teacherStore(ExamDraftTeacherStoreRequest $request): JsonResponse
    {
        $guard = $this->authenticatedUserIdOrUnauthorized();
        if ($guard instanceof JsonResponse) {
            return $guard;
        }

        $result = $this->teacherService->store($guard, $request->validated(), $request->file('draft_file'));
        if (!$result['ok']) {
            return response()->json(['ok' => false, 'message' => $result['message'] ?? 'Unable to save.'], 422);
        }

        return response()->json([
            'ok' => true,
            'draft' => new ExamDraftResource($result['draft']),
        ], 201);
    }

    public function adminIndex(): JsonResponse
    {
        $data = $this->adminService->list();

        return response()->json([
            'ok' => true,
            'drafts' => ExamDraftResource::collection($data['drafts']),
            'class_sections' => $data['classSections'],
            'legacy_by_class' => $data['legacyByClass'],
            'exam_types' => $data['examTypes'],
            'status_options' => $data['statusOptions'],
            'school_year' => $data['schoolYear'],
            'semester' => $data['semester'],
            'allowed_extensions' => $data['allowedExtensions'],
            'max_upload_bytes' => $data['maxUploadBytes'],
        ]);
    }

    public function adminUploadLegacy(ExamDraftAdminLegacyRequest $request): JsonResponse
    {
        $guard = $this->authenticatedUserIdOrUnauthorized();
        if ($guard instanceof JsonResponse) {
            return $guard;
        }

        $result = $this->adminService->uploadLegacy($guard, $request->validated(), $request->file('old_exam_file'));
        if (!$result['ok']) {
            return response()->json(['ok' => false, 'message' => $result['message'] ?? 'Unable to save.'], 422);
        }

        return response()->json([
            'ok' => true,
            'draft' => new ExamDraftResource($result['draft']),
        ], 201);
    }

    public function adminReview(ExamDraftAdminReviewRequest $request): JsonResponse
    {
        $guard = $this->authenticatedUserIdOrUnauthorized();
        if ($guard instanceof JsonResponse) {
            return $guard;
        }

        $result = $this->adminService->review($guard, $request->validated(), $request->file('final_file'));
        if (!$result['ok']) {
            return response()->json(['ok' => false, 'message' => $result['message'] ?? 'Unable to save.'], 422);
        }

        return response()->json([
            'ok' => true,
            'draft' => new ExamDraftResource($result['draft']),
        ]);
    }

    /**
     * @return int|JsonResponse
     */
    private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
    {
        $userId = (int) (auth()->id() ?? 0);
        if ($userId <= 0) {
            return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
        }

        return $userId;
    }
}
