<?php

namespace App\Services\Badges;

class BadgeFormDataService
{
    public function __construct(
        protected BadgeUserLookupService $lookupService,
        protected BadgeStudentLookupService $studentLookupService,
        protected BadgeTextFormatter $formatter
    ) {
    }

    public function build(
        ?string $schoolYear,
        array $selectedUserIds = [],
        array $selectedStudentIds = [],
        ?string $activeRole = null
    ): array {
        $selectedUserIds = $this->formatter->normalizeIds($selectedUserIds);
        $selectedStudentIds = $this->formatter->normalizeIds($selectedStudentIds);

        $users = $this->lookupService->fetchStaffList($schoolYear, $selectedUserIds);
        $students = $this->studentLookupService->fetchStudentList($schoolYear, $selectedStudentIds);

        foreach ($users as &$u) {
            if (!isset($u['user_id']) && isset($u['id'])) {
                $u['user_id'] = (int) $u['id'];
            }

            $rolesStr = $u['roles'] ?? '';
            if ($rolesStr === '' && isset($u['role_name'])) {
                $rolesStr = (string) $u['role_name'];
            }

            $u['roles_raw'] = $rolesStr;
            $u['roles'] = $this->formatter->formatRolesCsv($rolesStr);

            if (empty($u['role_name'])) {
                $parts = array_filter(array_map('trim', explode(',', $rolesStr)));
                $u['role_name'] = $parts[0] ?? '';
            }

            $u['role_name_raw'] = $u['role_name'];
            $u['role_name'] = $this->formatter->formatRole((string) $u['role_name']);
            $u['class_section_id'] = $u['class_section_id'] ?? null;
            $u['class_section_name'] = $u['class_section_name'] ?? null;
            $u['entity_type'] = 'user';
            $u['row_id'] = 'user:' . (int) ($u['user_id'] ?? 0);
            $u['role_group'] = $this->detectRoleGroup(
                strtolower((string) ($u['roles_raw'] ?? ($u['role_name_raw'] ?? '')))
            );
        }
        unset($u);

        foreach ($users as &$u) {
            $rolesDetect = strtolower((string) ($u['roles_raw'] ?? ($u['role_name_raw'] ?? '')));
            $isTeacherish = str_contains($rolesDetect, 'teacher') || preg_match('/\bta\b/', $rolesDetect);

            if ($isTeacherish && !empty($u['user_id'])) {
                $assign = $this->lookupService->getLatestClassForUser((int) $u['user_id'], $schoolYear);
                if ($assign) {
                    $u['class_section_id'] = $assign['class_section_id'] ?? null;
                    $u['class_section_name'] = $assign['class_section_name'] ?? null;
                }
            }
        }
        unset($u);

        foreach ($students as &$student) {
            $student['entity_type'] = 'student';
            $student['row_id'] = 'student:' . (int) ($student['student_id'] ?? 0);
            $student['role_group'] = 'student';
            $student['class_section_id'] = null;

            if (empty($student['class_section_name'])) {
                $student['class_section_name'] = $this->formatter->formatClass(
                    (string) ($student['registration_grade'] ?? '')
                );
            }
        }
        unset($student);

        $rows = array_merge($users, $students);
        usort($rows, static function (array $a, array $b): int {
            return strcasecmp(
                trim((string) ($a['lastname'] ?? '')) . ' ' . trim((string) ($a['firstname'] ?? '')),
                trim((string) ($b['lastname'] ?? '')) . ' ' . trim((string) ($b['firstname'] ?? ''))
            );
        });

        $rolesTabs = [
            'all'     => 'All',
            'teacher' => 'Teachers',
            'ta'      => 'Teacher Assistants',
            'admin'   => 'Admins',
            'staff'   => 'Staff',
            'student' => 'Students',
        ];

        $activeRole = array_key_exists((string) $activeRole, $rolesTabs)
            ? (string) $activeRole
            : 'all';

        return [
            'users'              => $rows,
            'schoolYears'        => $this->lookupService->getAvailableSchoolYears(),
            'selectedYear'       => $schoolYear,
            'selectedUserIds'    => $selectedUserIds,
            'selectedStudentIds' => $selectedStudentIds,
            'rolesTabs'          => $rolesTabs,
            'active_role'        => $activeRole,
        ];
    }

    protected function detectRoleGroup(string $rolesDetect): string
    {
        if (str_contains($rolesDetect, 'assistant') || preg_match('/\bta\b/', $rolesDetect)) {
            return 'ta';
        }

        if (str_contains($rolesDetect, 'teacher')) {
            return 'teacher';
        }

        if (str_contains($rolesDetect, 'admin')) {
            return 'admin';
        }

        return 'staff';
    }
}
