<?php

namespace Maestro\Core\Console\Commands;

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

class CoreInstallCommand extends Command
{
    protected $signature = 'core:install';

    protected $description = 'Publish Maestro CORE stubs and merge Composer / npm registry configuration';

    private const SATIS_URL = 'https://maestro-package.on-forge.com';

    private const VERDACCIO_SCOPE_REGISTRY = 'https://maestro-npm.on-forge.com';

    public function handle(): int
    {
        $this->call('vendor:publish', ['--tag' => 'core-config', '--force' => false]);
        $this->call('vendor:publish', ['--tag' => 'core-stubs', '--force' => false]);

        $this->mergeComposerRepositories();
        $this->ensureComposerRequire();
        $this->mergePackageJsonDependencies();
        $this->ensureNpmrc();

        $this->newLine();
        $this->info('Maestro CORE scaffolding updated.');
        $this->newLine();
        $this->line('Next steps:');
        $this->line('  1. php artisan migrate');
        $this->line('  2. npm install');
        $this->line('  3. npm run build');

        return self::SUCCESS;
    }

    private function mergeComposerRepositories(): void
    {
        $path = base_path('composer.json');
        if (! File::exists($path)) {
            return;
        }

        $data = json_decode(File::get($path), true);
        if (! is_array($data)) {
            return;
        }

        $repos = $data['repositories'] ?? [];
        $repos = is_array($repos) ? $repos : [];

        $exists = false;
        foreach ($repos as $repo) {
            if (($repo['url'] ?? '') === self::SATIS_URL) {
                $exists = true;
                break;
            }
        }

        if (! $exists) {
            $repos[] = ['type' => 'composer', 'url' => self::SATIS_URL];
            $data['repositories'] = $repos;
            File::put($path, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES).PHP_EOL);
            $this->info('Added Satis repository to composer.json: '.self::SATIS_URL);
        }
    }

    private function ensureComposerRequire(): void
    {
        $path = base_path('composer.json');
        if (! File::exists($path)) {
            return;
        }

        $data = json_decode(File::get($path), true);
        if (! is_array($data)) {
            return;
        }

        $require = $data['require'] ?? [];
        $require = is_array($require) ? $require : [];

        if (! isset($require['maestro/core'])) {
            $require['maestro/core'] = '^1.0';
            $data['require'] = $require;
            File::put($path, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES).PHP_EOL);
            $this->warn('Added maestro/core to composer.json require — run: composer update maestro/core');
        }
    }

    private function mergePackageJsonDependencies(): void
    {
        $path = base_path('package.json');
        if (! File::exists($path)) {
            return;
        }

        $data = json_decode(File::get($path), true);
        if (! is_array($data)) {
            return;
        }

        $deps = $data['dependencies'] ?? [];
        $deps = is_array($deps) ? $deps : [];

        if (! isset($deps['@maestro/core'])) {
            $deps['@maestro/core'] = '^1.0.0';
            ksort($deps);
            $data['dependencies'] = $deps;
            File::put($path, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES).PHP_EOL);
            $this->warn('Added @maestro/core to package.json — run: npm install');
        }
    }

    private function ensureNpmrc(): void
    {
        $path = base_path('.npmrc');
        $line = '@maestro:registry='.self::VERDACCIO_SCOPE_REGISTRY.'/';

        if (File::exists($path)) {
            $contents = File::get($path);
            if (str_contains($contents, '@maestro:registry=')) {
                return;
            }
            File::append($path, PHP_EOL.$line.PHP_EOL);
            $this->info('Appended @maestro registry line to .npmrc');

            return;
        }

        File::put($path, $line.PHP_EOL);
        $this->info('Created .npmrc with Verdaccio scope for @maestro');
    }
}
