<?php

namespace Database\Seeders;

use App\Domain\Identity\Models\Permission;
use App\Domain\Identity\Models\Role;
use App\Domain\Shared\Models\Academy;
use Illuminate\Database\Seeder;

class RolesAndPermissionsSeeder extends Seeder
{
    public function run(): void
    {
        $academy = Academy::where('slug', 'el-captain')->firstOrFail();

        $this->seedPermissions();
        $this->seedRoles($academy);
        $this->assignPermissions($academy);
    }

    // ─── Permissions ─────────────────────────────────────────────

    private function seedPermissions(): void
    {
        $modules = [
            'participants'    => ['view', 'list', 'create', 'update', 'delete', 'export'],
            'programs'        => ['view', 'list', 'create', 'update', 'delete'],
            'groups'          => ['view', 'list', 'create', 'update', 'delete'],
            'sessions'        => ['view', 'list', 'create', 'update', 'delete'],
            'enrollments'     => ['view', 'list', 'create', 'update', 'delete'],
            'attendance'      => ['view', 'list', 'create', 'update', 'export'],
            'invoices'        => ['view', 'list', 'create', 'update', 'delete', 'export', 'approve'],
            'payments'        => ['view', 'list', 'create', 'export', 'approve'],
            'wallets'         => ['view', 'list', 'create', 'update'],
            'cash_sessions'   => ['view', 'list', 'create', 'update'],
            'refunds'         => ['view', 'list', 'create', 'approve'],
            'pricing_rules'   => ['view', 'list', 'create', 'update', 'delete'],
            'facilities'      => ['view', 'list', 'create', 'update', 'delete'],
            'spaces'          => ['view', 'list', 'create', 'update', 'delete'],
            'assignments'     => ['view', 'list', 'create', 'update', 'delete'],
            'inventory'       => ['view', 'list', 'create', 'update', 'export'],
            'products'        => ['view', 'list', 'create', 'update', 'delete'],
            'purchase_orders' => ['view', 'list', 'create', 'update', 'approve'],
            'pos'             => ['view', 'list', 'create'],
            'kits'            => ['view', 'list', 'create', 'update', 'delete'],
            'stock_counts'    => ['view', 'list', 'create', 'approve'],
            'suppliers'       => ['view', 'list', 'create', 'update', 'delete'],
            'warehouses'      => ['view', 'list', 'create', 'update', 'delete'],
            'users'           => ['view', 'list', 'create', 'update', 'delete'],
            'roles'           => ['view', 'list', 'create', 'update', 'delete'],
            'branches'        => ['view', 'list', 'create', 'update', 'delete'],
            'settings'        => ['view', 'update'],
            'reports'         => ['view', 'export'],
            'notifications'   => ['view', 'update'],
            'templates'       => ['view', 'list', 'create', 'update', 'delete'],
            'evaluations'     => ['view', 'list', 'create', 'update', 'delete', 'export'],
            'waitlists'       => ['view', 'list', 'create', 'update'],
            'audit_logs'      => ['view', 'list', 'export'],
        ];

        foreach ($modules as $module => $actions) {
            foreach ($actions as $action) {
                Permission::firstOrCreate(
                    ['name' => "{$module}.{$action}"],
                    [
                        'module' => $module,
                        'action' => $action,
                    ]
                );
            }
        }
    }

    // ─── Roles ───────────────────────────────────────────────────

    private function seedRoles(Academy $academy): void
    {
        $roles = [
            ['slug' => 'super_admin',    'name' => 'Super Admin',     'name_ar' => 'مدير النظام',       'level' => 100, 'is_system' => true],
            ['slug' => 'academy_owner',  'name' => 'Academy Owner',   'name_ar' => 'مالك الأكاديمية',   'level' => 90,  'is_system' => true],
            ['slug' => 'academy_admin',  'name' => 'Academy Admin',   'name_ar' => 'مدير الأكاديمية',   'level' => 80,  'is_system' => true],
            ['slug' => 'branch_manager', 'name' => 'Branch Manager',  'name_ar' => 'مدير الفرع',        'level' => 70,  'is_system' => true],
            ['slug' => 'head_trainer',   'name' => 'Head Trainer',    'name_ar' => 'المدرب الرئيسي',    'level' => 60,  'is_system' => true],
            ['slug' => 'trainer',        'name' => 'Trainer',         'name_ar' => 'مدرب',              'level' => 50,  'is_system' => true],
            ['slug' => 'receptionist',   'name' => 'Receptionist',    'name_ar' => 'موظف الاستقبال',    'level' => 40,  'is_system' => true],
            ['slug' => 'accountant',     'name' => 'Accountant',      'name_ar' => 'محاسب',             'level' => 35,  'is_system' => true],
            ['slug' => 'data_entry',     'name' => 'Data Entry',      'name_ar' => 'مدخل بيانات',       'level' => 30,  'is_system' => true],
            ['slug' => 'parent',         'name' => 'Parent',          'name_ar' => 'ولي الأمر',         'level' => 5,   'is_system' => true],
        ];

        foreach ($roles as $role) {
            Role::firstOrCreate(
                ['academy_id' => $academy->id, 'slug' => $role['slug']],
                $role + ['academy_id' => $academy->id]
            );
        }
    }

    // ─── Permission Assignments ──────────────────────────────────

