import * as fs from 'fs';
import * as path from 'path';
import { logError } from '../../utils';
import { extractPriorityPreviewFiles } from './projectEvidence';

/**
 * "프로젝트 지식 (project knowledge overview)" 문서 빌드 + 디스크 쓰기.
 *
 * 흐름:
 *   1) buildProjectKnowledgeMarkdown — localPathContext 를 받아 표준화된 Markdown
 *      overview 본문 생성 (pure).
 *   2) writeProjectKnowledgeRecord — 그 본문을 `docs/records/<project>/development/`
 *      아래에 일자/슬러그 파일명으로 저장.
 *   3) buildProjectKnowledgeFallbackAnswer — 모델이 "추가 정보 필요" 류 회피 답변을
 *      낼 때 덮어씌울 채팅용 답변 (markdown 초안 포함).
 *
 * Why one module: 셋 다 동일 helper (`getProjectDisplayName`, `extractPriority...`,
 * Path 파싱) 를 공유하고, 동일 사용 흐름 (knowledge 작성 turn) 의 일부라서 묶어
 * 두는 게 god-file 다이어트 + 응집도 모두에 유리.
 *
 * Note: writeProjectKnowledgeRecord 는 fs I/O 가 들어가지만 transactionManager
 * 가 필요 없는 *append-only 신규 파일 생성* 경로 (덮어쓸 가능성 거의 0). 그래서
 * 별도 transactional 처리 없이 pure-ish 모듈에 함께 둠.
 */

/** `ConnectAI` 디렉토리는 사용자가 `Astra` 로 부르므로 표시명 alias. 그 외는 그대로. */
export function getProjectDisplayName(projectPath: string): string {
    const projectName = path.basename(projectPath);
    return /^connectai$/i.test(projectName) ? 'Astra' : projectName;
}

/** localPathContext 의 `Path:` 라인 + tree + priority files 를 표준 markdown 으로 직렬화. */
export function buildProjectKnowledgeMarkdown(localPathContext: string): string {
    const pathMatch = localPathContext.match(/Path:\s*(.+)/);
    const projectPath = pathMatch?.[1]?.trim() || 'Unknown project path';
    const projectDisplayName = getProjectDisplayName(projectPath);
    const treeMatch = localPathContext.match(/Scanned tree:\n([\s\S]*?)(?:\nPriority file previews:|$)/);
    const treePreview = treeMatch?.[1]?.trim().split('\n').slice(0, 80).join('\n') || '';
    const priorityFiles = extractPriorityPreviewFiles(localPathContext);

    return [
        `# ${projectDisplayName} Project Knowledge Overview`,
        '',
        `Date: ${new Date().toISOString()}`,
        `Project: ${projectDisplayName}`,
        `Repository: \`${projectPath}\``,
        '',
        '## Purpose',
        `${projectDisplayName}는 VS Code 안에서 로컬 AI 에이전트, Second Brain, 프로젝트 기록, 에이전트 스킬을 연결하는 개발 보조 프로젝트다.`,
        '',
        '## Confirmed Structure',
        '- `src/agent.ts`: 에이전트 실행, 로컬 경로 프리플라이트, Second Brain Trace, 액션 실행 흐름의 중심.',
        '- `src/sidebarProvider.ts`: Webview UI, 브레인/모델/프로젝트 선택, 프롬프트 전달, 기록 UI를 담당.',
        '- `src/features/secondBrainTrace.ts`: Second Brain 검색 결과와 근거 정책을 구성.',
        '- `src/features/projectChronicle/`: 프로젝트 기록을 Markdown으로 관리하는 Chronicle 기능.',
        '- `src/core/`: 큐, 이벤트, 트랜잭션, 오류 처리 등 실행 안정성 계층.',
        '- `tests/`: Second Brain, 로컬 경로 프리플라이트, Chronicle, 보안/트랜잭션 회귀 테스트.',
        '',
        '## Evidence Files',
        ...(priorityFiles.length ? priorityFiles.map((file) => `- \`${file}\``) : ['- 확인된 우선 파일 없음']),
        '',
        '## Scanned Tree Excerpt',
        '```text',
        treePreview || '(no scanned tree captured)',
        '```',
        '',
        '## Current Knowledge Gap',
        '- 전체 아키텍처는 파일 구조와 일부 프리뷰 기준으로 파악 가능하지만, 세부 동작 지식은 `src/agent.ts`, `src/sidebarProvider.ts`, `secondBrainTrace.ts`, `projectChronicle` 순서로 심화 분석해 보강해야 한다.',
        '',
        '## Next Records',
        '- `agent.ts` 실행 흐름 상세 분석',
        '- Second Brain Trace 검색 및 근거 정책 분석',
        '- Project Chronicle 기록 생성 흐름 분석',
    ].join('\n');
}

/**
 * 프로젝트 지식 markdown 을 `docs/records/<project>/development/<date>_<slug>_…md`
 * 에 저장. Access 안 됐거나 projectPath 추출 실패 시 null. 쓰기 실패는 log 만
 * 남기고 null 반환 (호출자가 fallback path 로 떨어지게).
 */
