<?php

namespace App\Modules\Mobile\Controllers;

use App\Core\BaseApiController;
use App\Modules\Academic\Models\ClassModel;
use App\Modules\Academic\Models\StudentModel;
use App\Modules\Mobile\Models\StudentMobileAccountModel;
use CodeIgniter\HTTP\ResponseInterface;

class RegistrationController extends BaseApiController
{
    /**
     * POST /api/mobile/login
     *
     * Body: { "nisn": "...", "pin": "..." }
     */
    public function login(): ResponseInterface
    {
        $payload = $this->request->getJSON(true) ?? [];
        $nisn    = trim((string) ($payload['nisn'] ?? ''));
        $pin     = (string) ($payload['pin'] ?? '');

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

        $studentModel = new StudentModel();
        $student      = $studentModel->findByNisn($nisn);

        if (! $student) {
            return $this->errorResponse('Siswa dengan NISN tersebut tidak ditemukan', null, null, ResponseInterface::HTTP_NOT_FOUND);
        }

        if ((int) ($student->is_active ?? 1) === 0) {
            return $this->errorResponse('Siswa ini tidak aktif', null, null, ResponseInterface::HTTP_FORBIDDEN);
        }

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

        $classModel = new ClassModel();
        /** @var \App\Modules\Academic\Entities\ClassEntity|null $class */
        $class      = null;
        if ($student->class_id) {
            $class = $classModel->find($student->class_id);
        }

        $classLabel = '-';
        if ($class !== null) {
            $parts = array_filter([
                trim((string) ($class->grade ?? '')),
                trim((string) ($class->major ?? '')),
                trim((string) ($class->name ?? '')),
            ]);
            $label = implode(' ', $parts);
            $classLabel = $label !== '' ? $label : ('Kelas #' . (int) $class->id);
        }

        $data = [
            'student_id'  => (int) $student->id,
            'name'        => (string) ($student->name ?? ''),
            'nisn'        => (string) ($student->nisn ?? ''),
            'class_id'    => $student->class_id ? (int) $student->class_id : null,
            'class_label' => $classLabel,
        ];

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

    /**
     * POST /api/mobile/register/nisn
     *
     * Body: { "nisn": "..." }
     */
    public function checkNisn(): ResponseInterface
    {
        $payload = $this->request->getJSON(true) ?? [];
        $nisn    = trim((string) ($payload['nisn'] ?? ''));

        if ($nisn === '') {
            return $this->errorResponse('NISN wajib diisi', null, null, ResponseInterface::HTTP_UNPROCESSABLE_ENTITY);
        }

        $studentModel = new StudentModel();
        $student      = $studentModel->findByNisn($nisn);

        if (! $student) {
            return $this->errorResponse('Siswa dengan NISN tersebut tidak ditemukan', null, null, ResponseInterface::HTTP_NOT_FOUND);
        }

        if ((int) ($student->is_active ?? 1) === 0) {
            return $this->errorResponse('Siswa ini tidak aktif', null, null, ResponseInterface::HTTP_FORBIDDEN);
        }

        // Sudah punya akun mobile (PIN) → arahkan ke login
        $accountModel = new StudentMobileAccountModel();
        $accountRow   = $accountModel->where('student_id', (int) $student->id)->first();
        if ($accountRow && ! empty($accountRow['pin_hash'])) {
            return $this->errorResponse('NISN ini sudah terdaftar. Silakan masuk.', null, null, ResponseInterface::HTTP_CONFLICT);
        }

        $classModel = new ClassModel();
        $classes    = $classModel->orderBy('grade', 'ASC')
            ->orderBy('major', 'ASC')
            ->orderBy('name', 'ASC')
            ->findAll();

        $availableClasses = [];
        foreach ($classes as $c) {
            $parts = array_filter([
                trim((string) ($c->grade ?? '')),
                trim((string) ($c->major ?? '')),
                trim((string) ($c->name ?? '')),
            ]);
            $label = implode(' ', $parts);
            $availableClasses[] = [
                'id'    => (int) $c->id,
                'label' => $label !== '' ? $label : ('Kelas #' . (int) $c->id),
            ];
        }

        $currentClassId    = $student->class_id ? (int) $student->class_id : null;
        $currentClassLabel = null;
        if ($currentClassId !== null) {
            foreach ($availableClasses as $cls) {
                if ($cls['id'] === $currentClassId) {
                    $currentClassLabel = $cls['label'];
                    break;
                }
            }
        }

        $data = [
            'student_id'        => (int) $student->id,
            'name'              => (string) ($student->name ?? ''),
            'nisn'              => (string) ($student->nisn ?? ''),
            'current_class_id'  => $currentClassId,
            'current_class_label' => $currentClassLabel,
            'available_classes' => $availableClasses,
        ];

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

    /**
     * POST /api/mobile/register/complete
     *
     * Body: { "student_id": 0, "class_id": 0, "pin": "123456" }
     */
    public function complete(): ResponseInterface
    {
        $payload   = $this->request->getJSON(true) ?? [];
        $studentId = (int) ($payload['student_id'] ?? 0);
        $classId   = (int) ($payload['class_id'] ?? 0);
        $pin       = (string) ($payload['pin'] ?? '');

        if ($studentId <= 0) {
            return $this->errorResponse('student_id wajib diisi', null, null, ResponseInterface::HTTP_UNPROCESSABLE_ENTITY);
        }
        if ($classId <= 0) {
            return $this->errorResponse('Kelas wajib dipilih', null, null, ResponseInterface::HTTP_UNPROCESSABLE_ENTITY);
        }
        $pin = trim($pin);
        if ($pin === '' || strlen($pin) < 4) {
            return $this->errorResponse('PIN minimal 4 karakter', null, null, ResponseInterface::HTTP_UNPROCESSABLE_ENTITY);
        }

        $studentModel = new StudentModel();
        $classModel   = new ClassModel();

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

        $class = $classModel->find($classId);
        if (! $class) {
            return $this->errorResponse('Kelas tidak ditemukan', null, null, ResponseInterface::HTTP_NOT_FOUND);
        }

        // Update class_id siswa (mapping pertama kali / koreksi)
        $studentModel->update($studentId, ['class_id' => $classId]);

        // Simpan / update akun mobile siswa
        $accountModel = new StudentMobileAccountModel();
        $pinHash      = password_hash($pin, PASSWORD_BCRYPT);

        $exists = $accountModel->where('student_id', $studentId)->first();
        if ($exists) {
            $accountModel->update((int) $exists['id'], [
                'pin_hash' => $pinHash,
            ]);
        } else {
            $accountModel->insert([
                'student_id' => $studentId,
                'pin_hash'   => $pinHash,
            ]);
        }

        $classLabelParts = array_filter([
            trim((string) ($class->grade ?? '')),
            trim((string) ($class->major ?? '')),
            trim((string) ($class->name ?? '')),
        ]);
        $classLabel = implode(' ', $classLabelParts);

        $data = [
            'student_id'  => $studentId,
            'name'        => (string) ($student->name ?? ''),
            'nisn'        => (string) ($student->nisn ?? ''),
            'class_id'    => (int) $class->id,
            'class_label' => $classLabel !== '' ? $classLabel : ('Kelas #' . (int) $class->id),
        ];

        return $this->successResponse($data, 'Registrasi mobile berhasil');
    }

    /**
     * POST /api/mobile/forgot-pin
     *
     * Body: { "nisn": "...", "new_pin": "1234", "new_pin_confirm": "1234" }
     */
    public function forgotPin(): ResponseInterface
    {
        $payload = $this->request->getJSON(true) ?? [];
        $nisn    = trim((string) ($payload['nisn'] ?? ''));
        $newPin  = (string) ($payload['new_pin'] ?? '');
        $newPinConfirm = (string) ($payload['new_pin_confirm'] ?? '');

        if ($nisn === '') {
            return $this->errorResponse('NISN wajib diisi', null, null, ResponseInterface::HTTP_UNPROCESSABLE_ENTITY);
        }

        $newPin = trim($newPin);
        $newPinConfirm = trim($newPinConfirm);
        if ($newPin === '' || strlen($newPin) < 4) {
            return $this->errorResponse('PIN baru minimal 4 karakter', null, null, ResponseInterface::HTTP_UNPROCESSABLE_ENTITY);
        }
        if ($newPin !== $newPinConfirm) {
            return $this->errorResponse('PIN baru dan konfirmasi tidak sama', null, null, ResponseInterface::HTTP_UNPROCESSABLE_ENTITY);
        }

        $studentModel = new StudentModel();
        $student      = $studentModel->findByNisn($nisn);

        if (! $student) {
            return $this->errorResponse('Siswa dengan NISN tersebut tidak ditemukan', null, null, ResponseInterface::HTTP_NOT_FOUND);
        }

        if ((int) ($student->is_active ?? 1) === 0) {
            return $this->errorResponse('Siswa ini tidak aktif', null, null, ResponseInterface::HTTP_FORBIDDEN);
        }

        $accountModel = new StudentMobileAccountModel();
        $accountRow   = $accountModel->where('student_id', (int) $student->id)->first();

        if (! $accountRow || empty($accountRow['pin_hash'])) {
            return $this->errorResponse('NISN ini belum terdaftar. Silakan daftar dulu.', null, null, ResponseInterface::HTTP_CONFLICT);
        }

        $pinHash = password_hash($newPin, PASSWORD_BCRYPT);
        $accountModel->update((int) $accountRow['id'], ['pin_hash' => $pinHash]);

        return $this->successResponse(
            ['student_id' => (int) $student->id],
            'PIN berhasil direset. Silakan masuk dengan PIN baru.'
        );
    }
}

