<?php

namespace App\Modules\Dashboard\Controllers;

use App\Core\BaseApiController;
use App\Modules\Academic\Models\ClassModel;
use App\Modules\Academic\Models\ScheduleModel;
use App\Modules\Academic\Models\SubjectModel;
use App\Modules\Auth\Entities\Role;
use App\Modules\Auth\Services\AuthService;
use App\Modules\Attendance\Models\QrAttendanceTokenModel;
use CodeIgniter\HTTP\ResponseInterface;

/**
 * Generate QR token untuk absen mapel (guru tampilkan QR, siswa scan).
 * POST /api/dashboard/qr-attendance/generate
 * Body: { schedule_id: number }
 */
class QrAttendanceController extends BaseApiController
{
    protected AuthService $authService;

    public function __construct()
    {
        $this->authService = new AuthService();
    }

    /**
     * Generate token untuk schedule_id. Hanya guru mapel jadwal tersebut / admin / wali kelas.
     */
    public function generate(): ResponseInterface
    {
        $user = $this->authService->currentUser();
        if (!$user) {
            return $this->errorResponse('Unauthorized', null, null, 401);
        }

        $payload = $this->request->getJSON(true) ?? [];
        $scheduleId = (int) ($payload['schedule_id'] ?? 0);
        if ($scheduleId < 1) {
            return $this->errorResponse('schedule_id wajib diisi', null, null, 400);
        }

        $scheduleModel = new ScheduleModel();
        $schedule = $scheduleModel->getScheduleWithSlot($scheduleId);
        if (!$schedule) {
            return $this->errorResponse('Jadwal tidak ditemukan', null, null, 404);
        }

        if (!$this->canAccessSchedule($schedule, $user)) {
            return $this->errorResponse('Anda tidak punya akses untuk jadwal ini', null, null, 403);
        }

        $qrModel = new QrAttendanceTokenModel();
        $token = $qrModel->generateForSchedule($scheduleId, (int) $user['id']);
        if (!$token) {
            return $this->errorResponse('Gagal generate token', null, null, 500);
        }

        $subjectName = '-';
        $className   = '-';
        if (!empty($schedule['subject_id'])) {
            $subject = (new SubjectModel())->find($schedule['subject_id']);
            $subjectName = $subject ? (string) $subject->name : '-';
        }
        if (!empty($schedule['class_id'])) {
            $class = (new ClassModel())->find($schedule['class_id']);
            $className = $class ? (trim($class->grade . ' ' . $class->major . ' ' . $class->name) ?: ('Kelas #' . $class->id)) : '-';
        }

        $expiresAt = date('Y-m-d H:i:s', strtotime('+' . QrAttendanceTokenModel::VALID_MINUTES . ' minutes'));

        $data = [
            'token'        => $token,
            'expires_at'   => $expiresAt,
            'schedule_id'  => $scheduleId,
            'subject_name' => $subjectName,
            'class_name'   => $className,
            'valid_minutes' => QrAttendanceTokenModel::VALID_MINUTES,
        ];

        return $this->successResponse($data, 'QR token berhasil dibuat. Tampilkan QR untuk siswa scan.');
    }

    protected function canAccessSchedule(array $schedule, array $user): bool
    {
        $roleCodes = array_column($user['roles'] ?? [], 'role_code');
        if (in_array(Role::CODE_ADMIN, $roleCodes, true) || in_array(Role::CODE_GURU_BK, $roleCodes, true)) {
            return true;
        }
        $classId = (int) ($schedule['class_id'] ?? 0);
        if (in_array(Role::CODE_WALI_KELAS, $roleCodes, true)) {
            $row = \Config\Database::connect()
                ->table('classes')
                ->select('id')
                ->where('id', $classId)
                ->where('wali_user_id', $user['id'])
                ->get()
                ->getRow();
            return $row !== null;
        }
        if (in_array(Role::CODE_GURU_MAPEL, $roleCodes, true)) {
            $teacherUserId = (int) ($schedule['teacher_user_id'] ?? 0);
            return $teacherUserId === (int) $user['id'];
        }
        return false;
    }
}
