<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

class PermissionSeeder extends Seeder
{

    private array $modules = [
        'dashboard' => [
            'actions' => ['view'],
            'label' => 'لوحة التحكم',
            'guard' => 'web'
        ],
        'plans' => [
            'actions' => ['view', 'create', 'edit', 'delete'],
            'label' => 'الخطط',
            'guard' => 'web'
        ],
        'customers' => [
            'actions' => ['view', 'create', 'edit', 'delete', 'whatsapp'], // 'export'
            'label' => 'العملاء',
            'guard' => 'web'
        ],
        'subscriptions' => [
            'actions' => ['view', 'create', 'edit', 'view_amounts', 'renew', 'cancel'],
            'label' => 'الاشتراكات',
            'guard' => 'web'
        ],

        'receipt_vouchers' => [
            'actions' => ['view', 'create', 'cancel'],
            'label' => 'سندات القبض',
            'guard' => 'web'
        ],
        'payment_vouchers' => [
            'actions' => ['view', 'create', 'cancel'],
            'label' => 'سندات الصرف',
            'guard' => 'web'
        ],
        'external_payment_vouchers' => [
            'actions' => ['view', 'create'],
            'label' => 'سندات الدفع الخارجي',
            'guard' => 'web'
        ],
        'customers_balance' => [
            'actions' => ['view', 'adjust'], // 'adjust'
            'label' => 'أرصدة العملاء',
            'guard' => 'web'
        ],

        'revenues_report' => [
            'actions' => ['view', 'print'], // 'export', 'schedule'
            'label' => 'تقرير الإيرادات',
            'guard' => 'web'
        ],
        'expenses_report' => [
            'actions' => ['view', 'print'], // 'export', 'schedule'
            'label' => 'تقرير المصروفات',
            'guard' => 'web'
        ],
        'refunds_report' => [
            'actions' => ['view', 'print'], // 'export'
            'label' => 'تقرير المبالغ المستردة',
            'guard' => 'web'
        ],
        'plans_report' => [
            'actions' => ['view', 'print'], // 'export'
            'label' => 'تقرير الخطط',
            'guard' => 'web'
        ],

        'system_settings' => [
            'actions' => ['view', 'edit'], // 'backup', 'restore'
            'label' => 'إعدادات النظام',
            'guard' => 'web'
        ],
        'users' => [
            'actions' => ['view', 'create', 'edit', 'delete'],
            'label' => 'المستخدمين',
            'guard' => 'web'
        ],
        'roles' => [
            'actions' => ['view', 'create', 'edit', 'delete', 'assign'],
            'label' => 'الأدوار',
            'guard' => 'web'
        ],
        'audit_logs' => [
            'actions' => ['view', 'export'],
            'label' => 'سجلات التدقيق',
            'guard' => 'web'
        ],
    ];

    private array $roles = [
        'owner' => [
            'name_ar' => 'مالك',
            'description' => 'صلاحيات كاملة على جميع وحدات النظام',
            'is_default' => true,
            'permissions' => 'all'
        ],
        'programmer' => [
            'name_ar' => 'مبرمج',
            'description' => 'صلاحيات كاملة مع إمكانية الوصول للإعدادات التقنية',
            'is_default' => true,
            'permissions' => 'all'
        ],
        'admin' => [
            'name_ar' => 'مدير عام',
            'description' => 'إدارة المستخدمين والأدوار والصلاحيات',
            'is_default' => true,
            'permissions' => [
                'dashboard.view',
                'users.*',
                'roles.*',
                'system_settings.view',
                'audit_logs.view',
                'revenues_report.*',
                'expenses_report.*',
                'refunds_report.*',
                'plans_report.*',
            ]
        ],
        'accountant' => [
            'name_ar' => 'محاسب',
            'description' => 'إدارة الحسابات والسندات المالية',
            'is_default' => true,
            'permissions' => [
                'dashboard.view',
                'receipt_vouchers.*',
                'payment_vouchers.*',
                'external_payment_vouchers.*',
                'customers_balance.view',
                'customers_balance.adjust',
                'revenues_report.*',
                'expenses_report.*',
                'refunds_report.view',
                'customers.view'
            ]
        ],
        'coach' => [
            'name_ar' => 'مدرب',
            'description' => 'عرض معلومات العملاء والاشتراكات',
            'is_default' => true,
            'permissions' => [
                'dashboard.view',
                'customers.view',
                'subscriptions.view',
                'plans.view'
            ]
        ],
        'reception' => [
            'name_ar' => 'استقبال',
            'description' => 'عرض معلومات العملاء وإنشاء اشتراكات جديدة',
            'is_default' => true,
            'permissions' => [
                'dashboard.view',
                'customers.view',
                'customers.create',
                'subscriptions.view',
                'subscriptions.create',
                'receipt_vouchers.create',
                'plans.view'
            ]
        ],
        'employee' => [
            'name_ar' => 'موظف',
            'description' => 'صلاحيات محدودة للعرض فقط',
            'is_default' => true,
            'permissions' => [
                'dashboard.view'
            ]
        ],
    ];

