<?php

namespace App\Controllers;

use App\Controllers\Base\LessonSessionController as BaseController;

use App\Resources\LessonSessionResource;
use Wibiesana\Padi\Core\Auth;

class LessonSessionController extends BaseController
{
    /**
     * Get all lessonsessions with pagination and optional filter
     * GET /lessonsessions
     */
    public function index()
    {
        $user = Auth::user();
        // Auto-generated eager loading
        $this->model->with(['teachingSchedule.classroom', 'teachingSchedule.subject', 'teacher:id,name']);

        $page = max(1, (int)$this->request->query('page', 1));
        $perPage = min(100, max(1, (int)$this->request->query('per-page', 10)));
        $search = $this->request->query('search', '');

        $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);

        $filters = [];
        if ($this->request->query('session_date')) {
            $filters['session_date'] = $this->request->query('session_date');
        }
        if ($user && ($role === 'teacher' || (int)$role === 2)) {
            $filters['teacher_id'] = $userId;
        } elseif ($this->request->query('teacher_id')) {
            $filters['teacher_id'] = (int)$this->request->query('teacher_id');
        }
        if ($this->request->query('status')) {
            $filters['status'] = $this->request->query('status');
        }

        $result = $this->model->searchPaginate($search, $page, $perPage, null, $filters);

