<?php

declare(strict_types=1);

namespace Flowaxy\Domain\User\Services;

use Flowaxy\Contracts\Domain\User\RoleRepositoryInterface;
use Flowaxy\Domain\User\Entities\Role;
use Flowaxy\Support\Facades\Log;
use Throwable;

// Сервіс авторизації користувача
final class AuthorizationService
{
    public function __construct(private readonly RoleRepositoryInterface $roles)
    {
    }

    public function userHasPermission(int $userId, string $permission): bool
    {
        // Root пользователь (userId = 0) всегда имеет все права
        if ($userId === 0) {
            return true;
        }

        $result = $this->roles->userHasPermission($userId, $permission);

        if (!$result) {
            try {
                Log::Warning('Доступ заборонено', [
                    'user_id' => $userId,
                    'permission' => $permission,
                ]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
        }

        return $result;
    }

    public function userHasRole(int $userId, string $roleSlug): bool
    {
        // Root пользователь (userId = 0) всегда имеет все роли
        if ($userId === 0) {
            return true;
        }

        return $this->roles->userHasRole($userId, $roleSlug);
    }

    public function getUserPermissions(int $userId): array
    {
        // Root пользователь (userId = 0) имеет все права - возвращаем специальный маркер
        if ($userId === 0) {
            return ['*']; // Специальный маркер для "все права"
        }

        return $this->roles->getPermissionsForUser($userId);
    }

    public function getUserRoles(int $userId): array
    {
        // Root пользователь (userId = 0) имеет все роли - возвращаем специальный маркер
        if ($userId === 0) {
            return ['root']; // Специальная роль для root
        }

        return $this->roles->getRolesForUser($userId);
    }

    public function assignRole(int $userId, int $roleId): bool
    {
        $result = $this->roles->assignRole($userId, $roleId);

        if (!$result) {
            try {
                Log::Error('Помилка призначення ролі', [
                    'user_id' => $userId,
                    'role_id' => $roleId,
                ]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
        }

        return $result;
    }

    public function removeRole(int $userId, int $roleId): bool
    {
        $result = $this->roles->removeRole($userId, $roleId);

        if (!$result) {
            try {
                Log::Error('Помилка видалення ролі', [
                    'user_id' => $userId,
                    'role_id' => $roleId,
                ]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
        }

        return $result;
    }
}
