<?php

namespace Database\Seeders;

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

class PermissionSeeder extends Seeder
{
    protected function removedPreviousPermissions()
    {
        $tableNames = config('permission.table_names');
        DB::table($tableNames['permissions'])->delete();
        DB::table($tableNames['role_has_permissions'])->delete();
        DB::table($tableNames['roles'])->delete();
        DB::table($tableNames['model_has_permissions'])->delete();

        return $this;
    }
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        // Define routes to be excluded (unnecessary routes)
        $excludedRoutes = [
            'home',
            'change-language',
            'login',
            'logout',
            'register',
            'password.confirm',
            'password.email',
            'password.request',
            'password.reset',
            'password.update',
            'sanctum.csrf-cookie',
            'livewire.preview-file',
            'livewire.update',
            'livewire.upload-file',
            'users.setting',
            'users.change-password',
            'users.update-user-status',
            'role.get-permissions',
            'ignition.executeSolution',
            'ignition.healthCheck',
            'ignition.updateConfig',
            'api.user',
            'livewire.livewire',
            'livewire.livewire.min.js.map',
        ];

        $this->removedPreviousPermissions();
        $routes = Route::getRoutes();
        $permissions = [];

        // Storage for processed resource routes
        $resourcePermissions = [];

        foreach ($routes as $route) {
            $action = $route->getAction();
            if (!isset($action['as'])) {
                continue;
            }

            $routeName = $action['as'];

            // Skip excluded routes
            if (in_array($routeName, $excludedRoutes)) {
                continue;
            }
            if (str_ends_with($routeName, 'dataTable')) {
                continue;
            }
            $routeName = str_replace('-', '_', $routeName);
            // Extract the main resource name (e.g., users.store → users)
            $segments = explode('.', $routeName);
            $resource = $segments[0];

            // Check if the route is a resource route
            if (count($segments) > 1) {
                $operation = end($segments);

                // Define common CRUD names
                $crudMap = [
                    'index' => 'read',
                    'show' => 'read',
                    'create' => 'create',
                    'store' => 'create',
                    'edit' => 'edit',
                    'update' => 'edit',
                    'destroy' => 'delete',
                ];

                // Check if it's a CRUD operation and rename accordingly
                if (isset($crudMap[$operation])) {
                    $operation = $crudMap[$operation];
                }

                // Group permissions under resource.* format
                $resourcePermissions[$resource][] = [
                    'name' => "{$resource}.{$operation}",
                    'guard_name' => 'web',
                ];
            } else {
                // Single routes should be stored under users.route_name
                $permissions[] = [
                    'name' => "users.{$routeName}",
                    'guard_name' => 'web',
                ];
            }
        }

        // Add wildcard permission for each resource
        foreach ($resourcePermissions as $resource => $perms) {
            array_unshift($perms, ['name' => "{$resource}.*", 'guard_name' => 'web']);
            $permissions = array_merge($permissions, $perms);
        }

        // Remove duplicates (if any)
        $permissions = array_unique($permissions, SORT_REGULAR);

        // Insert into the database
        DB::table('permissions')->insert($permissions);

        $role = Role::create(['name' => 'Super Admin', 'guard_name' => 'web']);
        $permissions = Permission::get();
        foreach ($permissions as $permission) {
            $role->givePermissionTo($permission->name);
        }
        $user = User::first();
        $user->assignRole($role->name);
    }
}
