import path from 'node:path';
import { ExitCode, processPatternList, sair } from '../helpers/index.js';
import { configurarFiltros } from '../processing/index.js';
import { chalk, config } from '../../core/config/index.js';
import { scanRepository } from '../../core/execution/index.js';
import { getMessages } from '../../core/messages/index.js';
import { formatarComPrettierProjeto, formatarPrettierMinimo } from '../../shared/formatters/index.js';
import { salvarEstado } from '../../shared/persistence/index.js';
import { Command } from 'commander';
import micromatch from 'micromatch';
const { log, CliFormatarExtraMensagens } = getMessages();
function isFormatavel(relPath) {
    const basename = relPath.split('/').pop()?.toLowerCase() || '';
    const arquivosIgnorados = ['third-party-notices.txt', 'avisos-de-terceiros.pt-br.txt'];
    if (arquivosIgnorados.includes(basename))
        return false;
    return /\.(json[c5]?|md|markdown|ya?ml|ts|tsx|js|jsx|mjs|cjs|html?|css|py|xml|php|toml|ini|sql|dockerfile|sh|bash|properties|txt|log|lock|env|gradle|svg|scss|less|go)$/i.test(relPath) || /^(\.gitignore|\.editorconfig|\.npmrc|\.nvmrc)$/i.test(basename);
}
function detectaNodeModulesExplicito(includeGroups, includeFlat) {
    const all = [...includeFlat, ...includeGroups.flat()];
    return all.some(caminho => /(^|\/)node_modules(\/|$)/.test(String(caminho || '')));
}
async function formatarComEngine(src, relPath, baseDir, engine) {
    if (engine === 'auto') {
        const raiz = await formatarComPrettierProjeto({ code: src, relPath, baseDir });
        if (!raiz.ok)
            return raiz;
        if (raiz.parser !== 'unknown')
            return raiz;
        return formatarPrettierMinimo({ code: src, relPath });
    }
    if (engine === 'interno') {
        return formatarPrettierMinimo({ code: src, relPath });
    }
    return formatarComPrettierProjeto({ code: src, relPath, baseDir });
}
export function comandoFormatar(aplicarFlagsGlobais) {
    return new Command('formatar').description(CliFormatarExtraMensagens.descricao).option('--check', 'Apenas verifica se arquivos precisariam de formatação (default)', true).option('--write', 'Aplica as mudanças no filesystem', false).option('--engine <engine>', 'Motor de formatação: auto|interno|prettier (auto tenta usar Prettier do projeto e cai no interno)', 'auto').option('--include <padrao>', 'Glob pattern a INCLUIR (pode repetir a flag ou usar vírgulas / espaços para múltiplos)', (val, prev) => {
        prev.push(val);
        return prev;
    }, []).option('--exclude <padrao>', 'Glob pattern a EXCLUIR adicionalmente (pode repetir a flag ou usar vírgulas / espaços)', (val, prev) => {
        prev.push(val);
        return prev;
    }, []).action(async function (opts) {
        try {
            await aplicarFlagsGlobais(this.parent && typeof this.parent.opts === 'function' ? this.parent.opts() : {});
            const write = Boolean(opts.write);
            const check = write ? false : Boolean(opts.check ?? true);
            const engineRaw = String(opts.engine || process.env.TUTANUS_FORMAT_ENGINE || 'auto').trim();
            const engine = engineRaw === 'interno' || engineRaw === 'prettier' || engineRaw === 'auto' ? engineRaw : 'auto';
            const includeList = processPatternList(opts.include);
            const excludeList = processPatternList(opts.exclude);
            const includeGroupsRaw = [];
            const incluiNodeModules = detectaNodeModulesExplicito(includeGroupsRaw, includeList);
            configurarFiltros(includeGroupsRaw, includeList, excludeList, incluiNodeModules);
            const baseDir = process.cwd();
            const result = {
                total: 0,
                formataveis: 0,
                mudaram: 0,
                erros: 0,
                arquivosMudaram: []
            };
            log.info(chalk.bold(CliFormatarExtraMensagens.titulo));
            if (config.SCAN_ONLY) {
                log.aviso(CliFormatarExtraMensagens.scanOnlyAtivo);
            }
            const fileMap = await scanRepository(baseDir, {
                includeContent: true,
                filter: relPath => {
                    return isFormatavel(relPath);
                }
            });
            const entries = Object.values(fileMap);
            result.total = entries.length;
            for (const erro of entries) {
                const relPath = erro.relPath;
                if (excludeList.length && micromatch.isMatch(relPath, excludeList)) {
                    continue;
                }
                if (includeList.length) {
                    const matchGlob = micromatch.isMatch(relPath, includeList);
                    const matchExact = includeList.some(caminho => String(caminho).trim() === relPath);
                    if (!matchGlob && !matchExact)
                        continue;
                }
                const src = typeof erro.content === 'string' ? erro.content : '';
                const resolved = await formatarComEngine(src, relPath, baseDir, engine);
                if (!resolved.ok) {
                    result.erros++;
                    log.erro(CliFormatarExtraMensagens.falhaFormatar.replace('{arquivo}', relPath).replace('{erro}', resolved.error ?? ''));
                    continue;
                }
                if (resolved.parser === 'unknown') {
                    continue;
                }
                result.formataveis++;
                if (!resolved.changed) {
                    continue;
                }
                result.mudaram++;
                result.arquivosMudaram.push(relPath);
                if (write) {
                    const abs = path.resolve(baseDir, relPath);
                    await salvarEstado(abs, resolved.formatted);
                }
            }
            if (result.erros > 0) {
                log.erro(CliFormatarExtraMensagens.errosEncontrados.replace('{total}', String(result.erros)));
                sair(ExitCode.Failure);
                return;
            }
            if (check) {
                if (result.mudaram > 0) {
                    log.aviso(CliFormatarExtraMensagens.precisaFormatacao.replace('{total}', String(result.mudaram)));
                    sair(ExitCode.Failure);
                    return;
                }
                log.sucesso(CliFormatarExtraMensagens.tudoFormatado);
                sair(ExitCode.Ok);
                return;
            }
            if (result.mudaram > 0) {
                log.sucesso(CliFormatarExtraMensagens.arquivosFormatados.replace('{total}', String(result.mudaram)));
            }
            else {
                log.info(CliFormatarExtraMensagens.nenhumaMudanca);
            }
            sair(ExitCode.Ok);
        }
        catch (err) {
            log.erro(`Falha ao formatar: ${err instanceof Error ? err.message : String(err)}`);
            sair(ExitCode.Failure);
        }
    });
}
//# sourceMappingURL=command-format.js.map