/**
 * 사용자 prompt 의 *의도 분류* 류 detection helpers. 모두 stateless 정규식 매칭.
 *
 * 옛 코드는 agent.ts 의 private 메서드로 박혀 있었는데, system prompt 빌더
 * (`buildJarvisProjectBriefContext` 등) 가 이걸 의존하면서 god-file 안에서 서로
 * 얽힘. 헬퍼만 먼저 떼면 의존 그래프가 단방향 (builders → detection) 으로 정리됨.
 *
 * 주의: 패턴 확장 시 false positive 폭 넓혀 일반 질문에서도 thinking-partner
 * 컨텍스트가 잘못 박히지 않는지 검증할 것 — 잘못된 컨텍스트는 모델 출력 품질을
 * 직접 깎는다.
 */

/**
 * Thinking partner request — 사용자가 "어떻게 생각해?" "어떤 게 맞을까?" 등
 * *결정 / 의견 / 판단 / 구조* 류 메타 질문을 던졌는가. 한 줄 정규식으로 폭 넓게
 * 잡되, 단어 일부 매칭이라 "구조" 같은 흔한 단어가 들어가면 true 일 수 있음 —
 * 호출자는 이걸 다른 detection (`isCasualConversationPrompt`) 과 함께 써야 함.
 */
export function isThinkingPartnerRequest(prompt: string): boolean {
    return /(어떤\s*거?\s*같|어때|어떻게\s*생각|의견|판단|방향|설계|아키텍처|구조|자비스|생각.*정리|갈림길|architecture|design|direction|opinion|think|judge)/i.test(prompt);
}

/**
 * Standalone greetings / acknowledgements / fillers — *전체 메시지* 가 짧은 잡담
 * 한 마디일 때만 true. "안녕, 이 프로젝트 분석해줘" 같이 일감이 붙으면 길어져
 * 자동 탈락. 잘못 잡으면 단순 "안녕" 에도 RAG 가 돌아 옛 프로젝트 기록을 끌어와
 * 모델이 stale context 에 답하는 사고가 남.
 */
const CASUAL_PHRASES = new Set<string>([
    // greetings
    '안녕', '안녕하세요', '안녕하십니까', '안뇽', '하이', '하잉', '헬로', '헬로우', 'hello', 'hi', 'hii', 'hey', 'yo', 'ㅎㅇ', 'ㅎㅇㅎㅇ', '굿모닝', 'good morning', 'morning', 'gm',
    // farewells
    '잘가', '잘가요', '안녕히', '안녕히가세요', '안녕히계세요', '바이', '바이바이', 'bye', 'byebye', 'bye bye', 'goodbye', 'good bye', '굿바이', '잘자', '잘자요', '굿나잇', 'good night', 'gn',
    // acknowledgements / affirmations
    '네', '넵', '넹', '예', '응', '웅', '음', '흠', '엄', '그래', '그렇구나', '그렇군', '그렇네', '오케이', '오케', 'ok', 'okay', 'okey', 'k', 'ㅇㅋ', 'ㅇㅇ', '알겠어', '알겠습니다', '알겠어요', '알았어', '알았다', '알았어요', 'yes', 'yeah', 'yep', 'yup', 'sure', '좋아', '좋아요', '좋네', '좋다', 'good', 'fine',
    // negations (still small talk — needs no RAG; the prior turn is already in the chat history)
    '아니', '아니요', '아니오', 'ㄴㄴ', 'no', 'nope', 'nah',
    // thanks / praise
    '고마워', '고마워요', '고맙습니다', '감사', '감사해요', '감사합니다', 'thanks', 'thank you', 'thx', 'ty', '굿', '굳', '굿잡', 'good job', '잘했어', '잘했네', '훌륭', '훌륭해', '대박', 'nice', 'cool', 'great', 'awesome', 'perfect', '완벽', '수고', '수고했어', '수고하셨습니다', '고생했어', '고생많았어',
    // laughs / fillers
    'lol', 'haha', 'hmm', 'hmmm', 'umm', 'uh',
]);

