<?php

namespace App\Services\Teachers;

use App\Models\StudentAllergy;
use App\Models\StudentClass;
use App\Models\StudentMedicalCondition;
use App\Models\TeacherClass;
use App\Models\User;
use Illuminate\Support\Facades\DB;

class TeacherDashboardService
{
    public function __construct(private TeacherConfigService $configService)
    {
    }

    public function classView(int $userId, ?int $requestedClassSectionId = null): array
    {
        $context = $this->configService->context();
        $schoolYear = (string) ($context['school_year'] ?? '');
        $semester = (string) ($context['semester'] ?? '');

        $roles = DB::table('user_roles as ur')
            ->join('roles as r', 'r.id', '=', 'ur.role_id')
            ->where('ur.user_id', $userId)
            ->whereNull('ur.deleted_at')
            ->pluck('r.name')
            ->map(fn ($r) => strtolower((string) $r))
            ->all();

        if (!array_intersect($roles, ['teacher', 'teacher_assistant'])) {
            throw new \RuntimeException('Access denied.');
        }

        $classes = TeacherClass::getClassAssignmentsByUserId($userId, $schoolYear, $semester);
        if (empty($classes)) {
            return [
                'teacher' => null,
                'classes' => [],
                'students' => [],
                'studentsBySection' => [],
                'active_class_section_id' => null,
                'class_section_name' => null,
                'assignedNames' => [],
            ];
        }

        $classSectionIds = array_values(array_unique(array_map('intval', array_column($classes, 'class_section_id'))));
        $activeClassSectionId = null;
        if ($requestedClassSectionId && in_array($requestedClassSectionId, $classSectionIds, true)) {
            $activeClassSectionId = $requestedClassSectionId;
        } elseif (!empty($classSectionIds)) {
            $activeClassSectionId = $classSectionIds[0];
        }

        $studentsBySection = [];
        if (!empty($classSectionIds)) {
            $students = StudentClass::getStudentsByClassSectionIds($classSectionIds);
            if (!empty($students)) {
                $studentIds = array_values(array_unique(array_map(
                    static fn (array $row) => (int) ($row['student_id'] ?? 0),
                    $students
                )));
                $studentIds = array_values(array_filter($studentIds));

                $conditionsByStudent = !empty($studentIds)
                    ? StudentMedicalCondition::getMedicalByStudentIds($studentIds)
                    : [];
                $allergiesByStudent = !empty($studentIds)
                    ? StudentAllergy::getAllergiesByStudentIds($studentIds)
                    : [];

                foreach ($students as $student) {
                    $sid = (int) ($student['student_id'] ?? 0);
                    $cid = (int) ($student['class_section_id'] ?? 0);

                    $medList = array_column($conditionsByStudent[$sid] ?? [], 'condition_name');
                    $algList = array_column($allergiesByStudent[$sid] ?? [], 'allergy');

                    $student['medical_conditions'] = $medList;
                    $student['allergies'] = $algList;
                    $student['medical_conditions_text'] = implode(', ', $medList);
                    $student['allergies_text'] = implode(', ', $algList);

                    $studentsBySection[$cid][] = $student;
                }
            }
        }

        $assignedNames = [];
        if (!empty($classSectionIds)) {
            $rows = DB::table('teacher_class as tc')
                ->select('tc.class_section_id', 'tc.position', 'u.firstname', 'u.lastname')
                ->join('users as u', 'u.id', '=', 'tc.teacher_id')
                ->whereIn('tc.class_section_id', $classSectionIds)
                ->where('tc.school_year', $schoolYear)
                ->orderBy('tc.class_section_id')
                ->orderByRaw("CASE tc.position WHEN 'main' THEN 0 WHEN 'ta' THEN 1 ELSE 2 END")
                ->orderBy('u.firstname')
                ->get();

            foreach ($rows as $row) {
                $sid = (int) ($row->class_section_id ?? 0);
                $pos = strtolower((string) ($row->position ?? ''));
                $name = trim(($row->firstname ?? '') . ' ' . ($row->lastname ?? ''));
                if ($sid === 0 || $name === '') {
                    continue;
                }
                if (in_array($pos, ['main', 'teacher'], true)) {
                    $assignedNames[$sid]['mains'][] = $name;
                } elseif (in_array($pos, ['ta', 'assistant', 'teacher_assistant'], true)) {
                    $assignedNames[$sid]['tas'][] = $name;
                } else {
                    $assignedNames[$sid]['others'][] = $name;
                }
            }
        }

        $teacher = User::query()->find($userId)?->toArray();

        $classSectionName = null;
        if ($activeClassSectionId !== null && (int) $activeClassSectionId > 0) {
            foreach ($classes as $row) {
                if ((int) ($row['class_section_id'] ?? 0) === (int) $activeClassSectionId) {
                    $n = trim((string) ($row['class_section_name'] ?? ''));
                    $classSectionName = $n !== '' ? $n : null;
                    break;
                }
            }
        }

        return [
            'teacher' => $teacher,
            'classes' => $classes,
            'students' => $activeClassSectionId ? ($studentsBySection[$activeClassSectionId] ?? []) : [],
            'studentsBySection' => $studentsBySection,
            'active_class_section_id' => $activeClassSectionId,
            'class_section_name' => $classSectionName,
            'assignedNames' => $assignedNames,
        ];
    }
}