    private array $actionLabels = [
        'view' => 'عرض',
        'create' => 'إنشاء',
        'edit' => 'تعديل',
        'delete' => 'حذف',
        'export' => 'تصدير',
        'print' => 'طباعة',
        'approve' => 'اعتماد',
        'cancel' => 'إلغاء',
        'renew' => 'تجديد',
        'adjust' => 'تسوية',
        'schedule' => 'جدولة',
        'backup' => 'نسخ احتياطي',
        'restore' => 'استعادة',
        'activate' => 'تفعيل',
        'deactivate' => 'تعطيل',
        'assign' => 'تعيين',
    ];

    public function run(): void
    {
        // تعطيل القيود المؤقتة
        Schema::disableForeignKeyConstraints();

        DB::transaction(function () {
            // تنظيف البيانات القديمة
            Permission::query()->delete();
            Role::query()->delete();

            // إنشاء الصلاحيات
            $this->createPermissions();

            // إنشاء الأدوار
            $this->createRoles();

            // تعيين الصلاحيات للأدوار
            $this->assignPermissionsToRoles();

            // تعيين الأدوار للمستخدمين الحاليين
            $this->assignRolesToExistingUsers();
        });

        Schema::enableForeignKeyConstraints();
    }

    private function createPermissions(): void
    {
        foreach ($this->modules as $module => $config) {
            foreach ($config['actions'] as $action) {
                $permissionName = "{$module}.{$action}";

                Permission::create([
                    'name' => $permissionName,
                    'guard_name' => $config['guard'] ?? 'web',
                    'module' => $module,
                    'action' => $action,
                    'description' => $this->getPermissionDescription($module, $action),
                ]);
            }
        }

        $this->command->info('✓ تم إنشاء ' . Permission::count() . ' صلاحية');
    }

    private function createRoles(): void
    {
        foreach ($this->roles as $roleName => $config) {
            Role::create([
                'name' => $roleName,
                'name_ar' => $config['name_ar'],
                'guard_name' => 'web',
                'description' => $config['description'],
                'is_default' => $config['is_default'],
            ]);
        }

        $this->command->info('✓ تم إنشاء ' . Role::count() . ' دور');
    }

    private function assignPermissionsToRoles(): void
    {
        foreach ($this->roles as $roleName => $config) {
            $role = Role::where('name', $roleName)->first();

            if (!$role) {
                continue;
            }

            if ($config['permissions'] === 'all') {
                // منح جميع الصلاحيات
                $role->syncPermissions(Permission::all());
                $this->command->info("✓ تم منح جميع الصلاحيات لدور: {$config['name_ar']}");
            } else {
                // منح الصلاحيات المحددة
                $permissions = $this->resolvePermissions($config['permissions']);
                $role->syncPermissions($permissions);
                $this->command->info("✓ تم منح " . count($permissions) . " صلاحية لدور: {$config['name_ar']}");
            }
        }
    }

    private function resolvePermissions(array $patterns): array
    {
        $allPermissions = Permission::all();
        $resolved = collect();

        foreach ($patterns as $pattern) {
            if (str_ends_with($pattern, '.*')) {
                // نمط يشمل جميع الصلاحيات للوحدة
                $module = substr($pattern, 0, -2);
                $filtered = $allPermissions->filter(function ($permission) use ($module) {
                    return str_starts_with($permission->name, $module . '.');
                });
                $resolved = $resolved->merge($filtered);
            } else {
                // صلاحية محددة
                $permission = $allPermissions->firstWhere('name', $pattern);
                if ($permission) {
                    $resolved->push($permission);
                }
            }
        }

        return $resolved->unique('id')->pluck('name')->toArray();
    }

    private function getPermissionDescription(string $module, string $action): string
    {
        $moduleLabel = $this->modules[$module]['label'] ?? $module;
        $actionLabel = $this->actionLabels[$action] ?? $action;

        return "{$actionLabel} {$moduleLabel}";
    }

    private function assignRolesToExistingUsers(): void
    {
        $roleMapping = [
            'owner' => 'owner',
            'programmer' => 'programmer',
            'admin' => 'admin',
            'coach' => 'coach',
            'reception' => 'reception',
            'employee' => 'employee',
        ];

        foreach ($roleMapping as $oldRole => $newRole) {
            $users = User::where('role', $oldRole)->get();

            foreach ($users as $user) {
                $user->assignRole($newRole);
            }

            if ($users->isNotEmpty()) {
                $this->command->info("✓ تم تعيين دور '{$newRole}' لـ {$users->count()} مستخدم");
            }
        }

        $usersWithoutRole = User::doesntHave('roles')->get();
        foreach ($usersWithoutRole as $user) {
            $user->assignRole('employee');
        }

        if ($usersWithoutRole->isNotEmpty()) {
            $this->command->info("✓ تم تعيين الدور الافتراضي 'user' لـ {$usersWithoutRole->count()} مستخدم");
        }
    }
}
