<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;

/**
 * PermissionPatchSeeder
 *
 * Applies targeted permission fixes to an existing live database.
 * Safe to run multiple times — uses firstOrCreate / givePermissionTo (idempotent).
 *
 * Run with:
 *   php artisan db:seed --class=PermissionPatchSeeder
 *
 * Fixes applied:
 *  1. Removes orphaned `manage chat agents` and `view chat conversations` permissions.
 *  2. Ensures `manage what we do images` is assigned to Super Manager and Manager.
 *  3. Ensures chat permissions are assigned to Super Manager and Manager.
 *  4. Fixes Health Marketor role missing Research / Advocacy / Partnership permissions.
 *  5. Ensures `manage pages` is assigned to Super Manager and Manager.
 *  6. Ensures `manage themes` is assigned to Super Manager.
 *  7. Ensures `view statistics` is assigned to Manager and Super Manager.
 *  8. Ensures `access admin panel` is assigned to Super Manager and Manager.
 *  9. Ensures all loan module permissions exist and are correctly assigned per role.
 * 10. Super Manager catch-all: assigns every permission that exists in the DB.
 */
class PermissionPatchSeeder extends Seeder
{
    public function run(): void
    {
        app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();

        // ----------------------------------------------------------------
        // 1. Remove orphaned permissions that are not used by any controller
        // ----------------------------------------------------------------
        foreach (['manage chat agents', 'view chat conversations'] as $name) {
            $perm = Permission::where('name', $name)->first();
            if ($perm) {
                $perm->roles()->detach();
                $perm->delete();
                $this->command->info("Deleted orphaned permission: {$name}");
            }
        }

        // ----------------------------------------------------------------
        // 2. Ensure `manage what we do images` exists and is assigned
        // ----------------------------------------------------------------
        Permission::firstOrCreate(['name' => 'manage what we do images', 'guard_name' => 'web']);

        foreach (['Super Manager', 'Manager'] as $roleName) {
            $role = Role::where('name', $roleName)->first();
            if ($role) {
                $role->givePermissionTo('manage what we do images');
                $this->command->info("{$roleName}: manage what we do images ✓");
            }
        }

        // ----------------------------------------------------------------
        // 3. Ensure chat permissions exist and are assigned to Super Manager + Manager
        // ----------------------------------------------------------------
        $chatPermissions = [
            'view chats',
            'handle chats',
            'manage chat categories',
            'appoint chat agents',
            'view chat statistics',
        ];

        foreach ($chatPermissions as $permName) {
            Permission::firstOrCreate(['name' => $permName, 'guard_name' => 'web']);
        }

        foreach (['Super Manager', 'Manager'] as $roleName) {
            $role = Role::where('name', $roleName)->first();
            if ($role) {
                $role->givePermissionTo($chatPermissions);
                $this->command->info("{$roleName}: chat permissions ✓");
            }
        }

        // ----------------------------------------------------------------
        // 4. Fix Health Marketor Research / Advocacy / Partnership permissions
        // ----------------------------------------------------------------
        $healthMarketor = Role::where('name', 'Health Marketor')->first();
        if ($healthMarketor) {
            $healthMarketorPermissions = [
                'view publications',
                'view featured publications',
                'view campaigns',
                'create campaigns',
                'edit campaigns',
                'manage campaigns',
                'feature campaigns',
                'view stories',
                'create stories',
                'edit stories',
                'moderate stories',
                'approve stories',
                'reject stories',
                'feature stories',
                'view polls',
                'create polls',
                'edit polls',
                'delete polls',
                'manage polls',
                'view poll results',
                'close polls',
                'view advocacy analytics',
                'export advocacy reports',
                'view partners',
                'view partnerships',
            ];

            $existing = Permission::whereIn('name', $healthMarketorPermissions)
                ->pluck('name')
                ->toArray();

            if (!empty($existing)) {
                $healthMarketor->givePermissionTo($existing);
                $this->command->info('Health Marketor: ' . count($existing) . ' R-module permissions ✓');
            }
        }

        // ----------------------------------------------------------------
        // 5. Ensure `manage pages` is assigned to Super Manager and Manager
        // ----------------------------------------------------------------
        Permission::firstOrCreate(['name' => 'manage pages', 'guard_name' => 'web']);

        foreach (['Super Manager', 'Manager'] as $roleName) {
            $role = Role::where('name', $roleName)->first();
            if ($role) {
                $role->givePermissionTo('manage pages');
                $this->command->info("{$roleName}: manage pages ✓");
            }
        }

        // ----------------------------------------------------------------
        // 6. Ensure `manage themes` exists and is assigned to Super Manager only
        // ----------------------------------------------------------------
        Permission::firstOrCreate(['name' => 'manage themes', 'guard_name' => 'web']);

        $superManager = Role::where('name', 'Super Manager')->first();
        if ($superManager) {
            $superManager->givePermissionTo('manage themes');
            $this->command->info('Super Manager: manage themes ✓');
        }

        // ----------------------------------------------------------------
        // 7. Ensure `view statistics` is assigned to Manager and Super Manager
        //    (required for stats rows in admin institution/machine views)
        // ----------------------------------------------------------------
        Permission::firstOrCreate(['name' => 'view statistics', 'guard_name' => 'web']);

        foreach (['Super Manager', 'Manager'] as $roleName) {
            $role = Role::where('name', $roleName)->first();
            if ($role) {
                $role->givePermissionTo('view statistics');
                $this->command->info("{$roleName}: view statistics ✓");
            }
        }

        // ----------------------------------------------------------------
        // 8. Ensure `access admin panel` exists and is assigned to Super Manager + Manager
        // ----------------------------------------------------------------
        Permission::firstOrCreate(['name' => 'access admin panel', 'guard_name' => 'web']);

        foreach (['Super Manager', 'Manager'] as $roleName) {
            $role = Role::where('name', $roleName)->first();
            if ($role) {
                $role->givePermissionTo('access admin panel');
                $this->command->info("{$roleName}: access admin panel ✓");
            }
        }

        // ----------------------------------------------------------------
        // 9. Ensure all loan module permissions exist and are correctly assigned
        //     Manager: can view/approve/reject/verify but NOT disburse
        //     Super Manager: all loan permissions (covered by catch-all, but explicit here)
        //     Members: view loan products only (they use member portal, not admin)
        // ----------------------------------------------------------------
        $loanPermissions = [
            'view loan products',
            'create loan products',
            'edit loan products',
            'delete loan products',
            'view loan applications',
            'approve loan applications',
            'reject loan applications',
            'disburse loans',
            'verify loan documents',
        ];

        foreach ($loanPermissions as $permName) {
            Permission::firstOrCreate(['name' => $permName, 'guard_name' => 'web']);
        }

        // Manager gets all loan permissions except delete loan products and disburse loans
        $managerLoanPermissions = [
            'view loan products',
            'create loan products',
            'edit loan products',
            'view loan applications',
            'approve loan applications',
            'reject loan applications',
            'verify loan documents',
        ];

        $managerRole = Role::where('name', 'Manager')->first();
        if ($managerRole) {
            $managerRole->givePermissionTo($managerLoanPermissions);
            // Explicitly revoke disburse loans from Manager — only Super Manager should disburse
            $disbursePerm = Permission::where('name', 'disburse loans')->first();
            if ($disbursePerm && $managerRole->hasPermissionTo('disburse loans')) {
                $managerRole->revokePermissionTo($disbursePerm);
                $this->command->info('Manager: disburse loans revoked (Super Manager only) ✓');
            }
            $this->command->info('Manager: loan permissions ✓');
        }

        // Members role: view loan products only (member portal uses its own auth)
        $membersRole = Role::where('name', 'Members')->first();
        if ($membersRole) {
            $membersRole->givePermissionTo('view loan products');
            $this->command->info('Members: view loan products ✓');
        }

        // Contributor role: view loan products
        $contributorRole = Role::where('name', 'Contributor')->first();
        if ($contributorRole) {
            $contributorRole->givePermissionTo('view loan products');
            $this->command->info('Contributor: view loan products ✓');
        }

        $this->command->info('Loan module permissions patched ✓');

        // ----------------------------------------------------------------
        // 10. Super Manager catch-all: ensure it has EVERY permission in the DB
        //    This is the final safety net — runs last so it captures everything
        //    created by all other seeders in this session.
        // ----------------------------------------------------------------
        $superManager = Role::where('name', 'Super Manager')->first();
        if ($superManager) {
            $superManager->givePermissionTo(Permission::all());
            $this->command->info('Super Manager: all permissions synced (catch-all) ✓');
        }

        // ----------------------------------------------------------------
        // 11. Ensure `assign roles` permission exists (used in sidebar check)
        //     Only Super Manager should have this permission.
        // ----------------------------------------------------------------
        Permission::firstOrCreate(['name' => 'assign roles', 'guard_name' => 'web']);

        $superManager = Role::where('name', 'Super Manager')->first();
        if ($superManager) {
            $superManager->givePermissionTo('assign roles');
            $this->command->info('Super Manager: assign roles ✓');
        }

        // ----------------------------------------------------------------
        // Done
        // ----------------------------------------------------------------
        app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();

        $this->command->newLine();
        $this->command->info('PermissionPatchSeeder completed successfully.');
        $this->command->info('Run `php artisan cache:clear` if you use a persistent cache driver.');
    }
}
