<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;

class MakeModuleFile extends Command
{
    protected $signature = 'make:module-file
                            {type : File type (controller, request, resource, event, migration, model, policy, service, provider)}
                            {name : File name}
                            {--module= : Module name}';
                            
    protected $description = 'Create a specified file type in a module';

    public function handle()
    {
        $type = strtolower($this->argument('type'));
        $name = $this->argument('name');
        $moduleName = $this->option('module');

        if (!$moduleName) {
            $this->error('You must specify a module using --module option.');
            return 1;
        }

        $modulePath = app_path("Modules/{$moduleName}");

        if (!File::exists($modulePath)) {
            $this->error("Module {$moduleName} does not exist.");
            return 1;
        }

        $typesMap = [
            'controller' => ['Http/Controllers', 'Controller', 'extends Controller'],
            'request' => ['Http/Requests', 'Request', 'extends FormRequest'],
            'resource' => ['Http/Resources', 'Resource', 'extends JsonResource'],
            'event' => ['Events', 'Event', ''],
            'migration' => ['database/migrations', '', '', true],
            'model' => ['Models', 'Model', 'extends Model'],
            'policy' => ['Policies', 'Policy', ''],
            'service' => ['Services', 'Service', ''],
            'provider' => ['Providers', 'ServiceProvider', 'extends ServiceProvider'],
        ];

        if (!array_key_exists($type, $typesMap)) {
            $this->error("Invalid type: {$type}. Allowed types: " . implode(', ', array_keys($typesMap)));
            return 1;
        }

        [$path, $suffix, $extends, $isMigration] = array_merge($typesMap[$type], [false]);

        if ($isMigration) {
            $timestamp = now()->format('Y_m_d_His');
            $fileName = "{$timestamp}_{$name}.php";
        } else {
            $fileName = Str::studly($name) . ($suffix ? "{$suffix}.php" : ".php");
        }

        $filePath = "{$modulePath}/{$path}/{$fileName}";
        $namespace = "App\\Modules\\{$moduleName}\\" . str_replace('/', '\\', $path);
        $className = Str::studly($name) . ($suffix !== '' ? $suffix : '');

        if (File::exists($filePath)) {
            $this->error("The {$type} {$name} already exists in module {$moduleName}.");
            return 1;
        }

        $stub = $isMigration ? $this->migrationStub($name) : $this->defaultStub($namespace, $className, $extends);

        File::ensureDirectoryExists("{$modulePath}/{$path}");
        File::put($filePath, $stub);

        $this->info("{$type} {$name} created successfully in module {$moduleName}!");

        return 0;
    }

    protected function defaultStub($namespace, $className, $extends)
    {
        return "<?php\n\nnamespace {$namespace};\n\n" .
               ($extends ? "use Illuminate\Foundation\Http\FormRequest;\n\n" : "") .
               "class {$className} {$extends}\n{\n    // Your code here\n}\n";
    }

    protected function migrationStub($name)
    {
        $tableName = Str::snake($name);

        return "<?php\n\n" .
               "use Illuminate\Database\Migrations\Migration;\n" .
               "use Illuminate\Database\Schema\Blueprint;\n" .
               "use Illuminate\Support\Facades\Schema;\n\n" .
               "return new class extends Migration\n{\n" .
               "    /**\n" .
               "     * Run the migrations.\n" .
               "     */\n" .
               "    public function up(): void\n" .
               "    {\n" .
               "        Schema::create('{$tableName}', function (Blueprint \$table) {\n" .
               "            \$table->id();\n" .
               "            \$table->timestamps();\n" .
               "        });\n" .
               "    }\n\n" .
               "    /**\n" .
               "     * Reverse the migrations.\n" .
               "     */\n" .
               "    public function down(): void\n" .
               "    {\n" .
               "        Schema::dropIfExists('{$tableName}');\n" .
               "    }\n" .
               "};\n";
    }
}