        return LessonSessionResource::collection($result);
    }

    /**
     * Get single lessonsession
     * GET /lessonsessions/{id}
     */
    public function show()
    {
        $id = $this->request->param('id');
        // Auto-generated eager loading
        $this->model->with(['teachingSchedule.classroom', 'teachingSchedule.subject', 'teacher:id,name']);

        $lessonsession = $this->model->find($id);

        if (!$lessonsession) {
            throw new \Exception('LessonSession not found', 404);
        }

        $lessonsession = $this->loadItemRelations($lessonsession);
        return LessonSessionResource::make($lessonsession);
    }

    protected function loadItemRelations($lessonsession)
    {
        if (empty($lessonsession)) return $lessonsession;

        // Manually load nested relations for the teachingSchedule
        if (!empty($lessonsession['teaching_schedule_id'])) {
            $tsModel = new \App\Models\TeachingSchedule();
            $ts = $tsModel->find($lessonsession['teaching_schedule_id']);
            if ($ts) {
                $tsSet = [$ts];
                $tsModel->with(['subject', 'classroom'])->loadRelations($tsSet);
                $lessonsession['teachingSchedule'] = $tsSet[0];
            }
        }
        return $lessonsession;
    }

    /**
     * Create or update lessonsession (Upsert)
     * POST /lessonsessions
     */
    public function store()
    {
        $validated = $this->validate([
            'teaching_schedule_id' => 'required|integer',
            'session_date' => 'required',
            'teacher_id' => 'required|integer',
            'material' => 'string',
            'note' => 'string|max:255',
            'status' => 'string|max:20',
            'allow_self_attendance' => 'integer',
        ]);

        if (!empty($validated['allow_self_attendance']) && (empty($existing) || empty($existing['qr_token']))) {
            $validated['qr_token'] = $this->generateQrToken();
        }

        // Check if exists for upsert
        $existing = $this->model->where([
            'teaching_schedule_id' => $validated['teaching_schedule_id'],
            'session_date' => $validated['session_date']
        ]);
        $existing = !empty($existing) ? $existing[0] : null;

        try {
            if ($existing) {
                $id = $existing['id'];
                $this->model->update($id, $validated);
            } else {
                $id = $this->model->create($validated);
            }

            // Auto-generated eager loading
            $this->model->with(['teachingSchedule.classroom', 'teachingSchedule.subject', 'teacher:id,name']);
            $lessonsession = $this->model->find($id);
            $lessonsession = $this->loadItemRelations($lessonsession);

            return $existing
                ? LessonSessionResource::make($lessonsession)
                : $this->created(LessonSessionResource::make($lessonsession));
        } catch (\PDOException $e) {
            $this->databaseError('Failed to save lessonsession', $e);
        }
    }

    /**
     * Update lessonsession
     * PUT /lessonsessions/{id}
     */
    public function update()
    {
        $id = $this->request->param('id');
        $lessonsession = $this->model->find($id);

        if (!$lessonsession) {
            throw new \Exception('LessonSession not found', 404);
        }

        $validated = $this->validate([
            'teaching_schedule_id' => 'required|integer',
            'session_date' => 'required',
            'teacher_id' => 'required|integer',
            'material' => 'string',
            'note' => 'string|max:255',
            'status' => 'string|max:20',
            'allow_self_attendance' => 'integer',
        ]);

        if (!empty($validated['allow_self_attendance']) && empty($lessonsession['qr_token'])) {
            $validated['qr_token'] = $this->generateQrToken();
        }

        try {
            $this->model->update($id, $validated);

            // Auto-generated eager loading
            $this->model->with(['teachingSchedule.classroom', 'teachingSchedule.subject', 'teacher:id,name']);
            $lessonsession = $this->model->find($id);
            $lessonsession = $this->loadItemRelations($lessonsession);
            return LessonSessionResource::make($lessonsession);
        } catch (\PDOException $e) {
            $this->databaseError('Failed to update lessonsession', $e);
        }
    }

    public function teachingSchedule()
    {
        $user = Auth::user();
        $userId = is_array($user) ? ($user['id'] ?? $user['user_id'] ?? null) : ($user->id ?? $user->user_id ?? null);

        $page = max(1, (int)$this->request->query('page', 1));
        $perPage = min(100, max(1, (int)$this->request->query('per-page', 10)));
        $search = $this->request->query('search', '');

        // Support both 'session_date' and 'date' for better frontend compatibility
        $date = $_GET['session_date'] ?? $_GET['date'] ?? $this->request->param('session_date') ?? $this->request->param('date');
        $reqTeacherId = $_GET['teacher_id'] ?? $this->request->param('teacher_id');
        $status = $_GET['status'] ?? $this->request->query('status');

        if (empty($date) || $date === 'undefined') {
            return $this->response->json([
                'success' => false,
                'message' => 'Session date is required for schedule lookup.',
                'item' => ['data' => []]
            ], 400);
        }

        // Determine final teacher_id based on profile and role
        $teacher = \App\Models\Teacher::findQuery()->where(['id', '=', $userId])->andWhere(['status', '=', 1])->one();
        $finalTeacherId = null;

        if ($teacher) {
            $finalTeacherId = $teacher['id'];
        } else if ($reqTeacherId) {
            $finalTeacherId = (int)$reqTeacherId;
        }

        $result = $this->model->getScheduleForDate(
            $date,
            $finalTeacherId,
            $page,
            $perPage,
            $search,
            ['status' => $status]
        );

        return $this->response->json([
            'success' => true,
            'message' => 'Success',
            'item' => $result
        ]);
    }

    /**
     * Student self-attendance via QR token
     * POST /lesson-session/self-attendance
     */
    public function selfAttendance()
    {
        $user = Auth::user();
        $userId = is_array($user) ? ($user['id'] ?? $user['user_id'] ?? null) : ($user->id ?? $user->user_id ?? null);

        $validated = $this->validate([
            'qr_token' => 'required|string',
        ]);

        // 1. Find lesson session by QR token
        $sessions = $this->model->where(['qr_token' => $validated['qr_token']]);
        $session = !empty($sessions) ? $sessions[0] : null;

        if (!$session) {
            return $this->response->json([
                'success' => false,
                'message' => 'QR Code tidak valid atau sesi tidak ditemukan',
            ], 404);
        }

        // 2. Check if self-attendance is enabled
        if (empty($session['allow_self_attendance'])) {
            return $this->response->json([
                'success' => false,
                'message' => 'Absen mandiri tidak diaktifkan untuk sesi ini',
            ], 403);
        }

        // 3. Check if session date is today
        $today = date('Y-m-d');
        if ($session['session_date'] !== $today) {
            return $this->response->json([
                'success' => false,
                'message' => 'QR Code ini hanya berlaku untuk tanggal ' . $session['session_date'],
            ], 403);
        }

        // 4. Check if student is in the class
        $tsModel = new \App\Models\TeachingSchedule();
        $ts = $tsModel->find($session['teaching_schedule_id']);
        if (!$ts) {
            return $this->response->json([
                'success' => false,
                'message' => 'Jadwal tidak ditemukan',
            ], 404);
        }

        $classId = $ts['classroom_id'] ?? null;
        $studentClasses = \App\Models\ClassroomMember::findQuery()
            ->where(['student_id', '=', $userId])
            ->andWhere(['class_id', '=', $classId])
            ->all();

        if (empty($studentClasses)) {
            return $this->response->json([
                'success' => false,
                'message' => 'Anda tidak terdaftar di kelas ini',
            ], 403);
        }

        // 5. Check if already attended
        $existing = \App\Models\AttendanceStudent::findQuery()
            ->where(['lesson_session_id', '=', $session['id']])
            ->andWhere(['student_id', '=', $userId])
            ->one();

        if ($existing) {
            return $this->response->json([
                'success' => true,
                'message' => 'Anda sudah tercatat hadir',
                'item' => $existing,
            ]);
        }

        // 6. Create attendance record (status 4 = Hadir)
        try {
            $attendanceModel = new \App\Models\AttendanceStudent();
            $id = $attendanceModel->create([
                'lesson_session_id' => $session['id'],
                'student_id' => $userId,
                'status' => 1,
                'note' => 'Self-attendance via QR',
            ]);

            $saved = $attendanceModel->find($id);

            // Load session info for response
            $this->model->with(['teachingSchedule.classroom', 'teachingSchedule.subject', 'teacher:id,name']);
            $sessionDetail = $this->model->find($session['id']);
            $sessionDetail = $this->loadItemRelations($sessionDetail);

            return $this->response->json([
                'success' => true,
                'message' => 'Absen berhasil dicatat',
                'item' => $saved,
                'session' => LessonSessionResource::make($sessionDetail),
            ]);
        } catch (\PDOException $e) {
            $this->databaseError('Gagal menyimpan absen', $e);
        }
    }

    /**
     * Get lesson session info by QR token (for preview before submitting)
     * GET /lesson-session/qr-info?token=xxx
     */
    public function qrInfo()
    {
        $token = $this->request->query('token');
        if (empty($token)) {
            return $this->response->json([
                'success' => false,
                'message' => 'Token is required',
            ], 400);
        }

        $sessions = $this->model->where(['qr_token' => $token]);
        $session = !empty($sessions) ? $sessions[0] : null;

        if (!$session || empty($session['allow_self_attendance'])) {
            return $this->response->json([
                'success' => false,
                'message' => 'QR Code tidak valid',
            ], 404);
        }

        $this->model->with(['teachingSchedule.classroom', 'teachingSchedule.subject', 'teacher:id,name']);
        $sessionDetail = $this->model->find($session['id']);
        $sessionDetail = $this->loadItemRelations($sessionDetail);

        return $this->response->json([
            'success' => true,
            'item' => LessonSessionResource::make($sessionDetail),
        ]);
    }

    protected function generateQrToken(): string
    {
        return bin2hex(random_bytes(16)) . '_' . time();
    }
}
