<?php

namespace App\Console\Commands;

use App\Workflows\Models\StepTemplate;
use Illuminate\Console\Command;
use Spatie\Permission\Models\Permission;

class EnsureWorkflowPermissions extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'workflow:ensure-permissions 
                            {--dry-run : Show what permissions would be created without making changes}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Ensure all workflow step permissions exist with stable naming (for fresh systems)';

    /**
     * Execute the console command.
     */
    public function handle(): int
    {
        $this->info('🔄 Ensuring workflow step permissions exist...');

        if ($this->option('dry-run')) {
            $this->warn('DRY RUN MODE - No changes will be made');
        }

        try {
            // Get all step templates from published workflows
            $stepTemplates = StepTemplate::with(['workflowTemplate'])
                ->whereHas('workflowTemplate', function ($query) {
                    $query->where('status', 'published')
                        ->where('is_active', true);
                })
                ->get();

            if ($stepTemplates->isEmpty()) {
                $this->info('ℹ️  No published workflows found. Permissions will be created when workflows are published.');

                return Command::SUCCESS;
            }

            $createdPermissions = [];
            $existingPermissions = [];

            foreach ($stepTemplates as $stepTemplate) {
                $permissionName = $stepTemplate->getPermissionName();
                $permissionLabel = $stepTemplate->getPermissionLabel();

                if ($this->option('dry-run')) {
                    $this->line("  Would ensure permission: {$permissionName}");

                    continue;
                }

                // Check if permission already exists
                $permission = Permission::where('name', $permissionName)->first();

                if (! $permission) {
                    // Create the permission
                    Permission::create([
                        'name' => $permissionName,
                        'guard_name' => 'web', // Default guard
                    ]);
                    $createdPermissions[] = [
                        'name' => $permissionName,
                        'label' => $permissionLabel,
                    ];
                } else {
                    $existingPermissions[] = [
                        'name' => $permissionName,
                        'label' => $permissionLabel,
                    ];
                }
            }

            // Display results
            if ($this->option('dry-run')) {
                $this->info('✅ Dry run completed. Check output above for what would be created.');
            } else {
                if (! empty($createdPermissions)) {
                    $this->info('✅ Created '.count($createdPermissions).' new permissions:');
                    foreach ($createdPermissions as $perm) {
                        $this->line("  • {$perm['name']} ({$perm['label']})");
                    }
                }

                if (! empty($existingPermissions)) {
                    $this->info('ℹ️  '.count($existingPermissions).' permissions already existed:');
                    foreach ($existingPermissions as $perm) {
                        $this->line("  • {$perm['name']} ({$perm['label']})");
                    }
                }

                if (empty($createdPermissions) && empty($existingPermissions)) {
                    $this->info('ℹ️  No permissions to create.');
                }
            }

            $this->newLine();
            $this->info('🎉 Permission check completed successfully!');

            return Command::SUCCESS;
        } catch (\Exception $e) {
            $this->error('❌ Permission check failed: '.$e->getMessage());

            return Command::FAILURE;
        }
    }
}
