<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

class DefaultRoleSeeder extends Seeder
{
    /** @var array<string, string> */
    private const ROLES = [
        'super-admin' => 'Super Admin',
        'administrator' => 'Administrator',
        'operations-manager' => 'Operations Manager',
        'security-manager' => 'Security Manager',
        'support-manager' => 'Support Manager',
        'finance-manager' => 'Finance Manager',
        'customer-support' => 'Customer Support',
        'auditor' => 'Auditor',
        'moderator' => 'Moderator',
        'marketing-manager' => 'Marketing Manager',
        'developer' => 'Developer',
        'api-manager' => 'API Manager',
        'read-only' => 'Read Only',
        'premium-user' => 'Premium User',
        'standard-user' => 'Standard User',
    ];

    public function run(): void
    {
        DB::table('permissions')->select(['id', 'name', 'display_name', 'uuid', 'slug', 'permission_name'])
            ->orderBy('id')
            ->each(function (object $permission): void {
                DB::table('permissions')->where('id', $permission->id)->update([
                    'uuid' => $permission->uuid ?: (string) Str::uuid(),
                    'slug' => $permission->slug ?: $permission->name,
                    'permission_name' => $permission->permission_name ?: $permission->display_name,
                ]);
            });

        foreach (self::ROLES as $name => $displayName) {
            $existing = DB::table('roles')->where('name', $name)->first();
            $values = [
                'slug' => $name,
                'display_name' => $displayName,
                'description' => $displayName.' role.',
                'is_system' => true,
                'status' => 'active',
                'updated_at' => now(),
            ];

            if ($existing === null) {
                DB::table('roles')->insert(array_merge($values, [
                    'uuid' => (string) Str::uuid(),
                    'name' => $name,
                    'created_at' => now(),
                ]));
            } else {
                DB::table('roles')->where('id', $existing->id)->update(array_merge($values, [
                    'uuid' => $existing->uuid ?: (string) Str::uuid(),
                ]));
            }
        }

        $superAdminId = DB::table('roles')->where('name', 'super-admin')->value('id');
        $permissionIds = DB::table('permissions')->pluck('id');
        foreach ($permissionIds as $permissionId) {
            DB::table('role_permission')->updateOrInsert(
                ['role_id' => $superAdminId, 'permission_id' => $permissionId],
                ['created_at' => now(), 'updated_at' => now()],
            );
        }

        $readOnlyId = DB::table('roles')->where('name', 'read-only')->value('id');
        $viewPermissionIds = DB::table('permissions')->where(function ($query): void {
            $query->where('name', 'like', '%.view')->orWhere('name', 'like', 'view.%');
        })->pluck('id');
        foreach ($viewPermissionIds as $permissionId) {
            DB::table('role_permission')->updateOrInsert(
                ['role_id' => $readOnlyId, 'permission_id' => $permissionId],
                ['created_at' => now(), 'updated_at' => now()],
            );
        }
    }
}
