<?php
/**
 * Compile SCSS assets via CLI (no HTTP-time compilation).
 *
 * @package Flowaxy\Interface\CLI\Commands
 */

declare(strict_types=1);

namespace Flowaxy\Interface\CLI\Commands;

use Flowaxy\Core\System\PathResolver;
use Flowaxy\Infrastructure\Compilers\AdminScssCompiler;
use Flowaxy\Infrastructure\Compilers\ScssCompiler;
use Flowaxy\Interface\CLI\Command;

use function basename;
use function is_dir;
use function is_file;
use function scandir;
use function str_contains;
use function str_starts_with;
use function strlen;
use function substr;
use function trim;

final class ScssCompileCommand extends Command
{
    public function getName(): string
    {
        return 'scss:compile';
    }

    public function getDescription(): string
    {
        return 'Compile SCSS to CSS for admin and/or themes';
    }

    public function getHelp(): string
    {
        return "Usage:\n"
            . "  php index.php scss:compile [--admin] [--theme=<slug>] [--all-themes] [--force]\n"
            . "\nDefaults:\n"
            . "  - If no flags provided: compiles admin SCSS only.\n";
    }

    protected function handle(array $args): int
    {
        $force = $this->hasFlag($args, '--force');
        $theme = $this->getOption($args, '--theme');
        $allThemes = $this->hasFlag($args, '--all-themes');
        $admin = $this->hasFlag($args, '--admin');

        if (!$admin && !$allThemes && $theme === null) {
            $admin = true; // default behavior
        }

        $ok = true;

        if ($admin) {
            $compiler = new AdminScssCompiler();
            $this->output('Compiling admin SCSS...');
            $res = $compiler->compile($force);
            if (!$res) {
                $this->error('Admin SCSS compilation failed. Check logs.');
                $ok = false;
            } else {
                $this->output('OK: admin CSS generated: ' . $compiler->getCssPath());
            }
        }

        if ($theme !== null) {
            $theme = trim($theme);
            if ($theme === '' || str_contains($theme, '..') || str_contains($theme, DS)) {
                $this->error('Invalid theme slug.');
                return 1;
            }
            $ok = $this->compileTheme($theme, $force) && $ok;
        }

        if ($allThemes) {
            $ok = $this->compileAllThemes($force) && $ok;
        }

        return $ok ? 0 : 1;
    }

    private function compileTheme(string $slug, bool $force): bool
    {
        $themeDir = PathResolver::themes() . DS . $slug;
        if (!is_dir($themeDir)) {
            $this->error("Theme not found: {$slug}");
            return false;
        }

        $scssMain = $themeDir . DS . 'assets' . DS . 'scss' . DS . 'main.scss';
        if (!is_file($scssMain)) {
            $this->error("Theme has no SCSS entry: {$slug} ({$scssMain})");
            return false;
        }

        $this->output("Compiling theme SCSS: {$slug}...");
        $compiler = new ScssCompiler($themeDir, 'assets/scss/main.scss', 'assets/css/style.css');

        // Force is handled by ScssCompiler internally via up-to-date check; to force we can delete output,
        // but we avoid destructive ops here. We just call compile which will rebuild when needed.
        $res = $compiler->compile('assets/scss/main.scss', 'assets/css/style.css');
        if (!$res) {
            $this->error("Theme compilation failed: {$slug} (check logs)");
            return false;
        }

        $this->output("OK: theme CSS generated: {$slug}/assets/css/style.css");
        return true;
    }

    private function compileAllThemes(bool $force): bool
    {
        $themesDir = PathResolver::themes();
        if (!is_dir($themesDir)) {
            $this->error("Themes directory not found: {$themesDir}");
            return false;
        }

        $entries = scandir($themesDir);
        if ($entries === false) {
            $this->error("Failed to read themes directory: {$themesDir}");
            return false;
        }

        $ok = true;
        foreach ($entries as $entry) {
            if ($entry === '.' || $entry === '..') {
                continue;
            }
            $dir = $themesDir . DS . $entry;
            if (!is_dir($dir)) {
                continue;
            }
            $slug = basename($dir);
            $scssMain = $dir . DS . 'assets' . DS . 'scss' . DS . 'main.scss';
            if (!is_file($scssMain)) {
                continue;
            }
            $ok = $this->compileTheme($slug, $force) && $ok;
        }

        return $ok;
    }

    /**
     * @param array<int, string> $args
     */
    private function hasFlag(array $args, string $flag): bool
    {
        foreach ($args as $arg) {
            if ($arg === $flag) {
                return true;
            }
        }
        return false;
    }

    /**
     * @param array<int, string> $args
     */
    private function getOption(array $args, string $name): ?string
    {
        foreach ($args as $arg) {
            if (str_starts_with($arg, $name . '=')) {
                return (string) substr($arg, strlen($name) + 1);
            }
        }
        return null;
    }
}
