<?php
namespace Services;

use Core\Database;
use Core\Session;
use Models\User;

class AuthService {
    private Database $db;
    private User $userModel;

    public function __construct() {
        $this->db        = Database::getInstance();
        $this->userModel = new User();
    }

    public function attempt(string $identifier, string $password, string $ip): array {
        // Brute force protection — max 5 failed attempts in 15 minutes
        $recentFails = $this->db->fetch(
            "SELECT COUNT(*) AS cnt FROM login_attempts
             WHERE (email=? OR ip_address=?) AND successful=0
             AND attempted_at >= DATE_SUB(NOW(), INTERVAL 15 MINUTE)",
            [$identifier, $ip]
        )['cnt'] ?? 0;
        if ($recentFails >= 5)
            return ['success'=>false,'error'=>'Too many failed attempts. Please wait 15 minutes and try again.'];

        // Try email first, then assessment number for students
        $user = $this->userModel->findByEmail($identifier);
        if (!$user) {
            $user = $this->userModel->findByAssessmentNo($identifier);
        }

        if (!$user || !password_verify($password, $user['password'])) {
            $this->logAttempt($identifier, $ip, false);
            return ['success'=>false,'error'=>'Invalid credentials.'];
        }

        if (!$user['is_active']) {
            return ['success'=>false,'error'=>'Your account has been deactivated.'];
        }

        $this->logAttempt($identifier, $ip, true);
        $this->userModel->updateLastLogin($user['id'], $ip);

        if ($user['two_fa_enabled']) {
            $this->sendTwoFaCode($user);
            return ['success'=>true,'requires_2fa'=>true,'user_id'=>$user['id']];
        }

        return ['success'=>true,'requires_2fa'=>false,'user'=>$user];
    }

    public function sendTwoFaCode(array $user): void {
        $code = str_pad((string)random_int(0, 999999), 6, '0', STR_PAD_LEFT);
        $this->userModel->setTwoFaCode($user['id'], password_hash($code, PASSWORD_BCRYPT));
        // Send email
        (new MailService())->send(
            $user['email'],
            'Your EduSmart 2FA Code',
            "Your verification code is: <strong>$code</strong><br>Valid for 10 minutes."
        );
    }

    public function verifyTwoFa(int $userId, string $code): bool {
        $user = $this->userModel->find($userId);
        if (!$user || !$user['two_fa_code']) return false;
        if (strtotime($user['two_fa_expires_at']) < time()) return false;
        if (!password_verify($code, $user['two_fa_code'])) return false;
        $this->userModel->clearTwoFa($userId);
        return true;
    }

    public function loginUser(array $user): void {
        Session::regenerate();
        Session::set('user', [
            'id'        => $user['id'],
            'name'      => $user['name'],
            'email'     => $user['email'],
            'role'      => $user['role'],
            'school_id' => $user['school_id'],
            'avatar'    => $user['avatar'],
            'is_active' => $user['is_active'],
        ]);
    }

    private function logAttempt(string $email, string $ip, bool $success): void {
        try {
            $this->db->insert('login_attempts', [
                'email'        => $email,
                'ip_address'   => $ip,
                'successful'   => $success ? 1 : 0,
                'attempted_at' => date('Y-m-d H:i:s'),
            ]);
        } catch (\Exception $e) {}
    }
}
