<?php

namespace Database\Seeders;

use App\Models\Permission;
use App\Services\PermissionService;
use Illuminate\Database\Seeder;

class PermissionSeeder extends Seeder
{
    public function __construct(
        protected PermissionService $permissionService,
    ) {}

    public function run(): void
    {
        // Criação de Permissões
        /*
        view   = 1
        add    = 2
        edit   = 4
        delete = 8
        print  = 16
        export = 32
        import = 64
        limit  = 128
        menu   = 256

        para cada cada bit selecionado se faz a soma dos valores.
        */
        $permissions = [
            [
                'scope'       => 'config',
                'description' => 'Configurações',
                'bits'        => 271,
                'children'    => [
                    [
                        'scope'       => 'config.address',
                        'description' => 'Configurações de Endereços',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.bank',
                        'description' => 'Configurações de Bancos',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.city',
                        'description' => 'Configurações de Cidades',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.client',
                        'description' => 'Configurações de Clientes',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.client_favorite_provider',
                        'description' => 'Configurações de Prestadores Favoritos do Cliente',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.client_payment_method',
                        'description' => 'Configurações de Métodos de Pagamento do Cliente',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.client_provider_block',
                        'description' => 'Prestadores Bloqueados do Cliente',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.country',
                        'description' => 'Configurações de Países',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.custom_schedule',
                        'description' => 'Oportunidades (Agendamentos Personalizados)',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.improvement_type',
                        'description' => 'Configurações de Tipos de Melhoria',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.media',
                        'description' => 'Configurações de Mídia',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.permission',
                        'description' => 'Configurações de Permissões',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.provider',
                        'description' => 'Configurações de Prestadores',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.provider_blocked_day',
                        'description' => 'Configurações de Dias Bloqueados do Prestador',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.provider_client_block',
                        'description' => 'Clientes Bloqueados do Prestador',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.provider_services_types',
                        'description' => 'Configurações de Tipos de Serviços do Prestador',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.provider_speciality',
                        'description' => 'Configurações de Especialidades do Prestador',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.provider_working_day',
                        'description' => 'Configurações de Dias de Trabalho do Prestador',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.review',
                        'description' => 'Avaliações',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.review_improvement',
                        'description' => 'Melhorias das Avaliações',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.schedule',
                        'description' => 'Agendamentos',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.schedule_proposal',
                        'description' => 'Propostas de Agendamento',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.schedule_refuse',
                        'description' => 'Recusas de Agendamento',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.service_type',
                        'description' => 'Configurações de Tipos de Serviço',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.speciality',
                        'description' => 'Configurações de Especialidades',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.state',
                        'description' => 'Configurações de Estados',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                    [
                        'scope'       => 'config.user',
                        'description' => 'Configurações de Usuários',
                        'bits'        => 271,
                        'children'    => [],
                    ],

                    [
                        'scope'       => 'notification',
                        'description' => 'Notificações',
                        'bits'        => 271,
                        'children'    => [],
                    ],
                ],
            ],
            [
                'scope'       => 'dashboard',
                'description' => 'Dashboard',
                'bits'        => 511,
                'children'    => [],
            ],
            [
                'scope'       => 'payment',
                'description' => 'Pagamentos',
                'bits'        => 257,
                'children'    => [
                    [
                        'scope'       => 'payment-split',
                        'description' => 'Splits de Pagamento',
                        'bits'        => 1,
                        'children'    => [],
                    ],
                ],
            ],
            [
                'scope'       => 'support.request',
                'description' => 'Solicitações de Atendimento',
                'bits'        => 271,
                'children'    => [],
            ],
        ];

        $this->createPermissionsAndChildren(permissions: $permissions);
    }

    /**
     * Recursively creates or updates permissions and handles nesting.
     *
     * @param  array  $permissions  The array of permission data.
     * @param  Permission|null  $parent  The parent Permission object (for nested sets).
     */
    private function createPermissionsAndChildren(
        array $permissions,
        ?Permission $parent = null,
    ): void {
        foreach ($permissions as $permissionData) {
            $children = $permissionData['children'];

            unset($permissionData['children']);

            $permissionNode = Permission::updateOrCreate(
                ['scope' => $permissionData['scope']],
                $permissionData,
            );

            if ($parent) {
                $parent->appendNode($permissionNode);
            }

            if (! empty($children)) {
                $this->createPermissionsAndChildren(
                    permissions: $children,
                    parent:      $permissionNode,
                );
            }
        }
    }
}
