<?php

namespace App\Http\Controllers\Api\Staff;

use App\Http\Controllers\Api\Core\BaseApiController;
use App\Http\Requests\Teachers\TeacherAbsenceSubmitRequest;
use App\Http\Requests\Teachers\TeacherClassViewRequest;
use App\Http\Requests\Teachers\TeacherSwitchClassRequest;
use App\Http\Resources\Teachers\TeacherAbsenceResource;
use App\Http\Resources\Teachers\TeacherClassResource;
use App\Http\Resources\Teachers\TeacherStudentResource;
use App\Models\User;
use App\Services\Teachers\TeacherAbsenceService;
use App\Services\Teachers\TeacherDashboardService;
use Illuminate\Http\JsonResponse;

class TeacherController extends BaseApiController
{
    public function __construct(
        private TeacherDashboardService $dashboardService,
        private TeacherAbsenceService $absenceService
    ) {
        parent::__construct();
    }

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

        try {
            $data = $this->dashboardService->classView(
                $guard,
                $request->validated()['class_section_id'] ?? null
            );
        } catch (\RuntimeException $e) {
            return response()->json(['ok' => false, 'message' => $e->getMessage()], 403);
        }

        $teacher = $this->teacherPayload($data['teacher'] ?? null, $guard);
        $studentsBySection = [];

        foreach (($data['studentsBySection'] ?? []) as $sectionId => $students) {
            $studentsBySection[(string) $sectionId] = TeacherStudentResource::collection($students);
        }

        return response()->json([
            'ok' => true,
            'teacher' => $teacher,
            'classes' => TeacherClassResource::collection($data['classes'] ?? []),
            'students' => TeacherStudentResource::collection($data['students'] ?? []),
            'students_by_section' => $studentsBySection,
            'assigned_names' => $data['assignedNames'] ?? [],
            'active_class_section_id' => $data['active_class_section_id'] ?? null,
            'class_section_name' => $data['class_section_name'] ?? null,
        ]);
    }

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

        $requested = (int) $request->validated()['class_section_id'];

        try {
            $data = $this->dashboardService->classView($guard, $requested);
        } catch (\RuntimeException $e) {
            return response()->json(['ok' => false, 'message' => $e->getMessage()], 403);
        }

        if (($data['active_class_section_id'] ?? null) !== $requested) {
            return response()->json([
                'ok' => false,
                'message' => 'You are not assigned to that class.',
            ], 422);
        }

        return response()->json([
            'ok' => true,
            'active_class_section_id' => $requested,
        ]);
    }

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

        $data = $this->absenceService->formData($guard);

        return response()->json([
            'ok' => true,
            'teacher_name' => $data['teacher_name'],
            'semester' => $data['semester'],
            'school_year' => $data['school_year'],
            'existing' => TeacherAbsenceResource::collection($data['existing'] ?? []),
            'available_dates' => $data['available_dates'] ?? [],
        ]);
    }

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

        $result = $this->absenceService->submit($guard, $request->validated());

        return response()->json([
            'ok' => (bool) ($result['ok'] ?? false),
            'message' => $result['message'] ?? '',
            'saved' => $result['saved'] ?? 0,
            'dates' => $result['dates'] ?? [],
        ], (int) ($result['status'] ?? 200));
    }

    private function teacherPayload(?array $teacher, int $userId): ?array
    {
        if (!$teacher) {
            $model = User::query()->find($userId);
            $teacher = $model?->toArray();
        }

        if (!$teacher) {
            return null;
        }

        return [
            'id' => (int) ($teacher['id'] ?? 0),
            'firstname' => (string) ($teacher['firstname'] ?? ''),
            'lastname' => (string) ($teacher['lastname'] ?? ''),
            'email' => $teacher['email'] ?? null,
            'role' => User::getUserRoleName($userId),
        ];
    }

    /**
     * @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;
    }
}
