<?php

namespace App\Services\Teachers;

use App\Models\ClassSection;
use App\Models\TeacherClass;
use App\Models\User;

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

    public function listAssignments(?string $schoolYear = null): array
    {
        $context = $this->configService->context();
        $schoolYear = $schoolYear ?: (string) ($context['school_year'] ?? '');
        $semester = trim((string) ($context['semester'] ?? ''));

        $teachers = User::getTeachersAndTAs();
        $classSections = ClassSection::query()
            ->when($schoolYear !== '', fn ($q) => $q->where('school_year', $schoolYear))
            ->orderBy('class_section_name')
            ->get()
            ->toArray();

        if (empty($classSections)) {
            $classSections = ClassSection::query()->orderBy('class_section_name')->get()->toArray();
        }

        $classNames = [];
        foreach ($classSections as $section) {
            $sectionId = (int) ($section['class_section_id'] ?? $section['id'] ?? 0);
            if ($sectionId <= 0) {
                continue;
            }
            $classNames[$sectionId] = $section['class_section_name'] ?? 'N/A';
        }

        $assignments = TeacherClass::query()
            ->when($schoolYear !== '', fn ($q) => $q->where('school_year', $schoolYear))
            ->when($semester !== '', fn ($q) => $q->where('semester', $semester))
            ->get()
            ->toArray();

        $assignmentMap = [];
        foreach ($assignments as $assign) {
            $teacherId = (int) ($assign['teacher_id'] ?? 0);
            $sectionId = (int) ($assign['class_section_id'] ?? 0);
            if ($teacherId <= 0 || $sectionId <= 0) {
                continue;
            }

            $role = strtolower((string) ($assign['position'] ?? ''));
            if (!in_array($role, ['main', 'ta'], true)) {
                continue;
            }

            $assignmentMap[$teacherId][$role][] = [
                'section_id' => $sectionId,
                'class_section_name' => $classNames[$sectionId] ?? 'N/A',
                'role' => $role,
                'semester' => (string) ($assign['semester'] ?? ''),
                'school_year' => (string) ($assign['school_year'] ?? $schoolYear),
            ];
        }

        $teacherData = [];
        foreach ($teachers as $teacher) {
            $tid = (int) ($teacher['id'] ?? 0);
            if ($tid <= 0) {
                continue;
            }
            $assigned = $assignmentMap[$tid] ?? ['main' => [], 'ta' => []];
            $name = trim(($teacher['firstname'] ?? '') . ' ' . ($teacher['lastname'] ?? ''));
            if ($name === '') {
                $name = 'User#' . $tid;
            }

            $teacherData[] = [
                'teacher_id' => $tid,
                'firstname' => $teacher['firstname'] ?? '',
                'lastname' => $teacher['lastname'] ?? '',
                'name' => $name,
                'email' => $teacher['email'] ?? '',
                'cellphone' => $teacher['cellphone'] ?? '',
                'role' => $teacher['role'] ?? '',
                'school_year' => $schoolYear,
                'main_assignments' => $assigned['main'] ?? [],
                'ta_assignments' => $assigned['ta'] ?? [],
            ];
        }

        $classesPayload = [];
        foreach ($classSections as $section) {
            $sectionId = (int) ($section['class_section_id'] ?? $section['id'] ?? 0);
            if ($sectionId <= 0) {
                continue;
            }
            $classesPayload[] = [
                'class_section_id' => $sectionId,
                'class_section_name' => $section['class_section_name'] ?? 'N/A',
            ];
        }

        return [
            'school_year' => $schoolYear,
            'teachers' => $teacherData,
            'classes' => $classesPayload,
        ];
    }

    public function assign(array $input): array
    {
        $context = $this->configService->context();
        $schoolYear = (string) ($input['school_year'] ?? $context['school_year'] ?? '');
        $semester = trim((string) ($input['semester'] ?? $context['semester'] ?? ''));
        $teacherId = (int) ($input['teacher_id'] ?? 0);
        $classSectionId = (int) ($input['class_section_id'] ?? 0);
        $teacherRole = (string) ($input['teacher_role'] ?? '');
        $loggedInUserId = (int) ($input['updated_by'] ?? 0);

        if ($teacherId <= 0 || $classSectionId <= 0 || $schoolYear === '' || $semester === '') {
            return ['ok' => false, 'message' => 'Missing required parameters for assignment.'];
        }

        if ($teacherRole === '') {
            $teacherRole = (string) (User::getUserRoleName($teacherId) ?? '');
        }
        $isAssistant = strtolower($teacherRole) === 'teacher_assistant';
        $position = $isAssistant ? 'ta' : 'main';

        $alreadyAssigned = TeacherClass::query()
            ->where('teacher_id', $teacherId)
            ->where('class_section_id', $classSectionId)
            ->where('position', $position)
            ->where('semester', $semester)
            ->where('school_year', $schoolYear)
            ->first();

        if ($alreadyAssigned) {
            return ['ok' => false, 'message' => 'This teacher is already assigned to this class with the same role.'];
        }

        TeacherClass::query()->create([
            'teacher_id' => $teacherId,
            'class_section_id' => $classSectionId,
            'position' => $position,
            'semester' => $semester,
            'school_year' => $schoolYear,
            'created_at' => now(),
            'updated_at' => now(),
            'updated_by' => $loggedInUserId ?: null,
        ]);

        return [
            'ok' => true,
            'message' => 'Class assigned successfully.',
            'position' => $position,
        ];
    }

    public function delete(array $input): array
    {
        $context = $this->configService->context();
        $teacherId = (int) ($input['teacher_id'] ?? 0);
        $classSectionId = (int) ($input['class_section_id'] ?? 0);
        $position = strtolower((string) ($input['position'] ?? ''));
        $semester = trim((string) ($input['semester'] ?? $context['semester'] ?? ''));
        $schoolYear = trim((string) ($input['school_year'] ?? $context['school_year'] ?? ''));

        if ($teacherId <= 0 || $classSectionId <= 0 || !in_array($position, ['main', 'ta'], true) || $schoolYear === '' || $semester === '') {
            return ['ok' => false, 'message' => 'Missing or invalid data for deletion.'];
        }

        $assignment = TeacherClass::query()
            ->where('teacher_id', $teacherId)
            ->where('class_section_id', $classSectionId)
            ->where('semester', $semester)
            ->where('school_year', $schoolYear)
            ->where('position', $position)
            ->first();

        if (!$assignment) {
            return ['ok' => false, 'message' => 'Assignment not found.'];
        }

        $assignment->delete();

        return ['ok' => true, 'message' => ucfirst($position) . ' assignment removed successfully.'];
    }
}
