<?php

namespace App\Services\Staff;

use App\Models\Staff;
use App\Models\TeacherClass;
use App\Models\User;
use App\Services\System\GlobalConfigService;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;

class StaffQueryService
{
    public function __construct(private GlobalConfigService $configService)
    {
    }

    public function paginate(array $filters, int $page, int $perPage): array
    {
        $excluded = ['student', 'parent', 'guest', 'inactive'];

        $query = Staff::query()
            ->whereNotIn(DB::raw('LOWER(active_role)'), $excluded);

        if (!empty($filters['role'])) {
            $role = strtolower(trim((string) $filters['role']));
            $query->whereRaw('LOWER(active_role) = ?', [$role]);
        }

        $sortBy = $filters['sort_by'] ?? 'created_at';
        $sortDir = strtolower((string) ($filters['sort_dir'] ?? 'desc')) === 'asc' ? 'asc' : 'desc';

        $paginator = $query
            ->orderBy($sortBy, $sortDir)
            ->paginate($perPage, ['*'], 'page', $page);

        $schoolYear = (string) ($filters['school_year'] ?? $this->configService->getSchoolYear() ?? '');
        $semester = (string) ($filters['semester'] ?? $this->configService->getSemester() ?? '');

        $assignByTeacher = $this->buildAssignments($schoolYear);

        $issuesCount = 0;
        $items = $paginator->getCollection()->map(function ($staff) use ($assignByTeacher, &$issuesCount) {
            $staff->school_id = User::getSchoolIdByUserId((int) ($staff->user_id ?? 0));

            $role = strtolower((string) ($staff->active_role ?? ''));
            if (in_array($role, ['teacher', 'teacher_assistant'], true)) {
                $tid = (int) ($staff->user_id ?? 0);
                $labels = $assignByTeacher[$tid] ?? [];
                if (!empty($labels)) {
                    $staff->class_section = implode(', ', array_unique($labels));
                    $staff->verification_issue = false;
                } else {
                    $staff->class_section = 'No class assigned';
                    $staff->verification_issue = true;
                    $issuesCount++;
                }
            } else {
                $staff->class_section = '—';
                $staff->verification_issue = false;
            }

            return $staff;
        });

        $paginator->setCollection($items);

        return [
            'paginator' => $paginator,
            'issues_count' => $issuesCount,
            'semester' => $semester,
            'school_year' => $schoolYear,
        ];
    }

    public function find(int $id): ?Staff
    {
        return Staff::query()->find($id);
    }

    private function buildAssignments(string $schoolYear): array
    {
        if ($schoolYear === '') {
            return [];
        }

        $rows = TeacherClass::query()
            ->select('teacher_class.teacher_id', 'teacher_class.position', 'classSection.class_section_name')
            ->leftJoin('classSection', 'classSection.class_section_id', '=', 'teacher_class.class_section_id')
            ->where('teacher_class.school_year', $schoolYear)
            ->get();

        $assignByTeacher = [];
        foreach ($rows as $row) {
            $tid = (int) ($row->teacher_id ?? 0);
            if ($tid <= 0) {
                continue;
            }
            $name = trim((string) ($row->class_section_name ?? ''));
            if ($name === '') {
                continue;
            }
            $pos = strtolower((string) ($row->position ?? ''));
            if (!in_array($pos, ['main', 'ta'], true)) {
                continue;
            }
            $assignByTeacher[$tid][] = $name . ' (' . $pos . ')';
        }

        return $assignByTeacher;
    }
}
