<?php

namespace App\Controllers;

use Wibiesana\Padi\Core\Controller;
use Wibiesana\Padi\Core\Auth;
use Wibiesana\Padi\Core\Query;

class DashboardController extends Controller
{
    /**
     * Get attendance dashboard statistics
     * GET /dashboard/attendance-stats
     * @param date optional date filter (YYYY-MM-DD format)
     */
    public function getAttendanceStats()
    {
        // Get date from query parameter, default to today
        $today = $_GET['date'] ?? date('Y-m-d');
        $classId = $_GET['class_id'] ?? null;
        $user = Auth::user();
        $userId = is_array($user) ? ($user['id'] ?? $user['user_id'] ?? null) : ($user->id ?? $user->user_id ?? null);
        $role = is_array($user) ? ($user['role'] ?? null) : ($user->role ?? null);

        // Role-based classroom filtering for teachers
        $filteredClassIds = null;
        if ($user && ($role === 'teacher' || (int)$role === 2)) {
            // Get classes where user is subject teacher
            $teachingClasses = Query::find()
                ->from('teaching_schedule')
                ->select(['DISTINCT classroom_id'])
                ->where(['teacher_id' => $userId])
                ->all();

            // Get classes where user is homeroom teacher
            $homeroomClasses = Query::find()
                ->from('classroom')
                ->select(['id'])
                ->where(['teacher_id' => $userId])
                ->all();

            $filteredClassIds = array_unique(array_merge(
                array_column($teachingClasses, 'classroom_id'),
                array_column($homeroomClasses, 'id')
            ));

            if (empty($filteredClassIds)) {
                $filteredClassIds = [0]; // Force no results if no classes assigned
            }
        }

        // Get student attendance stats
        $studentQuery = Query::find()
            ->from('attendance_daily_student')
            ->select([
                'attendance_daily_student.*',
                'student.name as student_name'
            ])
            ->leftJoin('student', 'attendance_daily_student.student_id = student.id')
            ->where(['attendance_daily_student.attendance_date' => $today]);

        if ($classId) {
            $studentQuery->leftJoin('classroom_member', 'student.id = classroom_member.student_id')
                ->andWhere(['classroom_member.class_id' => $classId]);
        } elseif ($filteredClassIds) {
            $studentQuery->leftJoin('classroom_member', 'student.id = classroom_member.student_id')
                ->andWhere(['classroom_member.class_id' => $filteredClassIds]);
        }

        $allStudentRecords = $studentQuery->all();
        $studentRecords = $allStudentRecords;
        
        // Get teacher attendance stats
        $teacherQuery = Query::find()
            ->from('attendance_daily_teacher')
            ->select([
                'attendance_daily_teacher.*',
                'teacher.name as teacher_name'
            ])
            ->leftJoin('teacher', 'attendance_daily_teacher.teacher_id = teacher.id')
            ->where(['attendance_daily_teacher.attendance_date' => $today])
            ->orderBy('attendance_daily_teacher.created_at DESC');

        // Note: For teachers, we might still show all teacher attendance or just their own?
        // Usually, dashboard shows overview. We keep it as is unless it's too much.
        // If it's a teacher dashboard specifically, maybe only their own?
        if ($filteredClassIds && $user) {
            // For teacher role, maybe they only want to see their own daily attendance status on the summary?
            // Or at least show their own prominently. Let's keep it restricted to their own for now to be "specific for teacher".
            $teacherQuery->andWhere(['attendance_daily_teacher.teacher_id' => $userId]);
        }

        $allTeacherRecords = $teacherQuery->all();
        $teacherRecords = $allTeacherRecords;

        // Get lesson sessions for today
        $sessionQuery = Query::find()
            ->from('lesson_session')
            ->where(['session_date' => $today]);

        if ($classId) {
            $sessionQuery->leftJoin('teaching_schedule', 'lesson_session.teaching_schedule_id = teaching_schedule.id')
                ->andWhere(['teaching_schedule.classroom_id' => $classId]);
        } elseif ($filteredClassIds) {
            $sessionQuery->leftJoin('teaching_schedule', 'lesson_session.teaching_schedule_id = teaching_schedule.id')
                ->andWhere(['teaching_schedule.classroom_id' => $filteredClassIds]);
        }

        $allSessionRecords = $sessionQuery->orderBy('lesson_session.created_at DESC')->all();
        $sessionRecords = $allSessionRecords;

        // Get Today's Schedule Checklist
        $dayOfWeek = date('N', strtotime($today)); // 1 (Mon) - 7 (Sun)
        $scheduleQuery = Query::find()
            ->from('teaching_schedule')
            ->select([
                'teaching_schedule.id',
                'teaching_schedule.classroom_id',
                'teaching_schedule.subject_id',
                'teaching_schedule.start_time',
                'teaching_schedule.end_time',
                'classroom.name as class_name',
                'classroom.teacher_id as homeroom_teacher_id',
                'subject.name as subject_name'
            ])
            ->leftJoin('classroom', 'teaching_schedule.classroom_id = classroom.id')
            ->leftJoin('subject', 'teaching_schedule.subject_id = subject.id')
            ->where(['teaching_schedule.day_of_week' => $dayOfWeek]);

        if ($classId) {
            $scheduleQuery->andWhere(['teaching_schedule.classroom_id' => $classId]);
        } elseif ($filteredClassIds) {
            $scheduleQuery->andWhere(['teaching_schedule.classroom_id' => $filteredClassIds]);
            $scheduleQuery->andWhere(['teaching_schedule.teacher_id' => $userId]);
        }
        
        $todaySchedules = $scheduleQuery->all();

        // Enhance schedules with completion status
        foreach ($todaySchedules as &$sch) {
            // 1. Check Daily Attendance Completion
            // A class is considered "Completed" for daily attendance if there is AT LEAST ONE record today
            $dailyCount = Query::find()
                ->from('attendance_daily_student')
                ->leftJoin('classroom_member', 'attendance_daily_student.student_id = classroom_member.student_id')
                ->where([
                    'attendance_daily_student.attendance_date' => $today,
                    'classroom_member.class_id' => $sch['classroom_id']
                ])
                ->count();
            
            $sch['daily_attendance_completed'] = $dailyCount > 0;

            // 2. Check Lesson Session Completion
            $sessionRecord = Query::find()
                ->from('lesson_session')
                ->where([
                    'teaching_schedule_id' => $sch['id'],
                    'session_date' => $today
                ])
                ->one();
            
            $sch['session_status'] = $sessionRecord ? $sessionRecord['status'] : 'Pending';
            $sch['session_id'] = $sessionRecord ? $sessionRecord['id'] : null;

            // 3. Check if any student attendance is recorded for this session
            $sch['attendance_count'] = 0;
            if ($sch['session_id']) {
                $sch['attendance_count'] = Query::find()
                    ->from('attendance_student')
                    ->where(['lesson_session_id' => $sch['session_id']])
                    ->count();
            }
        }

        // Detect attendance anomalies
        $anomalies = [];

        // Build where clause for class filtering - Get present students (Status 1)
        // Adjust status check to be more robust (1 or '1')
        $dailyWhereClause = [
            'attendance_daily_student.attendance_date' => $today,
            'attendance_daily_student.status' => 1
        ];

        // Add class filter if provided
        if ($classId) {
            $dailyWhereClause['classroom.id'] = $classId;
        } elseif ($filteredClassIds) {
            $dailyWhereClause['classroom.id'] = $filteredClassIds;
        }

        // Get all students present in daily attendance today
        $presentDailyQuery = Query::find()
            ->from('attendance_daily_student')
            ->select([
                'attendance_daily_student.student_id',
                'student.name as student_name',
                'student.nis as student_nis',
                'classroom.name as class_name',
                'classroom.id as class_id'
            ])
            ->leftJoin('student', 'attendance_daily_student.student_id = student.id')
            ->leftJoin('classroom_member', 'student.id = classroom_member.student_id')
            ->leftJoin('classroom', 'classroom_member.class_id = classroom.id')
            ->where($dailyWhereClause);

        $presentDailyStudents = $presentDailyQuery->all();

        // Anomaly Type 1: Present in Daily but NOT Present in Lessons
        foreach ($presentDailyStudents as $student) {
            // Check for any lessons where student is NOT marked as 'Present' (1)
            // or where no record exists yet for today's sessions
            $notPresentInLesson = Query::find()
                ->from('attendance_student')
                ->leftJoin('lesson_session', 'attendance_student.lesson_session_id = lesson_session.id')
                ->where([
                    'attendance_student.student_id' => $student['student_id'],
                    'lesson_session.session_date' => $today
                ])
                ->andWhere(['attendance_student.status', '!=', 1])
                ->count();

            $totalLessonRecords = Query::find()
                ->from('attendance_student')
                ->leftJoin('lesson_session', 'attendance_student.lesson_session_id = lesson_session.id')
                ->where([
                    'attendance_student.student_id' => $student['student_id'],
                    'lesson_session.session_date' => $today
                ])
                ->count();

            // If: (Present in Daily but NOT Present in at least one Lesson Record) 
            // OR (Present in Daily but NO Lesson Records at all yet)
            if ($notPresentInLesson > 0 || $totalLessonRecords == 0) {
                // Get teacher name from any lesson scheduled for this class today to give context
                $teacherInfo = Query::find()
                    ->from('lesson_session')
                    ->select(['teacher.name as teacher_name'])
                    ->leftJoin('teacher', 'lesson_session.teacher_id = teacher.id')
                    ->leftJoin('teaching_schedule', 'lesson_session.teaching_schedule_id = teaching_schedule.id')
                    ->where([
                        'lesson_session.session_date' => $today,
                        'teaching_schedule.classroom_id' => $student['class_id']
                    ])
                    ->limit(1)
                    ->one();

                $anomalies[] = [
                    'type' => 'present_daily_no_lesson',
                    'student_id' => $student['student_id'],
                    'student_name' => $student['student_name'],
                    'student_nis' => $student['student_nis'],
                    'class_name' => $student['class_name'] ?? '-',
                    'teacher_name' => isset($teacherInfo['teacher_name']) ? $teacherInfo['teacher_name'] : '-',
                    'lesson_absent_count' => $notPresentInLesson > 0 ? $notPresentInLesson : 1, // Default to 1 if no records yet
                    'severity' => 'warning',
                    'date' => $today
                ];
            }
        }

        // Anomaly Type 2: Present in Lesson but Absent/Not Present in Daily
        $lessonAttQuery = Query::find()
            ->from('attendance_student')
            ->select([
                'attendance_student.student_id',
                'MAX(student.name) as student_name',
                'MAX(student.nis) as student_nis',
                'MAX(classroom.name) as class_name',
                'MAX(classroom.id) as class_id',
                'MAX(teacher.name) as teacher_name',
                'MAX(ads.status) as daily_status',
                'COUNT(attendance_student.id) as lesson_present_count'
            ])
            ->leftJoin('lesson_session', 'attendance_student.lesson_session_id = lesson_session.id')
            ->leftJoin('teacher', 'lesson_session.teacher_id = teacher.id')
            ->leftJoin('student', 'attendance_student.student_id = student.id')
            ->leftJoin('classroom_member', 'student.id = classroom_member.student_id')
            ->leftJoin('classroom', 'classroom_member.class_id = classroom.id')
            // Crucial: Left join with Daily Attendance table to check presence status
            ->leftJoin('attendance_daily_student ads', 'attendance_student.student_id = ads.student_id AND ads.attendance_date = lesson_session.session_date')
            ->where([
                'lesson_session.session_date' => $today,
                'attendance_student.status' => 1 // Only consider students marked 'Present' in lesson
            ]);

        // Apply class filters
        if ($classId) {
            $lessonAttQuery->andWhere(['classroom.id' => $classId]);
        } elseif ($filteredClassIds) {
            $lessonAttQuery->andWhere(['classroom.id' => $filteredClassIds]);
        }

        $lessonAttToday = $lessonAttQuery->groupBy('attendance_student.student_id')->all();

        foreach ($lessonAttToday as $student) {
            // Anomaly if: No daily record exists OR status is NOT Present (1)
            $isDailyPresent = !is_null($student['daily_status']) && (int)$student['daily_status'] === 1;
            
            if (!$isDailyPresent) {
                $anomalies[] = [
                    'type' => 'present_lesson_absent_daily',
                    'student_id' => $student['student_id'],
                    'student_name' => $student['student_name'],
                    'student_nis' => $student['student_nis'],
                    'class_name' => $student['class_name'] ?? '-',
                    'teacher_name' => $student['teacher_name'] ?? '-',
                    'lesson_present_count' => $student['lesson_present_count'],
                    'severity' => 'error',
                    'date' => $today
                ];
            }
        }


        return $this->json([
            'today_schedules' => $todaySchedules,
            'students' => [
                'data' => $studentRecords,
                'stats' => [
                    'total' => count($allStudentRecords),
                    'present' => count(array_filter($allStudentRecords, fn($r) => $r['status'] == 1)),
                    'permission' => count(array_filter($allStudentRecords, fn($r) => $r['status'] == 2)),
                    'sick' => count(array_filter($allStudentRecords, fn($r) => $r['status'] == 3)),
                    'absent' => count(array_filter($allStudentRecords, fn($r) => $r['status'] == 4)),
                ]
            ],
            'anomalies' => $anomalies,
            'teachers' => [
                'data' => $teacherRecords,
                'stats' => [
                    'total' => count($allTeacherRecords),
                    'present' => count(array_filter($allTeacherRecords, fn($r) => $r['status'] == 1)),
                    'absent' => count(array_filter($allTeacherRecords, fn($r) => $r['status'] != 1)),
                ]
            ],
            'sessions' => [
                'data' => $sessionRecords,
                'stats' => [
                    'total' => count($allSessionRecords),
                    'completed' => count(array_filter($allSessionRecords, fn($r) => in_array($r['status'], ['Present', 'Completed']))),
                    'pending' => count(array_filter($allSessionRecords, fn($r) => !in_array($r['status'], ['Present', 'Completed']))),
                ]
            ]
        ]);
    }
}
