<?php

declare(strict_types=1);

namespace FatBottom\Services;

use FatBottom\Core\Config;
use FatBottom\Core\Database;

final class TwoFactorService
{
    public function __construct(
        private readonly Database $db,
        private readonly Mailer $mailer,
        private readonly Config $config
    ) {
    }

    public function issue(array $user, string $purpose = 'login'): ?string
    {
        $code = (string) random_int(100000, 999999);
        $expiresAt = gmdate('Y-m-d H:i:s', time() + 600);

        $this->db->execute(
            'INSERT INTO login_codes (user_id, code_hash, purpose, expires_at) VALUES (?, ?, ?, ?)',
            [(int) $user['id'], password_hash($code, PASSWORD_DEFAULT), $purpose, $expiresAt]
        );

        $name = htmlspecialchars((string) $user['full_name'], ENT_QUOTES, 'UTF-8');
        $this->mailer->send(
            (string) $user['email'],
            'Your Fat Bottom Grille verification code',
            "<p>Hi {$name},</p><p>Your verification code is <strong>{$code}</strong>.</p><p>It expires in 10 minutes.</p>"
        );

        return (bool) $this->config->get('mailgun.enabled', false) ? null : $code;
    }

    public function verify(int $userId, string $code, string $purpose = 'login'): bool
    {
        $record = $this->db->fetch(
            'SELECT * FROM login_codes
             WHERE user_id = ? AND purpose = ? AND used_at IS NULL AND expires_at > CURRENT_TIMESTAMP
             ORDER BY id DESC LIMIT 1',
            [$userId, $purpose]
        );
        if ($record === null || !password_verify($code, (string) $record['code_hash'])) {
            return false;
        }

        $this->db->execute('UPDATE login_codes SET used_at = CURRENT_TIMESTAMP WHERE id = ?', [(int) $record['id']]);
        return true;
    }
}
