/home/optimumoperation/digitalcard.optimumoperations.top/app/Console/Commands/CreatePackage.php
<?php

namespace App\Console\Commands;

use App\Models\Addon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use Illuminate\Filesystem\Filesystem;

class CreatePackage extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'package:make {name}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Create a new package with the specified folder structure';

    /**
     * Execute the console command.
     */

    protected $files;
    public $LowerName;
    public $UpperName;
    public $packageName;

    public function __construct(Filesystem $files)
    {
        parent::__construct();
        $this->files = $files;
    }

    public function handle()
    {
        $name = $this->argument('name');
        
        // Validate package name to prevent path traversal
        if (!preg_match('/^[A-Za-z][A-Za-z0-9]*$/', $name)) {
            $this->error('Invalid package name. Use only alphanumeric characters.');
            return 1;
        }
        
        $this->LowerName = strtolower($name);
        $this->UpperName = $name;
        $this->packageName = $this->camelToKebab($name);

        $packagePath = base_path("packages/workdo/{$name}");

        if (File::exists($packagePath)) {
            $this->error("Package {$name} already exists!");
            return;
        }

        File::makeDirectory($packagePath, 0755, true);

        $folders = [
            'src/database/migrations',
            'src/database/seeders',
            'src/Http/Controllers',
            'src/Models',
            'src/Providers',
            'src/resources/js/pages',
            'src/resources/js/menus',
            'src/routes',
            'src/services',
            'config'
        ];

        foreach ($folders as $folder) {
            File::makeDirectory("{$packagePath}/{$folder}", 0755, true);
        }

        $this->createStubFiles($packagePath);

        $this->createFiles();

        $addon = Addon::where('name', $this->UpperName)->first();
        if(empty($addon))
        {
            $addon = new Addon;
            $addon->name = $this->UpperName;
            $addon->slug = $this->packageName;
            $addon->monthly_price = 0;
            $addon->yearly_price = 0;
            $addon->is_enabled = 0;
            $addon->package_name = $this->UpperName;
            $addon->save();
        }


        $this->info("Package {$name} created successfully!");
    }

    protected function camelToKebab($name)
    {
        $packageName = preg_replace('/([a-z])([A-Z])/', '$1-$2', $name);
        return strtolower($packageName);
    }

    protected function getComposerJsonStub()
    {
        $name = "workdo/{$this->packageName}";
        $description = "Description for {$this->packageName} package";
        $namespace = "Workdo\\\\{$this->UpperName}\\\\Providers\\\\{$this->UpperName}ServiceProvider";

        return <<<EOT
        {
            "name": "{$name}",
            "description": "{$description}",
            "type": "library",
            "license": "MIT",
            "require": {},
            "autoload": {
                "psr-4": {
                    "Workdo\\\\{$this->UpperName}\\\\": "src/"
                }
            },
            "authors": [
                {
                    "name": "WorkDo",
                    "email": "support@workdo.io"
                }
            ],
            "extra": {
                "laravel": {
                    "providers": [
                        "{$namespace}"
                    ]
                }
            }
        }
        EOT;
    }

    protected function getModuleJsonStub()
    {
        return <<<EOT
        {
            "name": "{$this->UpperName}",
            "alias": "{$this->packageName}",
            "description": "",
            "priority": 0,
            "version":"1.0",
            "monthly_price": 0,
            "yearly_price": 0,
            "package_name":"{$this->UpperName}"
        }
        EOT;
    }

    protected function createStubFiles($packagePath)
    {
        $composerJson = $this->getComposerJsonStub();
        $this->files->put($packagePath . "/composer.json", $composerJson);

        $moduleJson = $this->getModuleJsonStub();
        $this->files->put($packagePath . "/module.json", $moduleJson);

        $serviceProviderStub = $this->getServiceProviderStub();
        $this->files->put($packagePath . "/src/Providers/{$this->UpperName}ServiceProvider.php", $serviceProviderStub);

        $seederStub = $this->getSeederStub();
        $this->files->put($packagePath."/src/database/seeders/{$this->UpperName}DatabaseSeeder.php",$seederStub);
    }

    protected function createFiles()
    {
        $files = [
            'routes/web.stub' => 'src/routes/web.php',
            'seeders/PermissionTableSeeder.stub' => 'src/database/seeders/PermissionTableSeeder.php',
            'controller.stub' => 'src/Http/Controllers/{$this->UpperName}Controller.php',
            'resources/js/pages/index.tsx.stub' => 'src/resources/js/pages/index.tsx',
            'resources/js/pages/create.tsx.stub' => 'src/resources/js/pages/create.tsx',
            'resources/js/pages/edit.tsx.stub' => 'src/resources/js/pages/edit.tsx',
            'resources/js/menus/company-menu.ts.stub' => 'src/resources/js/menus/company-menu.ts',
            'resources/js/menus/superadmin-menu.ts.stub' => 'src/resources/js/menus/superadmin-menu.ts'
        ];

        foreach ($files as $stubFile => $phpFile) {
            $stubPath = base_path('stubs/workdo-stubs/'.$stubFile);
            
            if (!File::exists($stubPath)) {
                $this->warn("Stub file not found: {$stubFile}");
                continue;
            }
            
            $stub = File::get($stubPath);

            $stub = str_replace(
                ['$STUDLY_NAME$', '$LOWER_NAME$', '$PACKAGE_NAME$'],
                [$this->UpperName, $this->LowerName, $this->packageName],
                $stub
            );

            $phpFile = str_replace('{$this->UpperName}', $this->UpperName, $phpFile);
            $filePath = base_path("packages/workdo/{$this->UpperName}/".$phpFile);

            if (!File::exists(dirname($filePath))) {
                File::makeDirectory(dirname($filePath), 0755, true);
            }
            $this->files->put($filePath, $stub);
        }
    }

    protected function getServiceProviderStub()
    {
        return <<<EOT
        <?php

        namespace Workdo\\{$this->UpperName}\\Providers;

        use Illuminate\Support\ServiceProvider;

        class {$this->UpperName}ServiceProvider extends ServiceProvider
        {
            protected \$moduleName = '{$this->UpperName}';
            protected \$moduleNameLower = '{$this->LowerName}';

            public function register()
            {
                //
            }

            public function boot()
            {
                \$this->loadRoutesFrom(__DIR__ . '/../routes/web.php');
                \$this->loadMigrationsFrom(__DIR__ . '/../database/migrations');
            }
        }
        EOT;
    }

    protected function getSeederStub()
    {
        return <<<EOT
        <?php

        namespace Workdo\\{$this->UpperName}\\database\seeders;

        use Illuminate\Database\Seeder;
        use Illuminate\Database\Eloquent\Model;

        class {$this->UpperName}DatabaseSeeder extends Seeder
        {
            /**
             * Run the database seeds.
             *
             * @return void
             */
            public function run()
            {
                Model::unguard();

                \$this->call(PermissionTableSeeder::class);
            }
        }
        EOT;
    }
}