import { getConfig } from '../../config';
import { estimateTokens, estimateModelParamsB } from '../contextManager';
import { isCasualConversationPrompt } from './promptDetection';
import { isAstraModeArchitectureQuestion } from './astraModeArchitecture';
import { shouldPreflightLocalProjectPath } from './localProjectIntent';

/**
 * 단일-LLM vs Multi-Agent (5단계 파이프라인) 라우팅 결정. 사용자가 명시 토글을
 * 켰거나 (configEnabled), 작은 모델인데 prompt 가 크거나, 복합 작업 키워드가
 * 매치되면 multi-agent 활성화. 잡담/짧은 prompt 는 무조건 단일 LLM.
 *
 * Priority (위→아래로 evaluated, 먼저 매치되면 그 결정 사용):
 *   1) Astra-mode meta question / local-path preflight → 단일 (false)
 *   2) mode='off' 인 사용자 — legacy 키워드+길이 휴리스틱만 사용
 *   3) casual prompt / 너무 짧음 (<12자) → 단일
 *   4) mode='always' → 무조건 multi (위 가드 통과 시)
 *   5) mode='auto' — 작은 모델 / context fraction / 키워드 / 길이 중 하나라도
 *      매치되면 multi. 단 prompt tokens 가 `chunkedSwitchTokens` 미만이면 *모든*
 *      트리거 무시하고 단일 (큰 context 모델에서 키워드만으로 chunked 강제 발동
 *      되는 회귀 차단 — 사용자 명시 요청).
 *
 * Stateless — agent.ts 의 private 메서드를 그대로 추출. 의존: config / token
 * 추정기 / 다른 detection 함수 (모두 이미 stateless).
 */
export function shouldUseMultiAgentWorkflow(prompt: string, configEnabled: boolean): boolean {
    if (!prompt || isAstraModeArchitectureQuestion(prompt)) {
        return false;
    }

    if (shouldPreflightLocalProjectPath(prompt)) {
        return false;
    }

    const cfg = getConfig();
    const mode = cfg.workflowMultiAgentMode || 'auto';

    // 'off' → 기존 키워드/길이 휴리스틱만 사용 (legacy multiAgentEnabled 토글 존중).
    if (mode === 'off') {
        const legacyComplex = prompt.length > 180 || /(보고서|심층|종합\s*분석|리서치|조사|전략\s*수립|기획안|제안서|roadmap|research|report|deep\s*analysis|strategy|proposal)/i.test(prompt);
        if (!legacyComplex) return false;
        return configEnabled || /(보고서|심층|종합\s*분석|리서치|조사|전략\s*수립|기획안|제안서|research|report|deep\s*analysis|strategy|proposal)/i.test(prompt);
    }

    // 인사·잡담은 5단계 파이프라인 낭비. 짧은 casual prompt 는 제외.
    if (isCasualConversationPrompt(prompt)) {
        return false;
    }
    if (prompt.trim().length < 12) {
        return false;
    }

    // 'always' → 위 가드만 통과하면 무조건 발동.
    if (mode === 'always') return true;

    // 'auto' → 다음 중 하나라도 만족하면 발동:
    //   (1) 사용자가 multiAgentEnabled 를 명시적으로 켰다,
    //   (2) 작은 모델 (≤4B params) 이라 한 번에 처리하기 위험,
    //   (3) prompt 토큰이 효과적 context window 의 임계 이상을 차지한다,
    //   (4) "보고서/리뷰/심층 분석" 같은 명백한 복합 작업 키워드 매치,
    //   (5) prompt 길이 자체가 큼 (>240 chars).
    if (configEnabled) return true;

    const paramB = estimateModelParamsB(cfg.defaultModel);
    if (paramB !== null && paramB <= 4) return true;

    // ── 절대 임계값 게이트 (사용자 명시 요청) ────────────────────────────
    // 입력 prompt 가 `chunkedSwitchTokens` 미만이면 *키워드·길이 트리거 모두 무시*
    // 하고 단일 LLM 호출. 큰 컨텍스트 모델(131k 등)에서 "요약/리뷰" 같은 키워드만
    // 써도 chunked 가 강제 발동해 답변이 느려지던 문제 해결.
    //
    // 이 게이트는 fraction 안전 체크보다 *먼저* 평가됨 — 사용자가 절대 임계값을
    // 명시한 의도(50k 미만은 한 번에 처리)를 fraction 이 뒤집지 못하게. 작은
    // 컨텍스트 모델 사용자는 config 에서 이 값을 모델 윈도우의 ~30% 로 낮춰야 함.
    try {
        const promptTokensForGate = estimateTokens(prompt);
        if (promptTokensForGate < cfg.chunkedSwitchTokens) {
            return false;
        }
    } catch { /* fall through — 안전 측 fraction/keyword 체크가 처리 */ }

    try {
        const effectiveCtx = cfg.smallModelContextCap > 0 && paramB !== null && paramB <= 4
            ? cfg.smallModelContextCap
            : cfg.contextLength;
        const promptTokens = estimateTokens(prompt);
        const threshold = Math.floor(effectiveCtx * cfg.workflowAutoCtxFractionThreshold);
        if (promptTokens >= threshold) return true;
    } catch { /* 안전한 폴백: 키워드/길이 체크로 진행 */ }

    if (/(보고서|심층|종합\s*분석|리서치|조사|전략\s*수립|기획안|제안서|코드\s*리뷰|리뷰|아키텍처|architecture|research|report|deep\s*analysis|strategy|proposal|review)/i.test(prompt)) {
        return true;
    }
    if (prompt.length > 240) return true;

    return false;
}