    private function assignPermissions(Academy $academy): void
    {
        $this->assignAcademyOwner($academy);
        $this->assignAcademyAdmin($academy);
        $this->assignBranchManager($academy);
        $this->assignTrainer($academy);
        $this->assignReceptionist($academy);
        $this->assignParent($academy);
    }

    private function assignAcademyOwner(Academy $academy): void
    {
        $role = Role::where('academy_id', $academy->id)->where('slug', 'academy_owner')->first();
        $allPermissions = Permission::pluck('id')->toArray();

        $pivotData = [];
        foreach ($allPermissions as $permId) {
            $pivotData[$permId] = ['scope' => 'academy'];
        }

        $role->permissions()->syncWithoutDetaching($pivotData);
    }

    private function assignAcademyAdmin(Academy $academy): void
    {
        $role = Role::where('academy_id', $academy->id)->where('slug', 'academy_admin')->first();

        // All permissions EXCEPT roles.delete
        $excluded = Permission::where('name', 'roles.delete')->pluck('id')->toArray();
        $permissions = Permission::whereNotIn('id', $excluded)->pluck('id')->toArray();

        $pivotData = [];
        foreach ($permissions as $permId) {
            $pivotData[$permId] = ['scope' => 'academy'];
        }

        $role->permissions()->syncWithoutDetaching($pivotData);
    }

    private function assignBranchManager(Academy $academy): void
    {
        $role = Role::where('academy_id', $academy->id)->where('slug', 'branch_manager')->first();

        $permissionMap = [
            'participants'  => ['view', 'list', 'create', 'update', 'export'],
            'programs'      => ['view', 'list'],
            'groups'        => ['view', 'list', 'create', 'update'],
            'sessions'      => ['view', 'list', 'create', 'update', 'delete'],
            'attendance'    => ['view', 'list', 'create', 'export'],
            'invoices'      => ['view', 'list', 'create'],
            'payments'      => ['view', 'list', 'create'],
            'cash_sessions' => ['view', 'list', 'create', 'update'],
            'pos'           => ['view', 'list', 'create'],
            'inventory'     => ['view', 'list'],
            'users'         => ['view', 'list'],
            'reports'       => ['view', 'export'],
            'facilities'    => ['view', 'list', 'update'],
            'assignments'   => ['view', 'list', 'create', 'update'],
            'branches'      => ['view'],
        ];

        $this->attachPermissions($role, $permissionMap, 'branch');
    }

    private function assignTrainer(Academy $academy): void
    {
        $role = Role::where('academy_id', $academy->id)->where('slug', 'trainer')->first();

        $ownGroupsPerms = [
            'participants'  => ['view', 'list'],
            'groups'        => ['view', 'list'],
            'sessions'      => ['view', 'list', 'update'],
            'attendance'    => ['view', 'list', 'create'],
            'evaluations'   => ['view', 'list', 'create', 'update'],
        ];

        $this->attachPermissions($role, $ownGroupsPerms, 'own_groups');

        // facilities.view with branch scope
        $facilityView = Permission::where('name', 'facilities.view')->first();
        if ($facilityView) {
            $role->permissions()->syncWithoutDetaching([
                $facilityView->id => ['scope' => 'branch'],
            ]);
        }
    }

    private function assignReceptionist(Academy $academy): void
    {
        $role = Role::where('academy_id', $academy->id)->where('slug', 'receptionist')->first();

        $permissionMap = [
            'participants'  => ['view', 'list', 'create', 'update'],
            'invoices'      => ['view', 'list', 'create'],
            'payments'      => ['view', 'list', 'create'],
            'pos'           => ['view', 'list', 'create'],
            'cash_sessions' => ['view', 'list', 'create', 'update'],
            'inventory'     => ['view', 'list'],
            'products'      => ['view', 'list'],
            'wallets'       => ['view', 'list'],
            'enrollments'   => ['view', 'list', 'create'],
        ];

        $this->attachPermissions($role, $permissionMap, 'branch');
    }

    private function assignParent(Academy $academy): void
    {
        $role = Role::where('academy_id', $academy->id)->where('slug', 'parent')->first();

        $ownChildrenPerms = [
            'participants' => ['view'],
            'attendance'   => ['view'],
            'invoices'     => ['view', 'list'],
            'evaluations'  => ['view'],
            'wallets'      => ['view'],
        ];

        $this->attachPermissions($role, $ownChildrenPerms, 'own_children');

        // programs.view and programs.list with academy scope
        $programPerms = Permission::whereIn('name', ['programs.view', 'programs.list'])->pluck('id')->toArray();
        $pivotData = [];
        foreach ($programPerms as $permId) {
            $pivotData[$permId] = ['scope' => 'academy'];
        }
        $role->permissions()->syncWithoutDetaching($pivotData);
    }

    // ─── Helper ──────────────────────────────────────────────────

    private function attachPermissions(Role $role, array $permissionMap, string $scope): void
    {
        $pivotData = [];

        foreach ($permissionMap as $module => $actions) {
            $names = array_map(fn ($action) => "{$module}.{$action}", $actions);
            $permissions = Permission::whereIn('name', $names)->pluck('id');

            foreach ($permissions as $permId) {
                $pivotData[$permId] = ['scope' => $scope];
            }
        }

        $role->permissions()->syncWithoutDetaching($pivotData);
    }
}
