<?php

declare(strict_types=1);

namespace apexl\Io\modules\user\Commands;

use apexl\Io\exceptions\RecordNotFoundException;
use apexl\Io\modules\user\entities\roleEntity;
use Exception;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(name: 'user:list-permissions', description: 'List a user\'s permissions')]
class UserListPermissionsCommand extends AbstractUserCommand
{
    protected function configure(): void
    {
        parent::configure();

        $this->addArgument('userIdOrEmail', InputArgument::REQUIRED, 'The user ID or email');
        $this->addOption(
            '--roles',
            '-R',
            InputOption::VALUE_NEGATABLE,
            'Include permissions granted via user\'s roles',
            true
        );
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);
        $userIdOrEmail = $input->getArgument('userIdOrEmail');
        $includeRoles = $input->getOption('roles');

        try {
            $user = $this->getUser($userIdOrEmail);
        } catch (RecordNotFoundException) {
            $io->error(sprintf('User with ID or email \'%s\' not found.', $userIdOrEmail));

            return self::FAILURE;
        }

        try {
            $rows = [
                ...$user->permissions(false)->map(
                    fn(string $permission) => ['Direct', $permission]
                )->toArray(),
            ];

            if ($includeRoles) {
                $user->roles()->each(function (roleEntity $role) use (&$rows) {
                    return $rows = [
                        ...$rows,
                        ...$role->permissions()->map(
                            fn(string $permission) => [sprintf('Role: %s', $role->name), $permission]
                        )->toArray(),
                    ];
                });
            }

            $io->info(sprintf('Permissions for user %s:', $user->email));
            $io->table(
                ['Granted Via', 'Role'],
                $rows,
            );

            return self::SUCCESS;

        } catch (Exception $e) {
            $io->error($e->getMessage());

            return self::FAILURE;
        }
    }
}
