import { statSync } from 'node:fs';
import path from 'node:path';
import { getTypesDirectoryRelPosix } from '../../core/config/index.js';
import { carregarConfigEstrategia, destinoPara, deveIgnorar, normalizarRel } from '../../shared/helpers/index.js';
export async function gerarPlanoEstrategico(contexto, opcoes = {}, sinaisAvancados) {
    const typesDir = getTypesDirectoryRelPosix();
    const cfg = await carregarConfigEstrategia(contexto.baseDir, {
        ...opcoes,
        ignorarPastas: Array.from(new Set([...(opcoes.ignorarPastas || []), typesDir])).filter(Boolean)
    });
    const mover = [];
    const conflitos = [];
    const rels = contexto.arquivos.map(arquivo => normalizarRel(arquivo.relPath));
    const isTestLike = (caminho) => /__(tests|mocks)__/.test(caminho) || /\.(test|spec)\.[jt]sx?$/.test(caminho) || /fixtures\//.test(caminho);
    for (const rel of rels) {
        if (deveIgnorar(rel, cfg.ignorarPastas))
            continue;
        if (isTestLike(rel))
            continue;
        if (!rel.endsWith('.ts') && !rel.endsWith('.js'))
            continue;
        const base = path.posix.basename(rel);
        if (/^(eslint|vitest|next|tailwind|postcss|prettier|jest)\.config\.[jt]s$/i.test(base))
            continue;
        const res = destinoPara(rel, cfg.raizCodigo, cfg.criarSubpastasPorEntidade, cfg.apenasCategoriasConfiguradas, cfg.categoriasMapa);
        if (!res.destinoDir)
            continue;
        const currentDir = path.posix.dirname(rel);
        const alreadyInTarget = currentDir === res.destinoDir || currentDir.startsWith(`${res.destinoDir}/`);
        if (alreadyInTarget)
            continue;
        let destinoDirAjustado = res.destinoDir;
        const motivoAjustado = res.motivo || 'Reorganização padrão';
        if (sinaisAvancados) {
            destinoDirAjustado = ajustarDestinoPorSinais(rel, res.destinoDir, sinaisAvancados, motivoAjustado);
        }
        const destino = path.posix.join(destinoDirAjustado, path.posix.basename(rel));
        let destinoExiste = rels.includes(destino);
        if (!destinoExiste) {
            try {
                const abs = path.join(contexto.baseDir, destino.replace(/\\/g, '/'));
                statSync(abs);
                destinoExiste = true;
            }
            catch {
                destinoExiste = false;
            }
        }
        if (destinoExiste) {
            conflitos.push({
                alvo: destino,
                motivo: 'destino já existe'
            });
            continue;
        }
        mover.push({
            de: rel,
            para: destino,
            motivo: motivoAjustado
        });
    }
    const seen = new Set();
    const moverFiltrado = mover.filter(migracao => {
        const migrationChave = `${migracao.de}→${migracao.para}`;
        if (seen.has(migrationChave))
            return false;
        seen.add(migrationChave);
        return true;
    });
    return {
        mover: moverFiltrado,
        conflitos,
        resumo: {
            total: moverFiltrado.length + conflitos.length,
            zonaVerde: moverFiltrado.length,
            bloqueados: conflitos.length
        }
    };
}
function ajustarDestinoPorSinais(relPath, destinoOriginal, sinais, motivoOriginal) {
    let destino = destinoOriginal;
    let _motivo = motivoOriginal;
    if (sinais.tipoDominante) {
        switch (sinais.tipoDominante) {
            case 'api-rest':
                if (relPath.includes('controller') || relPath.includes('route')) {
                    if (!destino.includes('controllers') && !destino.includes('routes')) {
                        destino = 'src/controllers';
                        _motivo += ' | Ajustado para estrutura API REST típica';
                    }
                }
                break;
            case 'frontend-framework':
                if (relPath.includes('component') && !destino.includes('components')) {
                    destino = 'src/components';
                    _motivo += ' | Ajustado para estrutura frontend típica';
                }
                break;
            case 'cli-tool':
                if (relPath.includes('cli') || relPath.includes('command')) {
                    destino = 'src/cli';
                    _motivo += ' | Ajustado para estrutura CLI típica';
                }
                break;
            case 'library':
                if (relPath.includes('index') || relPath.includes('export')) {
                    destino = 'src';
                    _motivo += ' | Mantido na raiz src para biblioteca';
                }
                break;
            case 'clean-arch':
                if (relPath.includes('entity') || relPath.includes('value-object')) {
                    destino = 'src/domain';
                    _motivo += ' | Clean Architecture: camada de domínio';
                }
                if (relPath.includes('use-case') || relPath.includes('interactor') || relPath.includes('port') || relPath.includes('dto')) {
                    destino = 'src/application';
                    _motivo += ' | Clean Architecture: camada de aplicação';
                }
                if (relPath.includes('repository') || relPath.includes('gateway') || relPath.includes('adapter') || relPath.includes('event') || relPath.includes('consumer')) {
                    destino = 'src/infrastructure';
                    _motivo += ' | Clean Architecture: camada de infraestrutura';
                }
                if (relPath.includes('controller') || relPath.includes('presenter') || relPath.includes('handler')) {
                    destino = 'src/presentation';
                    _motivo += ' | Clean Architecture: camada de apresentação';
                }
                break;
            case 'distributed':
            case 'microservices':
                if (relPath.includes('gateway')) {
                    destino = 'src/infrastructure/gateways';
                    _motivo += ' | Distributed Arch: gateways';
                }
                else if (relPath.includes('event') || relPath.includes('message') || relPath.includes('queue')) {
                    destino = 'src/infrastructure/messaging';
                    _motivo += ' | Distributed Arch: mensageria';
                }
                else if (relPath.includes('worker') || relPath.includes('job') || relPath.includes('scheduler')) {
                    destino = 'src/infrastructure/jobs';
                    _motivo += ' | Distributed Arch: jobs/workers';
                }
                else if (relPath.includes('health') || relPath.includes('monitor') || relPath.includes('metric')) {
                    destino = 'src/infrastructure/monitoring';
                    _motivo += ' | Distributed Arch: monitoramento';
                }
                else {
                    const nomeBase = path.posix.basename(relPath, path.posix.extname(relPath));
                    const servicosConhecidos = ['auth', 'user', 'payment', 'order', 'product', 'notification', 'email', 'catalog', 'inventory', 'shipping'];
                    for (const servico of servicosConhecidos) {
                        if (nomeBase.toLowerCase().includes(servico)) {
                            destino = `src/services/${servico}`;
                            _motivo += ` | Distributed Arch: serviço '${servico}'`;
                            break;
                        }
                    }
                }
                break;
        }
    }
    if (sinais.padroesArquiteturais.includes('repository-service')) {
        if (relPath.includes('repository') && !destino.includes('repositories')) {
            destino = 'src/repositories';
            _motivo += ' | Padrão Repository/Service detectado';
        }
        if (relPath.includes('service') && !destino.includes('services')) {
            destino = 'src/services';
            _motivo += ' | Padrão Repository/Service detectado';
        }
    }
    if (sinais.padroesArquiteturais.includes('cli-patterns')) {
        if (relPath.includes('command') && !destino.includes('commands')) {
            destino = 'src/commands';
            _motivo += ' | Padrão CLI detectado';
        }
    }
    if (sinais.padroesArquiteturais.includes('clean-arch-domain') ||
        sinais.padroesArquiteturais.includes('clean-arch-application') ||
        sinais.padroesArquiteturais.includes('clean-arch-infrastructure') ||
        sinais.padroesArquiteturais.includes('clean-arch-presentation')) {
        if ((relPath.includes('entity') || relPath.includes('entities')) && !destino.includes('domain')) {
            destino = 'src/domain/entities';
            _motivo += ' | Clean Architecture: domínio/entities';
        }
        if ((relPath.includes('value-object') || relPath.includes('value-objects')) && !destino.includes('domain')) {
            destino = 'src/domain/value-objects';
            _motivo += ' | Clean Architecture: domínio/value-objects';
        }
        if ((relPath.includes('use-case') || relPath.includes('usecase') || relPath.includes('interactor')) && !destino.includes('application')) {
            destino = 'src/application/use-cases';
            _motivo += ' | Clean Architecture: aplicação/use-cases';
        }
        if (relPath.includes('/ports/') && !destino.includes('application')) {
            destino = 'src/application/ports';
            _motivo += ' | Clean Architecture: aplicação/ports';
        }
        if ((relPath.includes('.dto.') || relPath.includes('/dto/')) && !destino.includes('application')) {
            destino = 'src/application/dto';
            _motivo += ' | Clean Architecture: aplicação/dto';
        }
        if (relPath.includes('repository') && !relPath.includes('domain') && !destino.includes('infrastructure')) {
            destino = 'src/infrastructure/repositories';
            _motivo += ' | Clean Architecture: infraestrutura/repositories';
        }
        if ((relPath.includes('controller') || relPath.includes('handler')) && !destino.includes('presentation') && !destino.includes('controllers')) {
            destino = 'src/presentation/controllers';
            _motivo += ' | Clean Architecture: apresentação/controllers';
        }
        if (relPath.includes('presenter') && !destino.includes('presentation')) {
            destino = 'src/presentation/presenters';
            _motivo += ' | Clean Architecture: apresentação/presenters';
        }
    }
    if (sinais.boundariesServicos && sinais.boundariesServicos.length > 0) {
        for (const boundary of sinais.boundariesServicos) {
            if (relPath.includes(`/services/${boundary}/`)) {
                _motivo += ` | Microsserviço '${boundary}' detectado`;
                break;
            }
        }
    }
    if (sinais.padroesDistribuidos?.includes('api-gateway') || sinais.padroesDistribuidos?.includes('event-driven')) {
        if ((relPath.includes('gateway') || relPath.includes('api-gateway')) && !destino.includes('gateways') && !destino.includes('infrastructure')) {
            destino = 'src/infrastructure/gateways';
            _motivo += ' | Distributed Arch: infrastructure/gateways';
        }
        if ((relPath.includes('event') || relPath.includes('message')) && (relPath.includes('handler') || relPath.includes('consumer')) && !destino.includes('infrastructure')) {
            destino = 'src/infrastructure/events';
            _motivo += ' | Distributed Arch: infrastructure/events';
        }
        if ((relPath.includes('consumer') || relPath.includes('subscriber')) && !destino.includes('infrastructure')) {
            destino = 'src/infrastructure/consumers';
            _motivo += ' | Distributed Arch: infrastructure/consumers';
        }
        if ((relPath.includes('producer') || relPath.includes('publisher')) && !destino.includes('infrastructure')) {
            destino = 'src/infrastructure/producers';
            _motivo += ' | Distributed Arch: infrastructure/producers';
        }
    }
    if (sinais.tecnologiasDominantes.includes('typescript-advanced')) {
        if (relPath.includes('type') || relPath.includes('interface')) {
            destino = 'src/types';
            _motivo += ' | TypeScript avançado detectado';
        }
    }
    if (sinais.complexidadeEstrutura === 'alta') {
        const nomeArquivo = path.posix.basename(relPath, path.posix.extname(relPath));
        if (nomeArquivo.length > 3) {
            const dominioInferido = inferirDominio(nomeArquivo);
            if (dominioInferido && !destino.includes(dominioInferido)) {
                destino = `src/${dominioInferido}`;
                _motivo += ` | Domínio '${dominioInferido}' inferido da complexidade`;
            }
        }
    }
    return destino;
}
function inferirDominio(nomeArquivo) {
    const padroesDominio = {
        auth: ['auth', 'login', 'user', 'session', 'security'],
        payment: ['payment', 'billing', 'invoice', 'transaction', 'checkout'],
        product: ['product', 'item', 'catalog', 'inventory', 'stock'],
        order: ['order', 'cart', 'purchase', 'sale'],
        report: ['report', 'analytics', 'metric', 'dashboard'],
        admin: ['admin', 'management', 'config', 'setting'],
        customer: ['customer', 'client', 'account'],
        billing: ['billing', 'invoice', 'receipt', 'payment'],
        shipping: ['shipping', 'delivery', 'freight', 'logistics'],
        inventory: ['inventory', 'stock', 'warehouse', 'supply'],
        catalog: ['catalog', 'product', 'item', 'category'],
        'api-gateway': ['gateway', 'proxy', 'router'],
        notification: ['notification', 'notify', 'alert', 'push', 'email', 'message'],
        analytics: ['analytics', 'tracking', 'event', 'metric']
    };
    const nomeLower = nomeArquivo.toLowerCase();
    for (const [dominio, palavras] of Object.entries(padroesDominio)) {
        if (palavras.some(palavra => nomeLower.includes(palavra))) {
            return dominio;
        }
    }
    return null;
}
export const EstrategistaEstrutura = {
    nome: 'estrategista-estrutura',
    gerarPlano: gerarPlanoEstrategico
};
//# sourceMappingURL=strategist-structure.js.map