<?php

namespace App\Modules\Mobile\Controllers;

use App\Core\BaseApiController;
use App\Modules\Academic\Models\StudentModel;
use App\Modules\Attendance\Services\AttendanceCheckinService;
use App\Modules\Mobile\Models\StudentMobileAccountModel;
use CodeIgniter\HTTP\ResponseInterface;

/**
 * Check-in via QR (guru generate QR di dashboard, siswa scan di app).
 * POST /api/mobile/checkin-qr
 * Body: { nisn, pin, qr_token [, lat, lng ] }
 *
 * Absen masuk/pulang: POST /api/mobile/checkin-masuk-pulang
 * Body: { nisn, pin, type: 'masuk'|'pulang', lat, lng }
 */
class CheckinController extends BaseApiController
{
    /**
     * Absen mapel via scan QR yang ditampilkan guru.
     */
    public function checkinQr(): ResponseInterface
    {
        $payload = $this->request->getJSON(true) ?? [];
        $nisn    = trim((string) ($payload['nisn'] ?? ''));
        $pin     = (string) ($payload['pin'] ?? '');
        $qrToken = trim((string) ($payload['qr_token'] ?? ''));

        if ($nisn === '' || $pin === '' || $qrToken === '') {
            return $this->errorResponse('NISN, PIN, dan qr_token wajib diisi', null, null, ResponseInterface::HTTP_UNPROCESSABLE_ENTITY);
        }

        $studentModel = new StudentModel();
        $student     = $studentModel->findByNisn($nisn);
        if (!$student) {
            return $this->errorResponse('Siswa tidak ditemukan', null, null, ResponseInterface::HTTP_NOT_FOUND);
        }

        $accountModel = new StudentMobileAccountModel();
        $accountRow   = $accountModel->where('student_id', (int) $student->id)->first();
        if (!$accountRow || empty($accountRow['pin_hash']) || !password_verify($pin, $accountRow['pin_hash'])) {
            return $this->errorResponse('PIN salah', null, null, ResponseInterface::HTTP_UNAUTHORIZED);
        }

        $studentId = (int) $student->id;
        $checkinPayload = [
            'student_id' => $studentId,
            'qr_token'   => $qrToken,
            'lat'        => $payload['lat'] ?? 0,
            'lng'        => $payload['lng'] ?? 0,
        ];

        $checkinService = new AttendanceCheckinService();
        $result = $checkinService->checkinByQr($checkinPayload);

        $messages = [
            'PRESENT'               => 'Absensi berhasil (Hadir)',
            'LATE'                  => 'Absensi berhasil (Terlambat)',
            'INVALID_QR_TOKEN'      => 'QR tidak valid atau sudah kadaluarsa',
            'STUDENT_NOT_IN_CLASS'  => 'Siswa tidak termasuk kelas untuk mapel ini',
            'ALREADY_CHECKED_IN'    => 'Sudah absen untuk mapel ini hari ini',
            'NO_SCHEDULE'           => 'Jadwal tidak ditemukan',
            'INVALID_DEVICE'        => 'Kesalahan sistem',
        ];
        $message = $messages[$result['status']] ?? $result['status'];

        return $this->successResponse($result, $message);
    }

