<?php

namespace App\Services\Badges;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

class BadgeUserLookupService
{
    public function __construct(
        protected BadgeTextFormatter $formatter
    ) {
    }

    public function fetchStaffList(?string $schoolYear, array $selectedUserIds = []): array
    {
        $query = DB::table('users')
            ->leftJoin('user_roles', 'user_roles.user_id', '=', 'users.id')
            ->leftJoin('roles', 'roles.id', '=', 'user_roles.role_id')
            ->select([
                'users.id',
                'users.firstname',
                'users.lastname',
                DB::raw("GROUP_CONCAT(DISTINCT CASE WHEN LOWER(roles.name) != 'parent' THEN roles.name END ORDER BY roles.name SEPARATOR ', ') as roles"),
            ])
            ->groupBy('users.id', 'users.firstname', 'users.lastname');

        if (!empty($selectedUserIds)) {
            $query->whereIn('users.id', $selectedUserIds);
        }

        if (!empty($schoolYear) && Schema::hasColumn('user_roles', 'school_year')) {
            $query->where('user_roles.school_year', $schoolYear);
        }

        return array_map(static fn ($row) => (array) $row, $query->get()->all());
    }

    public function getLatestClassForUser(int $userId, ?string $schoolYear = null): ?array
    {
        $query = DB::table('teacher_class as tc')
            ->leftJoin('classSection as cs', 'cs.class_section_id', '=', 'tc.class_section_id')
            ->select([
                'tc.class_section_id',
                'cs.class_section_name',
            ])
            ->where('tc.teacher_id', $userId);

        if (!empty($schoolYear)) {
            $query->where('tc.school_year', $schoolYear);
        }

        $row = $query
            ->orderByRaw("FIELD(tc.position, 'main', 'ta')")
            ->orderByRaw('IFNULL(tc.updated_at,"0000-00-00 00:00:00") DESC')
            ->orderByDesc('tc.id')
            ->first();

        if (!$row || empty($row->class_section_id)) {
            return null;
        }

        return [
            'class_section_id'   => (int) $row->class_section_id,
            'class_section_name' => $row->class_section_name ?? null,
        ];
    }

    public function getUserInfoById(int $id, ?string $schoolYear = null): ?array
    {
        $u = DB::table('users')
            ->select(['id as user_id', 'firstname', 'lastname'])
            ->where('id', $id)
            ->first();

        if (!$u) {
            return null;
        }

        $userId = (int) $u->user_id;
        $fullname = trim(($u->firstname ?? '') . ' ' . ($u->lastname ?? ''));

        $rolesRows = DB::table('user_roles as ur')
            ->join('roles as r', 'r.id', '=', 'ur.role_id')
            ->select(['r.id as role_id', 'r.name as role_name'])
            ->where('ur.user_id', $userId)
            ->get();

        $allRoles = [];
        foreach ($rolesRows as $rr) {
            $name = trim((string) ($rr->role_name ?? ''));
            if ($name !== '' && strtolower($name) !== 'parent') {
                $allRoles[] = ucwords(strtolower($name));
            }
        }

        $allRoles = array_values(array_unique($allRoles));
        $rolesCsv = $allRoles ? implode(', ', $allRoles) : '';

        $tcQuery = DB::table('teacher_class')
            ->select(['class_section_id', 'updated_at', 'id', 'position', 'school_year'])
            ->where('teacher_id', $userId);

        if (!empty($schoolYear)) {
            $tcQuery->where('school_year', $schoolYear);
        }

        $assignment = $tcQuery
            ->orderByRaw('IFNULL(updated_at, "1970-01-01 00:00:00") DESC, id DESC')
            ->first();

        $classId = $assignment->class_section_id ?? null;
        $position = strtolower(trim((string) ($assignment->position ?? '')));
        $className = null;

        if (!empty($classId)) {
            $className = $this->resolveClassName((int) $classId);
        }

        if (in_array($position, ['ta', 'teacher_assistant', 'assistant'], true)) {
            $roleLabel = 'Teacher Assistant';
        } elseif ($position === 'teacher' || $position === 'main') {
            $roleLabel = 'Teacher';
        } elseif (!empty($allRoles)) {
            $roleLabel = $allRoles[0];
        } else {
            $roleLabel = 'Staff';
        }

        $schoolLogo = $this->formatter->firstExisting([
            public_path('assets/images/school_logo.png'),
            public_path('assets/images/logo.png'),
        ]);

        $isglLogo = $this->formatter->firstExisting([
            public_path('assets/images/isgl_logo.png'),
            public_path('assets/images/isgl.png'),
        ]);

        $jobTitle = '';
        if (!empty($roleLabel) && !empty($className)) {
            $jobTitle = "{$roleLabel} - {$className}";
        } elseif (!empty($roleLabel)) {
            $jobTitle = $roleLabel;
        } elseif (!empty($className)) {
            $jobTitle = $className;
        }

        return [
            'user_id'             => $userId,
            'name'                => $fullname !== '' ? $fullname : 'STAFF',
            'role'                => $roleLabel,
            'roles'               => $rolesCsv,
            'class_section_id'    => $classId ? (int) $classId : null,
            'class_section_name'  => $className,
            'job_title'           => $jobTitle,
            'school_name'         => 'Al Rahma Sunday School',
            'school_id'           => $userId,
            'school_logo'         => $schoolLogo,
            'isgl_logo'           => $isglLogo,
            'school_year'         => $assignment->school_year ?? $schoolYear,
        ];
    }

    public function getAvailableSchoolYears(): array
    {
        $schoolYears = [];

        try {
            if (Schema::hasTable('teacher_class')) {
                $schoolYears = DB::table('teacher_class')
                    ->selectRaw('DISTINCT school_year')
                    ->whereNotNull('school_year')
                    ->orderByDesc('school_year')
                    ->pluck('school_year')
                    ->filter()
                    ->values()
                    ->all();
            }
        } catch (\Throwable) {
        }

        if (empty($schoolYears)) {
            try {
                if (Schema::hasTable('user_roles') && Schema::hasColumn('user_roles', 'school_year')) {
                    $schoolYears = DB::table('user_roles')
                        ->selectRaw('DISTINCT school_year')
                        ->whereNotNull('school_year')
                        ->orderByDesc('school_year')
                        ->pluck('school_year')
                        ->filter()
                        ->values()
                        ->all();
                }
            } catch (\Throwable) {
            }
        }

        return $schoolYears;
    }

    protected function resolveClassName(int $classSectionId): ?string
    {
        $row = DB::table('classSection')
            ->select('class_section_name')
            ->where('class_section_id', $classSectionId)
            ->first();

        return $row->class_section_name ?? null;
    }
}