<?php

declare(strict_types=1);

namespace App\Core;

/**
 * Authentification administrateur (password_hash / password_verify).
 */
final class Auth
{
    private const SESSION_KEY = 'admin_id';

    public static function attempt(string $email, string $password): bool
    {
        $pdo  = Database::connection();
        $stmt = $pdo->prepare('SELECT id, password_hash, display_name FROM admins WHERE email = :email LIMIT 1');
        $stmt->execute(['email' => $email]);
        $admin = $stmt->fetch();

        if ($admin === false || !password_verify($password, (string) $admin['password_hash'])) {
            return false;
        }

        // Re-hachage si l'algorithme par défaut a évolué.
        if (password_needs_rehash((string) $admin['password_hash'], PASSWORD_DEFAULT)) {
            $pdo->prepare('UPDATE admins SET password_hash = :hash WHERE id = :id')
                ->execute(['hash' => password_hash($password, PASSWORD_DEFAULT), 'id' => $admin['id']]);
        }

        Session::regenerate();
        $_SESSION[self::SESSION_KEY] = (int) $admin['id'];
        $_SESSION['admin_name']      = (string) $admin['display_name'];

        $pdo->prepare('UPDATE admins SET last_login_at = NOW() WHERE id = :id')
            ->execute(['id' => $admin['id']]);

        return true;
    }

    public static function check(): bool
    {
        return !empty($_SESSION[self::SESSION_KEY]);
    }

    public static function id(): ?int
    {
        return isset($_SESSION[self::SESSION_KEY]) ? (int) $_SESSION[self::SESSION_KEY] : null;
    }

    public static function name(): string
    {
        return (string) ($_SESSION['admin_name'] ?? '');
    }

    /** Vérifie le mot de passe de l'admin actuellement connecté. */
    public static function verifyPassword(string $password): bool
    {
        $id = self::id();
        if ($id === null) {
            return false;
        }
        $stmt = Database::connection()->prepare('SELECT password_hash FROM admins WHERE id = :id');
        $stmt->execute(['id' => $id]);
        $hash = $stmt->fetchColumn();
        return is_string($hash) && password_verify($password, $hash);
    }

    /** Définit un nouveau mot de passe (haché) pour l'admin connecté. */
    public static function setPassword(string $newPassword): bool
    {
        $id = self::id();
        if ($id === null) {
            return false;
        }
        Database::connection()
            ->prepare('UPDATE admins SET password_hash = :h WHERE id = :id')
            ->execute(['h' => password_hash($newPassword, PASSWORD_DEFAULT), 'id' => $id]);
        return true;
    }

    public static function logout(): void
    {
        unset($_SESSION[self::SESSION_KEY], $_SESSION['admin_name']);
        Session::regenerate();
    }
}