/**
 * Second Brain 명시 요청 — RAG 강제 발동 트리거. 키워드 폭이 넓어서 false positive
 * 가능하나 호출자가 force=true 의도로만 사용하므로 약간 관대해도 OK.
 */
export function isExplicitSecondBrainRequest(prompt: string): boolean {
    return /(second brain|2nd brain|제2뇌|브레인|brain|기억|기록|노트|문서|참고해서|사용해서|검색해서|근거|출처)/i.test(prompt);
}

/**
 * Second Brain *전체 평가* 요청 — "내 제2뇌의 강점/약점은?" 류. brain 키워드 +
 * overview/평가 키워드 둘 다 있어야 true (좁게 잡음). 매치되면 inventory 컨텍스트
 * 블록 + fallback 답변 path 가 활성화.
 */
export function isSecondBrainInventoryRequest(prompt: string): boolean {
    const normalized = prompt.toLowerCase();
    const asksBrain = /(second brain|2nd brain|제2뇌|브레인|brain)/i.test(normalized);
    const asksOverview = /(평가|분석|강점|약점|부족|무엇을 할 수|활용|전체|연결된|현재|inside|overview|inventory|strength|weakness)/i.test(normalized);
    return asksBrain && asksOverview;
}

/**
 * 모델이 "데이터/파일/근거 없어서 평가 불가" 류 회피 답변을 냈는지 detect. true 면
 * 호출자(inventory 흐름) 가 답변을 fallback 본문으로 덮어쓴다.
 */
export function isNoBrainDataRefusal(answer: string): boolean {
    return /(분석할 만한 실제 데이터가 없어|분석할.*데이터가 없어|파일 목록.*제공|핵심 내용.*제공|자료를 준비|지식을 먼저 제공|cannot be evaluated|no data|no files)/i.test(answer);
}

export function isCasualConversationPrompt(prompt: string): boolean {
    const normalized = (prompt || '')
        .trim()
        .replace(/\s+/g, ' ')
        .replace(/[~!?.,，。！？·…\s]+$/g, '')
        .toLowerCase();
    if (!normalized) return false;
    if (normalized.length > 40) return false;

    if (CASUAL_PHRASES.has(normalized)) return true;
    if (/^[ㅋㅎ]{2,}$/.test(normalized)) return true;       // ㅋㅋ, ㅎㅎㅎ, ㅋㅎㅋㅎ
    if (/^(?:ha){2,}h?$|^(?:he){2,}h?$/.test(normalized)) return true; // haha, hahaha, hehe
    return false;
}

/**
 * 슬래시 명령(/wikify, /benchmark 등)인지 — *명령만* 골라낸다. 절대경로
 * ("/Volumes/Data/... 분석해줘")는 명령이 아니다. 옛 `startsWith('/')` 가드가
 * 경로로 시작하는 프롬프트를 전부 명령으로 오인해 분석 지시·URL 주입이 통째로
 * 죽는 버그가 있었다 (이 사용자 패턴의 대표형이 "경로 + 분석해줘").
 * 패턴: 슬래시 + 명령어 + (공백|끝). 경로는 두 번째 '/'가 바로 이어져 미스매치.
 */
export function isSlashCommand(text: string): boolean {
    return /^\/[a-zA-Z][\w-]*(\s|$)/.test((text || '').trim());
}

/**
 * 분석/검토/의견형 요청 감지 — 이런 요청에서 모델이 코드를 읽지 않고 "~로
 * 보입니다" 추측으로 답하는 실패 모드를 막기 위한 grounding 지시 주입 트리거.
 * 보수적 휴리스틱: 분석 동사 포함 + 슬래시 명령 아님 + 최소 길이.
 */
export function isAnalysisRequest(prompt: string): boolean {
    const p = (prompt || '').trim();
    if (p.length < 8 || isSlashCommand(p)) return false;
    return /(분석|검토|리뷰|평가|점검|진단|의견|개선점|개선 ?방향|review|analyze|audit|assess)/i.test(p);
}