    /**
     * POST /api/mobile/checkin-masuk-pulang
     * Body: { nisn, pin, type: 'masuk'|'pulang', lat, lng }
     * Absen masuk atau pulang pakai jam dari Pengaturan Presensi, auth NISN+PIN.
     */
    public function checkinMasukPulang(): ResponseInterface
    {
        $payload = $this->request->getJSON(true) ?? [];
        $nisn    = trim((string) ($payload['nisn'] ?? ''));
        $pin     = (string) ($payload['pin'] ?? '');
        $type    = strtolower(trim((string) ($payload['type'] ?? '')));
        $lat     = (float) ($payload['lat'] ?? 0);
        $lng     = (float) ($payload['lng'] ?? 0);

        if ($nisn === '' || $pin === '') {
            return $this->errorResponse('NISN dan PIN wajib diisi', null, null, ResponseInterface::HTTP_UNPROCESSABLE_ENTITY);
        }
        if ($type !== 'masuk' && $type !== 'pulang') {
            return $this->errorResponse('type harus masuk atau pulang', null, null, ResponseInterface::HTTP_UNPROCESSABLE_ENTITY);
        }

        $studentModel = new StudentModel();
        $student      = $studentModel->findByNisn($nisn);
        if (! $student) {
            return $this->errorResponse('Siswa tidak ditemukan', null, null, ResponseInterface::HTTP_NOT_FOUND);
        }

        $accountModel = new StudentMobileAccountModel();
        $accountRow  = $accountModel->where('student_id', (int) $student->id)->first();
        if (! $accountRow || empty($accountRow['pin_hash']) || ! password_verify($pin, $accountRow['pin_hash'])) {
            return $this->errorResponse('PIN salah', null, null, ResponseInterface::HTTP_UNAUTHORIZED);
        }

        $checkinService = new AttendanceCheckinService();
        $result         = $checkinService->checkinMasukPulang([
            'student_id' => (int) $student->id,
            'type'       => $type,
            'lat'        => $lat,
            'lng'       => $lng,
        ]);

        $messages = [
            'PRESENT'                => $type === 'masuk' ? 'Absen masuk berhasil.' : 'Absen pulang berhasil.',
            'LATE'                   => 'Absensi tercatat.',
            'OUTSIDE_ZONE'           => 'Anda di luar jangkauan sekolah.',
            'NO_SCHEDULE'            => 'Data tidak valid.',
            'INVALID_DEVICE'         => 'Device aplikasi mobile belum dikonfigurasi. Hubungi admin untuk menambah device dengan kode MOBILE_APP.',
            'ALREADY_CHECKED_IN'      => $type === 'masuk' ? 'Sudah absen masuk hari ini.' : 'Sudah absen pulang hari ini.',
            'ABSENCE_WINDOW_CLOSED'  => 'Di luar jam absen. Cek jam masuk/pulang di pengaturan sekolah.',
        ];
        $message = $messages[$result['status']] ?? $result['status'];

        return $this->successResponse($result, $message);
    }

    /**
     * GET /api/mobile/attendance/today?student_id=123
     * Returns today's attendance status for the student (untuk UI tombol Masuk/Pulang).
     */
    public function todayStatus(): ResponseInterface
    {
        $studentId = (int) $this->request->getGet('student_id');
        if ($studentId < 1) {
            return $this->errorResponse('student_id wajib', null, null, ResponseInterface::HTTP_BAD_REQUEST);
        }

        $db = \Config\Database::connect();
        $today = date('Y-m-d');
        $rows = $db->table('attendance_sessions')
            ->select('checkin_at, checkin_type')
            ->where('student_id', $studentId)
            ->where('attendance_date', $today)
            ->orderBy('checkin_at', 'ASC')
            ->get()
            ->getResultArray();

        $has_masuk = false;
        $has_pulang = false;
        $first_at = null;
        $last_at = null;
        foreach ($rows as $r) {
            $t = $r['checkin_at'] ?? '';
            $ct = $r['checkin_type'] ?? 'mapel';
            if ($t === '') {
                continue;
            }
            if (!$first_at) {
                $first_at = $t;
            }
            $last_at = $t;
            if ($ct === 'masuk') {
                $has_masuk = true;
            } elseif ($ct === 'pulang') {
                $has_pulang = true;
            } else {
                $timeOnly = date('H:i:s', strtotime($t));
                if ($timeOnly < '12:00:00') {
                    $has_masuk = true;
                }
                if ($timeOnly >= '13:00:00') {
                    $has_pulang = true;
                }
            }
        }

        $data = [
            'has_masuk'  => $has_masuk,
            'has_pulang' => $has_pulang,
            'first_at'   => $first_at,
            'last_at'    => $last_at,
            'date'       => $today,
        ];

        return $this->successResponse($data, 'OK');
    }
}
