<?php

namespace Mtc\Core\Admin;

use PragmaRX\Google2FA\Google2FA;
use BaconQrCode\Renderer\ImageRenderer;
use BaconQrCode\Renderer\Image\SvgImageBackEnd;
use BaconQrCode\Renderer\RendererStyle\RendererStyle;
use BaconQrCode\Writer;

class TotpService
{
    private Google2FA $google2fa;

    public function __construct()
    {
        $this->google2fa = new Google2FA();
    }

    public function generateSecret(): string
    {
        return $this->google2fa->generateSecretKey();
    }

    public function getQrCodeSvg(string $secret, string $email): string
    {
        $issuer = config('app.name', 'Pharmacy Admin');
        $uri = $this->google2fa->getQRCodeUrl($issuer, $email, $secret);

        $renderer = new ImageRenderer(
            new RendererStyle(200),
            new SvgImageBackEnd()
        );
        $writer = new Writer($renderer);

        return $writer->writeString($uri);
    }

    /**
     * Verify a TOTP code with replay protection.
     *
     * @param string   $secret       The user's TOTP secret
     * @param string   $code         The 6-digit code to verify
     * @param int|null $oldTimestamp  The timestamp from the last accepted code (totp_last_used_at), or null
     * @return false|int  False on failure, or the new timestamp counter to store on success
     */
    public function verifyCode(string $secret, string $code, ?int $oldTimestamp = null): false|int
    {
        return $this->google2fa->verifyKeyNewer($secret, $code, $oldTimestamp ?? 0, 1);
    }

    public static function shouldBypass(): bool
    {
        return app()->isLocal() && config('auth.bypass_2fa', false);
    }

    public static function isExempt(string $username): bool
    {
        if (self::shouldBypass()) {
            return true;
        }

        return OtpAuthService::shouldHandleLogin($username);
    }
}
