<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\CompetitionAssignment;
use App\Services\StudentExamService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class StudentExamController extends Controller
{
    public function __construct(
        private readonly StudentExamService $examService,
    ) {
    }

    public function start(Request $request, CompetitionAssignment $assignment): JsonResponse
    {
        $validated = $request->validate([
            'instructions_accepted' => ['required', 'boolean'],
        ]);

        if (! $validated['instructions_accepted']) {
            return response()->json([
                'message' => 'Exam instructions must be accepted before starting.',
            ], 422);
        }

        $result = $this->examService->startExamSession(
            $request->user(),
            $assignment,
            $request->attributes->get('studentDeviceSession'),
            $request,
        );

        if (($result['status'] ?? null) !== 'ok') {
            return response()->json([
                'message' => $result['message'] ?? 'Exam session could not be started.',
            ], 422);
        }

        return response()->json([
            'message' => 'Exam session started.',
            'session' => $result['session'],
        ]);
    }

    public function session(Request $request, CompetitionAssignment $assignment): JsonResponse
    {
        $result = $this->examService->getExamSessionPayload(
            $request->user(),
            $assignment,
            $request->attributes->get('studentDeviceSession'),
            $request,
        );

        $statusCode = match ($result['status'] ?? 'missing') {
            'ok' => 200,
            'submitted' => 409,
            'missing' => 404,
            default => 422,
        };

        return response()->json($result, $statusCode);
    }

    public function heartbeat(Request $request, CompetitionAssignment $assignment): JsonResponse
    {
        $validated = $request->validate([
            'elapsed_seconds' => ['required', 'integer', 'min:0'],
            'answers' => ['nullable', 'array'],
            'answers.*' => ['nullable', 'string', 'in:A,B,C,D'],
        ]);

        $result = $this->examService->syncExamHeartbeat(
            $request->user(),
            $assignment,
            $request->attributes->get('studentDeviceSession'),
            $validated['answers'] ?? [],
            (int) $validated['elapsed_seconds'],
            $request,
        );

        $statusCode = match ($result['status'] ?? 'missing') {
            'ok' => 200,
            'submitted' => 409,
            'missing' => 404,
            default => 422,
        };

        return response()->json($result, $statusCode);
    }

    public function event(Request $request, CompetitionAssignment $assignment): JsonResponse
    {
        $validated = $request->validate([
            'event_type' => ['required', 'string', 'max:120'],
            'payload' => ['nullable', 'array'],
        ]);

        $result = $this->examService->registerExamEvent(
            $request->user(),
            $assignment,
            $request->attributes->get('studentDeviceSession'),
            $validated['event_type'],
            $validated['payload'] ?? [],
            $request,
        );

        $statusCode = match ($result['status'] ?? 'missing') {
            'submitted' => 409,
            'logged' => 200,
            'missing' => 404,
            default => 422,
        };

        return response()->json($result, $statusCode);
    }

    public function submit(Request $request, CompetitionAssignment $assignment): JsonResponse
    {
        $validated = $request->validate([
            'elapsed_seconds' => ['required', 'integer', 'min:0'],
            'answers' => ['nullable', 'array'],
            'answers.*' => ['nullable', 'string', 'in:A,B,C,D'],
        ]);

        $result = $this->examService->submitExamByAssignment(
            $request->user(),
            $assignment,
            $request->attributes->get('studentDeviceSession'),
            $validated['answers'] ?? [],
            (int) $validated['elapsed_seconds'],
            $request,
        );

        $statusCode = match ($result['status'] ?? 'missing') {
            'submitted' => 200,
            'missing' => 404,
            default => 422,
        };

        return response()->json($result, $statusCode);
    }
}
