<?php
declare(strict_types=1);
require_once __DIR__ . '/../includes/config.php';require_once __DIR__ . '/../includes/db.php';require_once __DIR__ . '/../includes/functions.php';require_once __DIR__ . '/../includes/student-auth.php';require_once __DIR__ . '/../includes/student-course-context.php';require_once __DIR__ . '/../includes/grade-engine.php';
$pdo=db();requireStudent();$student=currentStudent($pdo);if(!$student){studentLogout();redirect('login.php');}$error=flash('error')?:'';$success=flash('success')?:'';
$courseId=(int)($_GET['course_id']??$_POST['course_id']??0);$token=trim((string)($_GET['token']??$_POST['token']??''));$code=strtoupper(trim((string)($_POST['attendance_code']??'')));
function findAttendanceSession(PDO $pdo,string $code,string $token): ?array {
 $where=$token!==''?'a.qr_token=?':'UPPER(COALESCE(NULLIF(a.current_code,\'\'),a.attendance_code))=?';$value=$token!==''?$token:$code;
 if($value==='')return null;
 return safeFetch($pdo,"SELECT a.*,s.id AS session_id,s.course_id,s.teacher_id,s.title AS session_title,s.session_date,s.session_time,s.status AS session_status,c.title AS course_title,c.course_code FROM core_attendance_sessions a INNER JOIN core_sessions s ON s.id=COALESCE(NULLIF(a.core_session_id,0),NULLIF(a.session_id,0)) INNER JOIN core_courses c ON c.id=s.course_id WHERE {$where} AND a.is_active=1 ORDER BY a.id DESC LIMIT 1",[$value]);
}
$preview=($token!==''||$code!=='')?findAttendanceSession($pdo,$code,$token):null;
if(isPost()){requireCsrf();if(!$preview)$error='The attendance code or QR token is invalid.';elseif(!isStudentActiveInCourse($pdo,(int)$student['id'],(int)$preview['course_id']))$error='You are not enrolled in this course.';elseif(!in_array((string)$preview['session_status'],['scheduled','active','completed'],true))$error='This session is not available for attendance.';else{$now=time();$expires=strtotime((string)$preview['expires_at']);$starts=!empty($preview['starts_at'])?strtotime((string)$preview['starts_at']):strtotime((string)$preview['session_date'].' '.(string)$preview['session_time']);if($expires&&$expires<$now){safeExecute($pdo,'UPDATE core_attendance_sessions SET is_active=0 WHERE id=?',[(int)$preview['id']]);$error='This attendance code has expired.';}elseif($starts&&$now<$starts-900)$error='Attendance has not opened yet.';else{$minutesAfter=max(0,(int)floor(($now-($starts?:$now))/60));$status=attendanceStatusByArrival($minutesAfter);$points=$status==='present'?.5:.25;try{$stmt=$pdo->prepare("INSERT INTO core_attendance (session_id,student_id,course_id,core_session_id,attendance_session_id,status,points_awarded,submitted_at,attendance_minutes,minutes_attended,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,0,0,NOW(),NOW()) ON DUPLICATE KEY UPDATE status=VALUES(status),points_awarded=VALUES(points_awarded),submitted_at=VALUES(submitted_at),updated_at=NOW()");$stmt->execute([(int)$preview['session_id'],(int)$student['id'],(int)$preview['course_id'],(int)$preview['session_id'],(int)$preview['id'],$status,$points,now()]);saveStudentGrade($pdo,(int)$student['id'],(int)$preview['course_id'],'attendance',(int)$preview['session_id'],'Attendance — '.(string)$preview['session_title'],$points,.5,0,'Arrival status: '.$status,null,null);logActivity($pdo,'student',(int)$student['id'],'Attendance submitted','Session '.(int)$preview['session_id'].'; status '.$status,null,(int)$preview['course_id']);flash('success','Attendance recorded as '.ucfirst($status).'. The teacher may update the final status according to your attendance duration.');redirect('student/submit-attendance.php?course_id='.(int)$preview['course_id']);}catch(Throwable $e){error_log('[SMI student attendance] '.$e->getMessage());$error=APP_DEBUG?$e->getMessage():'Attendance could not be recorded.';}}}}
$recent=$courseId>0&&isStudentActiveInCourse($pdo,(int)$student['id'],$courseId)?safeFetchAll($pdo,"SELECT a.*,s.title,s.session_date,s.session_time FROM core_attendance a INNER JOIN core_sessions s ON s.id=COALESCE(NULLIF(a.core_session_id,0),NULLIF(a.session_id,0)) WHERE a.student_id=? AND s.course_id=? ORDER BY COALESCE(a.submitted_at,a.created_at) DESC LIMIT 20",[(int)$student['id'],$courseId]):[];
?>
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Attendance · SMI</title><style>:root{font-family:Inter,Arial,sans-serif;background:#f3f6fb;color:#0f172a}*{box-sizing:border-box}body{margin:0}.page{max-width:1000px;margin:auto;padding:30px}.top{display:flex;justify-content:space-between;align-items:center}.top h1{font-size:44px;margin:0}.btn{border:0;border-radius:14px;padding:12px 16px;background:#2563eb;color:white;text-decoration:none;font-weight:850;cursor:pointer}.layout{display:grid;grid-template-columns:390px 1fr;gap:20px;margin-top:24px}.card{background:white;border-radius:26px;padding:24px;box-shadow:0 16px 44px rgba(15,23,42,.08)}label{display:block;font-weight:850;font-size:13px}input{width:100%;padding:14px;border:1px solid #dbe3ef;border-radius:13px;margin:8px 0 14px;font:inherit;text-transform:uppercase}.preview{background:#eff6ff;border-radius:18px;padding:16px;margin-bottom:14px}.meta{color:#64748b;font-size:13px;line-height:1.8}.alert{padding:14px 18px;border-radius:14px;margin-top:16px;font-weight:800}.ok{background:#dcfce7;color:#166534}.bad{background:#fee2e2;color:#991b1b}.row{display:flex;justify-content:space-between;gap:10px;border-top:1px solid #e2e8f0;padding:13px 0}.pill{padding:5px 9px;border-radius:999px;background:#eff6ff;color:#1d4ed8;font-size:12px;font-weight:850}@media(max-width:800px){.layout{grid-template-columns:1fr}.page{padding:18px}.top h1{font-size:34px}}</style></head><body><main class="page"><div class="top"><div><h1>Attendance</h1><p>Submit the live code or confirm the QR session.</p></div><a class="btn" href="dashboard.php<?= $courseId?'?course_id='.$courseId:'' ?>">Dashboard</a></div><?php if($success):?><div class="alert ok"><?=e($success)?></div><?php endif;?><?php if($error):?><div class="alert bad"><?=e($error)?></div><?php endif;?><div class="layout"><section class="card"><h2>Record attendance</h2><?php if($preview):?><div class="preview"><strong><?=e($preview['session_title'])?></strong><div class="meta"><?=e($preview['course_title'])?><br><?=e(formatDateNice($preview['session_date']))?> · <?=e(formatTimeNice($preview['session_time']))?><br>Expires: <?=e(formatDateTimeNice($preview['expires_at']))?></div></div><?php endif;?><form method="post"><?=csrfField()?><input type="hidden" name="course_id" value="<?=e($courseId?:($preview['course_id']??0))?>"><input type="hidden" name="token" value="<?=e($token)?>"><label>Attendance code</label><input name="attendance_code" value="<?=e($code?:($preview['current_code']??''))?>" placeholder="ATT-00000" <?= $token===''?'required':'' ?>><button class="btn" style="width:100%"><?= $preview?'Confirm attendance':'Submit code' ?></button></form><p class="meta">Arrival within the first <?=ATTENDANCE_PRESENT_WINDOW_MINUTES?> minutes is initially marked present. The final result is recalculated from your actual duration.</p></section><section class="card"><h2>Recent records</h2><?php foreach($recent as $r):?><div class="row"><div><strong><?=e($r['title'])?></strong><div class="meta"><?=e(formatDateNice($r['session_date']))?> · <?=e((int)($r['attendance_minutes']?:$r['minutes_attended']))?> minutes</div></div><span class="pill"><?=e($r['status'])?></span></div><?php endforeach;?><?php if(!$recent):?><p class="meta">Choose a course from your dashboard to see its attendance history.</p><?php endif;?></section></div></main></body></html>
