<?php

declare(strict_types=1);

namespace Flowaxy\Infrastructure\Persistence\Repositories;

use Flowaxy\Domain\User\Entities\Role;
use Flowaxy\Support\Facades\Log;
use PDO;
use PDOException;
use Throwable;

// Репозиторий для ролей
final class RoleRepository extends AbstractRepository
{
    protected string $tableName = 'roles';

    // Найти роль по slug
    public function findBySlug(string $slug): ?Role
    {
        if ($this->connection === null) {
            return null;
        }

        try {
            $stmt = $this->connection->prepare("SELECT * FROM {$this->tableName} WHERE slug = ?");
            $stmt->execute([$slug]);
            $row = $stmt->fetch(PDO::FETCH_ASSOC);
            return $row ? $this->mapToEntity($row) : null;
        } catch (PDOException $e) {
            try {
                Log::Error('Помилка пошуку ролі за slug', ['exception' => $e, 'slug' => $slug]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
            return null;
        }
    }

    /**
     * Преобразовать строку БД в сущность
     *
     * @param array<string, mixed> $row
     * @return Role
     */
    protected function mapToEntity(array $row): Role
    {
        $permissions = [];
        if (!empty($row['permissions'])) {
            $permissions = is_string($row['permissions'])
                ? json_decode($row['permissions'], true) ?? []
                : $row['permissions'];
        }

        return new Role(
            id: (int)$row['id'],
            name: (string)$row['name'],
            slug: (string)$row['slug'],
            description: $row['description'] ?? null,
            isSystem: (bool)($row['is_system'] ?? false),
            permissions: $permissions
        );
    }

    /**
     * Преобразовать сущность в массив для БД
     *
     * @param object $entity
     * @return array<string, mixed>
     */
    protected function mapFromEntity(object $entity): array
    {
        if (!$entity instanceof Role) {
            throw new \InvalidArgumentException('Entity must be an instance of Role');
        }

        return [
            'id' => $entity->id,
            'name' => $entity->name,
            'slug' => $entity->slug,
            'description' => $entity->description,
            'is_system' => $entity->isSystem ? 1 : 0,
            'permissions' => json_encode($entity->permissions),
        ];
    }
}
