<?php

namespace App\Http\Controllers\Student;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Inertia\Inertia;
use Inertia\Response;

class DashboardController extends Controller
{
    public function index(Request $request): Response
    {
        $schoolId = $this->currentSchoolId($request);
        $studentId = $request->user()
            ? DB::table('students')->where('user_id', $request->user()->id)->value('id')
            : null;

        $metrics = [
            'todayClasses' => $schoolId && $studentId ? $this->todayClassesCount((int) $schoolId, (int) $studentId) : 0,
            'activeExams' => $schoolId ? DB::table('exams')->where('school_id', $schoolId)->where('status', 'published')->count() : 0,
            'openHomeworks' => $schoolId ? DB::table('homeworks')->where('school_id', $schoolId)->where('status', 'published')->count() : 0,
            'monthAbsences' => $schoolId && $studentId ? DB::table('attendance_records')->where('school_id', $schoolId)->where('student_id', $studentId)->where('status', 'absent')->where('created_at', '>=', now()->startOfMonth())->count() : 0,
        ];

        $importantMessage = $schoolId
            ? DB::table('announcements')
                ->where('school_id', $schoolId)
                ->where('is_important', true)
                ->whereIn('audience', ['all', 'students'])
                ->latest('created_at')
                ->value('body')
            : null;

        $recentAnnouncements = $schoolId
            ? DB::table('announcements')
                ->where('school_id', $schoolId)
                ->whereIn('audience', ['all', 'students'])
                ->orderByDesc('created_at')
                ->limit(5)
                ->get(['title', 'body', 'is_important', 'created_at'])
                ->map(fn ($a): array => [
                    'title' => $a->title,
                    'body' => $a->body,
                    'isImportant' => (bool) $a->is_important,
                    'createdAt' => $this->jalaliDate($a->created_at),
                ])
                ->values()
            : collect()->values();

        $classroomIds = $schoolId && $studentId
            ? DB::table('class_students')
                ->where('school_id', $schoolId)
                ->where('student_id', $studentId)
                ->where('status', 'active')
                ->pluck('classroom_id')
            : collect();

        $upcomingOnlineClasses = ($schoolId && $classroomIds->isNotEmpty())
            ? DB::table('online_classes')
                ->leftJoin('subjects', 'subjects.id', '=', 'online_classes.subject_id')
                ->whereIn('online_classes.classroom_id', $classroomIds)
                ->where('online_classes.school_id', $schoolId)
                ->where(function ($q): void {
                    $q->whereNull('online_classes.ends_at')
                        ->orWhere('online_classes.ends_at', '>=', now());
                })
                ->orderBy('online_classes.starts_at')
                ->limit(5)
                ->get(['online_classes.id', 'online_classes.title', 'online_classes.meeting_url', 'online_classes.starts_at', 'subjects.name_fa as subject'])
                ->map(fn ($c): array => [
                    'id' => (int) $c->id,
                    'title' => $c->title,
                    'subject' => $c->subject ?? '—',
                    'meetingUrl' => $c->meeting_url,
                    'startsAt' => $c->starts_at ? $this->jalaliDate($c->starts_at, true) : '—',
                ])
                ->values()
            : collect()->values();

        $activeVotingCount = $schoolId
            ? DB::table('votings')
                ->where('school_id', $schoolId)
                ->where('status', 'published')
                ->count()
            : 0;

        $approvedGradeCount = ($schoolId && $studentId)
            ? DB::table('grades')
                ->where('school_id', $schoolId)
                ->where('student_id', $studentId)
                ->where('status', 'approved')
                ->count()
            : 0;

        return Inertia::render('Student/Home', [
            'metrics' => array_map('intval', $metrics),
            'importantMessage' => $importantMessage,
            'announcements' => $recentAnnouncements,
            'onlineClasses' => $upcomingOnlineClasses,
            'activeVotingCount' => (int) $activeVotingCount,
            'approvedGradeCount' => (int) $approvedGradeCount,
        ]);
    }

    private function todayClassesCount(int $schoolId, int $studentId): int
    {
        $classroomIds = DB::table('class_students')
            ->where('school_id', $schoolId)
            ->where('student_id', $studentId)
            ->where('status', 'active')
            ->pluck('classroom_id');

        if ($classroomIds->isEmpty()) {
            return 0;
        }

        $dayOfWeek = ((int) now()->dayOfWeek + 1) % 7;

        return DB::table('schedules')
            ->where('school_id', $schoolId)
            ->whereIn('classroom_id', $classroomIds)
            ->where('day_of_week', $dayOfWeek)
            ->count();
    }
}
