<?php

namespace App\Commands;

use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Str;

class CreateCrud extends Command
{
    protected $signature = 'create:crud
                            {name : The name of the model}
                            {--m|model : Create only the Model}
                            {--s|service : Create only the Service}
                            {--c|controller : Create only the Controller}
                            {--r|request : Create only the Request}
                            {--e|resource : Create only the Resource}
                            {--t|route : Create only the Route}
                            {--g|migration : Create only the Migration}
                            {--all : Create all files (default behavior)}';

    protected $description = 'Create CRUD operations with typed Models (use options to create specific files)';

    protected $files;

    public function __construct(Filesystem $files)
    {
        parent::__construct();

        $this->files = $files;
    }

    //

    public function handle(): void
    {
        $name = Str::studly($this->argument('name'));

        $hasSpecificOption = $this->option('model') ||
            $this->option('service') ||
            $this->option('controller') ||
            $this->option('request') ||
            $this->option('resource') ||
            $this->option('route') ||
            $this->option('migration');

        $createAll = ! $hasSpecificOption || $this->option('all');

        $this->info("Creating CRUD for: {$name}");
        $this->newLine();

        if ($createAll || $this->option('model')) {
            $this->createModel($name);
        }

        if ($createAll || $this->option('service')) {
            $this->createService($name);
        }

        if ($createAll || $this->option('controller')) {
            $this->createController($name);
        }

        if ($createAll || $this->option('request')) {
            $this->createRequest($name);
        }

        if ($createAll || $this->option('resource')) {
            $this->createResource($name);
        }

        if ($createAll || $this->option('route')) {
            $this->createRoute($name);
        }

        if ($createAll || $this->option('migration')) {
            $this->createMigration($name);
        }

        $this->newLine();
        $this->info('✓ CRUD operations created successfully!');

        if ($createAll) {
            $this->newLine();
            $this->info('Next steps:');

            $this->info(
                "1. Update the migration: database/migrations/*_create_{$this->getTableName(
                    $name,
                )}_table.php",
            );

            $this->info(
                "2. Update the model properties in: app/Models/{$name}.php",
            );

            $this->info(
                "3. Update validation rules in: app/Http/Requests/{$name}Request.php",
            );

            $this->info(
                "4. Update resource fields in: app/Http/Resources/{$name}Resource.php",
            );

            $this->info('5. Run: php artisan migrate');
            $this->info('6. Run: php artisan ide-helper:models -RW');
        }
    }

    //

    protected function createController(string $name): void
    {
        $controllerTemplate = str_replace(
            ['{{modelName}}'],
            [$name],
            $this->getStub('Controller'),
        );

        $this->put(
            "app/Http/Controllers/{$name}Controller.php",
            $controllerTemplate,
        );

        $this->info(
            "✓ Created Controller: app/Http/Controllers/{$name}Controller.php",
        );
    }

    protected function createMigration(string $name): void
    {
        $tableName = $this->getTableName($name);

        $migrationTemplate = str_replace(
            ['{{tableNameSnakeCase}}'],
            [$tableName],
            $this->getStub('Migration'),
        );

        $timestamp = date('Y_m_d_His');
        $filename  = $timestamp."_create_{$tableName}_table.php";

        $this->put(database_path("migrations/{$filename}"), $migrationTemplate);
        $this->info("✓ Created Migration: database/migrations/{$filename}");
    }

    protected function createModel(string $name): void
    {
        $modelTemplate = str_replace(
            ['{{modelName}}', '{{tableNameSnakeCase}}'],
            [$name, $this->getTableName($name)],
            $this->getStub('Model'),
        );

        $this->put("app/Models/{$name}.php", $modelTemplate);
        $this->info("✓ Created Model: app/Models/{$name}.php");
    }

    protected function createRequest(string $name): void
    {
        $requestTemplate = str_replace(
            ['{{modelName}}'],
            [$name],
            $this->getStub('Request'),
        );

        $this->put("app/Http/Requests/{$name}Request.php", $requestTemplate);
        $this->info("✓ Created Request: app/Http/Requests/{$name}Request.php");
    }

    protected function createResource(string $name): void
    {
        $resourceTemplate = str_replace(
            ['{{modelName}}'],
            [$name],
            $this->getStub('Resource'),
        );

        $this->put("app/Http/Resources/{$name}Resource.php", $resourceTemplate);

        $this->info(
            "✓ Created Resource: app/Http/Resources/{$name}Resource.php",
        );
    }

    protected function createRoute(string $name): void
    {
        $routeTemplate = str_replace(
            ['{{modelName}}', '{{modelNameSnakeCase}}'],
            [$name, Str::snake($name, '-')],
            $this->getStub('Route'),
        );

        $routePath = base_path(
            'routes/authRoutes/'.Str::snake($name).'.php',
        );

        if (! $this->files->isDirectory(base_path('routes/authRoutes'))) {
            $this->files->makeDirectory(
                base_path('routes/authRoutes'),
                0755,
                true,
            );
        }

        $this->put($routePath, $routeTemplate);

        $this->info(
            '✓ Created Route: routes/authRoutes/'.Str::snake($name).'.php',
        );
    }

    protected function createService(string $name): void
    {
        $serviceTemplate = str_replace(
            ['{{modelName}}'],
            [$name],
            $this->getStub('Service'),
        );

        $this->put("app/Services/{$name}Service.php", $serviceTemplate);
        $this->info("✓ Created Service: app/Services/{$name}Service.php");
    }

    //

    protected function getStub(string $type): string
    {
        return $this->files->get(storage_path("stubs/{$type}.stub"));
    }

    protected function getTableName(string $name): string
    {
        return Str::snake(Str::plural($name));
    }

    protected function put(string $path, string $contents): void
    {
        $this->files->put($path, $contents);
    }
}