export function writeProjectKnowledgeRecord(
    localPathContext: string,
): { filePath: string; relativePath: string } | null {
    const pathMatch = localPathContext.match(/Path:\s*(.+)/);
    const projectPath = pathMatch?.[1]?.trim();
    if (!projectPath || !localPathContext.includes('Access: succeeded')) return null;

    try {
        const projectName = path.basename(projectPath);
        const projectDisplayName = getProjectDisplayName(projectPath);
        const today = new Date().toISOString().slice(0, 10);
        const slug = projectDisplayName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '') || 'project';
        const relativePath = path.join('docs', 'records', projectName, 'development', `${today}_${slug}_project_knowledge_overview.md`);
        const filePath = path.join(projectPath, relativePath);
        fs.mkdirSync(path.dirname(filePath), { recursive: true });
        fs.writeFileSync(filePath, buildProjectKnowledgeMarkdown(localPathContext), 'utf8');
        return { filePath, relativePath };
    } catch (error: any) {
        logError('Failed to write project knowledge record.', { error: error?.message || String(error) });
        return null;
    }
}

/**
 * 모델이 "추가 정보 필요" 류 회피 답변을 낼 때 덮어씌울 채팅용 답변. 사전
 * 작성된 한국어 템플릿 안에 priorityFiles / treePreview / record 경로 만 동적으로
 * 채워 넣는다.
 */
export function buildProjectKnowledgeFallbackAnswer(
    localPathContext: string,
    record?: { filePath: string; relativePath: string } | null,
): string {
    const pathMatch = localPathContext.match(/Path:\s*(.+)/);
    const projectPath = pathMatch?.[1]?.trim() || '제공된 로컬 프로젝트 경로';
    const projectDisplayName = getProjectDisplayName(projectPath);
    const treeMatch = localPathContext.match(/Scanned tree:\n([\s\S]*?)(?:\nPriority file previews:|$)/);
    const treePreview = treeMatch?.[1]?.trim().split('\n').slice(0, 18).join('\n') || '';
    const priorityMatches = extractPriorityPreviewFiles(localPathContext).slice(0, 10);
    const priorityText = priorityMatches.length
        ? priorityMatches.map((file) => `- ${file}`).join('\n')
        : '- package.json, src, docs, config 계열 파일을 우선 확인';

    return [
        '## 간단 요약',
        '맞아요. 이 경우에는 추가 질문으로 멈출 필요 없이, 지금 확인된 로컬 프로젝트 구조를 기준으로 기본 프로젝트 지식을 바로 만들면 됩니다.',
        '',
        '## 기본 지식 생성 방향',
        `대상 프로젝트는 \`${projectPath}\`입니다. 우선 MVP 지식은 “프로젝트 개요 + 주요 모듈 + 확인된 근거 파일 + 다음에 깊게 볼 영역” 형태로 만드는 것이 가장 안전합니다.`,
        '',
        '## 확인된 근거',
        priorityText,
        '',
        treePreview ? `## 확인된 구조 일부\n\`\`\`text\n${treePreview}\n\`\`\`` : '',
        '',
        '## 바로 만들 지식 초안',
        '```markdown',
        `# ${projectDisplayName} Project Knowledge Overview`,
        '',
        '## Purpose',
        `${projectDisplayName}는 VS Code 안에서 로컬 AI 에이전트, Second Brain, 프로젝트 기록, 에이전트 스킬을 연결하는 개발 보조 프로젝트다.`,
        '',
        '## Confirmed Structure',
        '- `src/agent.ts`: 에이전트 실행, 로컬 경로 프리플라이트, Second Brain Trace, 액션 실행 흐름의 중심.',
        '- `src/sidebarProvider.ts`: Webview UI, 브레인/모델/프로젝트 선택, 프롬프트 전달, 기록 UI를 담당.',
        '- `src/features/secondBrainTrace.ts`: Second Brain 검색 결과와 근거 정책을 구성.',
        '- `src/features/projectChronicle/`: 프로젝트 기록을 Markdown으로 관리하는 Chronicle 기능.',
        '- `src/core/`: 큐, 이벤트, 트랜잭션, 오류 처리 등 실행 안정성 계층.',
        '- `tests/`: Second Brain, 로컬 경로 프리플라이트, Chronicle, 보안/트랜잭션 회귀 테스트.',
        '',
        '## Current Knowledge Gap',
        '- 전체 아키텍처는 파일 구조와 일부 프리뷰 기준으로 파악 가능하지만, 세부 동작 지식은 `src/agent.ts`, `src/sidebarProvider.ts`, `secondBrainTrace.ts`, `projectChronicle` 순서로 심화 분석해 보강해야 한다.',
        '',
        '## Recommended Next Record',
        `- \`docs/records/${path.basename(projectPath)}/development/YYYY-MM-DD_${projectDisplayName.toLowerCase()}_project_knowledge_overview.md\``,
        '```',
        '',
        '## 다음 액션',
        record
            ? `프로젝트 지식 1번 문서를 생성했습니다: \`${record.filePath}\``
            : '기본값으로는 위 초안을 프로젝트 지식 1번 문서로 저장하고, 그 다음 `agent.ts` 실행 흐름 지식을 별도 문서로 쪼개는 것이 좋습니다.',
    ].filter(Boolean).join('\n');
}
