<?php

declare(strict_types=1);

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Arr;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;

class DberpI18nAuditCommand extends Command
{
    protected $signature = 'dberp:i18n-audit
                            {--locale=zh_CN : 对照的 dberp 语种目录（如 zh_CN、en）}
                            {--json : 以 JSON 输出结果（便于 CI）}';

    protected $description = '校验 app/ 与 resources/views 中出现的 dberp.* 翻译键是否存在于指定语种的 dberp.php 中';

    public function handle(): int
    {
        $locale = (string) $this->option('locale');
        $path = lang_path($locale.'/dberp.php');

        if (! is_file($path)) {
            $this->error("Missing translation file: {$path}");

            return self::FAILURE;
        }

        /** @var array<string, mixed> $definitions */
        $definitions = require $path;

        $usedKeys = $this->collectUsedDberpKeys();

        $missing = [];
        foreach ($usedKeys as $key) {
            if (! Arr::has($definitions, $key)) {
                $missing[] = $key;
            }
        }

        sort($missing);

        if ($this->option('json')) {
            $this->line((string) json_encode([
                'locale' => $locale,
                'used_key_count' => count($usedKeys),
                'missing' => array_values($missing),
            ], JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));

            return $missing === [] ? self::SUCCESS : self::FAILURE;
        }

        $this->info('DBErp i18n audit (dberp.* keys)');
        $this->line("Locale file: {$path}");
        $this->line('Distinct keys referenced in code: '.count($usedKeys));

        if ($missing === []) {
            $this->info('All referenced keys exist.');

            return self::SUCCESS;
        }

        $this->error('Missing '.count($missing).' key(s):');
        foreach ($missing as $key) {
            $this->line(" - {$key}");
        }

        return self::FAILURE;
    }

    /**
     * @return list<string>
     */
    private function collectUsedDberpKeys(): array
    {
        $finder = Finder::create()
            ->files()
            ->in([app_path(), resource_path('views')])
            ->name(['*.php', '*.blade.php']);

        $patterns = [
            '/(?:__|trans)\(\s*[\'"]dberp\.([a-zA-Z0-9_.-]+)[\'"]/',
            '/@lang\(\s*[\'"]dberp\.([a-zA-Z0-9_.-]+)[\'"]/',
        ];

        $keys = [];
        foreach ($finder as $file) {
            $content = $this->readFileContent($file);
            if ($content === null) {
                continue;
            }

            foreach ($patterns as $pattern) {
                if (preg_match_all($pattern, $content, $matches) === 0) {
                    continue;
                }

                foreach ($matches[1] as $key) {
                    if (! is_string($key) || $key === '') {
                        continue;
                    }

                    if (str_ends_with($key, '.') || str_ends_with($key, '_')) {
                        // 跳过形如 __('dberp.foo.'.$bar) 或 __('dberp.errors.'.$code) 的拼接键，无法静态校验。
                        continue;
                    }

                    $keys[$key] = true;
                }
            }
        }

        $list = array_keys($keys);
        sort($list);

        return $list;
    }

    private function readFileContent(SplFileInfo $file): ?string
    {
        $realPath = $file->getRealPath();
        if ($realPath === false) {
            return null;
        }

        $content = file_get_contents($realPath);

        return is_string($content) ? $content : null;
    }
}
