<?php

namespace App\Models;

/** See CreateLoginOtpCodesTable's migration comment. */
class LoginOtpCodeModel extends TenantModel
{
    protected $table            = 'login_otp_codes';
    protected $primaryKey       = 'id';
    protected $useAutoIncrement = true;
    protected $returnType       = 'object';
    protected $useTimestamps    = true;
    protected $createdField     = 'created_at';
    protected $updatedField     = '';

    protected $allowedFields = ['user_id', 'code', 'expires_at', 'used_at'];

    private const TTL_MINUTES = 10;

    /**
     * Invalidates any previous unused code for this user (so only the
     * most recently sent code ever works) and issues a new one.
     */
    public function generateFor(int $userId): string
    {
        $this->where('user_id', $userId)->where('used_at', null)->set(['used_at' => date('Y-m-d H:i:s')])->update(null);

        $code = (string) random_int(100000, 999999);

        $this->insert([
            'user_id'    => $userId,
            'code'       => $code,
            'expires_at' => date('Y-m-d H:i:s', strtotime('+' . self::TTL_MINUTES . ' minutes')),
            'used_at'    => null,
        ]);

        return $code;
    }

    /** Validates a code without consuming it — consume() is called separately once login actually completes. */
    public function isValid(int $userId, string $code): bool
    {
        return $this->where('user_id', $userId)
            ->where('code', $code)
            ->where('used_at', null)
            ->where('expires_at >', date('Y-m-d H:i:s'))
            ->first() !== null;
    }

    public function consume(int $userId, string $code): void
    {
        $this->where('user_id', $userId)->where('code', $code)->set(['used_at' => date('Y-m-d H:i:s')])->update(null);
    }
}
