<?php

declare(strict_types=1);

namespace App\Core;

use PDO;

/**
 * PlatformAuth
 *
 * The software owner's identity, kept completely separate from
 * App\Core\Auth (which is per-tenant CRM users). Deliberately uses a
 * different session key ('platform_admin_id' vs 'user_id') so the two
 * never collide, and a platform admin session is never accidentally
 * treated as a tenant login (or vice versa) by anything that just
 * checks Auth::check().
 */
final class PlatformAuth
{
    private static ?array $cachedAdmin = null;
    private static bool $resolved = false;

    public static function id(): ?int
    {
        $id = Session::get('platform_admin_id');

        return $id === null ? null : (int) $id;
    }

    public static function check(): bool
    {
        return self::id() !== null;
    }

    public static function guest(): bool
    {
        return !self::check();
    }

    public static function admin(): ?array
    {
        if (self::$resolved) {
            return self::$cachedAdmin;
        }

        self::$resolved = true;
        $id = self::id();

        if ($id === null) {
            return self::$cachedAdmin = null;
        }

        $stmt = Database::connection()->prepare(
            'SELECT * FROM platform_admins WHERE id = :id AND is_active = 1 LIMIT 1'
        );
        $stmt->execute(['id' => $id]);
        $admin = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($admin === false) {
            Session::destroy();

            return self::$cachedAdmin = null;
        }

        unset($admin['password_hash']);

        return self::$cachedAdmin = $admin;
    }

    public static function attempt(string $email, string $password): bool
    {
        $stmt = Database::connection()->prepare(
            'SELECT * FROM platform_admins WHERE email = :email AND is_active = 1 LIMIT 1'
        );
        $stmt->execute(['email' => $email]);
        $admin = $stmt->fetch(PDO::FETCH_ASSOC);

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

        self::login((int) $admin['id']);

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

        return true;
    }

    public static function login(int $adminId): void
    {
        Session::regenerate();
        Session::set('platform_admin_id', $adminId);
        self::$resolved = false;
        self::$cachedAdmin = null;
    }

    public static function logout(): void
    {
        Session::destroy();
        self::$resolved = false;
        self::$cachedAdmin = null;
    }
}
