<?php

namespace Ignite\Core\Listeners;

use Ignite\Core\Listeners\ThemeScaffolding\LegacyThemeScaffolder;
use Ignite\Core\Listeners\ThemeScaffolding\ModernThemeScaffolder;
use Illuminate\Filesystem\Filesystem;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class ScaffoldTheme
{
    /**
     * The code to execute when a theme has been scaffolded.
     *
     * @param InputInterface $input
     * @param OutputInterface $output
     * @param string $path
     */
    public function handle(InputInterface $input, OutputInterface $output, string $path)
    {
        $base = $input->getOption('parent') ?: 'default';
        $name = $input->getArgument('name');
        $this->resolveScaffolder()->scaffold($name, $base, $path, $output);

        $output->writeln("Updating .env files...");
        $this->updateEnvFile($name, '.env');
        $this->updateEnvFile($name, '.env.example');
    }

    /**
     * Resolve the active scaffold strategy implementation.
     * 
     * @return object
     */
    protected function resolveScaffolder()
    {
        $method = config('core.theming.scaffolding_method', 'modern');

        if ($method === 'legacy') {
            return app(LegacyThemeScaffolder::class);
        }

        return app(ModernThemeScaffolder::class);
    }

    /**
     * Update the .env file to set the theme.
     *
     * @param  string $name
     */
    protected function updateEnvFile(string $name, string $file = '.env')
    {
        $path = base_path($file);
        $filesystem = $this->files();

        if (! $filesystem->exists($path)) {
            return;
        }

        $contents = $filesystem->get($path);

        // Replace the complete setting so theme names containing hyphens do not
        // leave a suffix from the previous value in the environment file.
        $updatedContents = preg_replace('/^APP_THEME_ACTIVE=.*$/m', "APP_THEME_ACTIVE={$name}", $contents, 1);

        if (is_string($updatedContents)) {
            $filesystem->put($path, $updatedContents);
        }
    }

    /**
     * The filesystem implementation.
     *
     * @return Filesystem
     */
    protected function files(): Filesystem
    {
        return app('files');
    }
}
