<?php

namespace App\Services;

use App\Models\User;
use Illuminate\Support\Facades\Hash;

class OtpService
{
    private const TTL_MINUTES = 10;

    private const MAX_ATTEMPTS = 5;

    public function generateFor(User $user): string
    {
        $user->emailOtps()->whereNull('consumed_at')->delete();

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

        $user->emailOtps()->create([
            'code_hash'  => Hash::make($code),
            'expires_at' => now()->addMinutes(self::TTL_MINUTES),
        ]);

        return $code;
    }

    public function verify(User $user, string $code): bool
    {
        $otp = $user->emailOtps()
            ->whereNull('consumed_at')
            ->where('expires_at', '>', now())
            ->latest()
            ->first();

        if (!$otp || $otp->attempts >= self::MAX_ATTEMPTS) {
            return false;
        }

        if (!Hash::check($code, $otp->code_hash)) {
            $otp->increment('attempts');

            return false;
        }

        $otp->update(['consumed_at' => now()]);
        $user->markEmailAsVerified();

        return true;
    }
}
