import * as fs from 'fs';
import type { ProjectProfile } from '../../features/projectChronicle';
import { formatArchitectureContextForPrompt } from '../../features/projectArchitecture';

/**
 * Architecture (chronicle 프로젝트 자동 attach) 관련 webview payload + prompt
 * context 빌더. webview send / fs write / scan 같은 *상태성* 부분은 provider 와
 * `ArchitectureWatchManager` 가 계속 책임 — 이 모듈은 데이터 변환만.
 *
 *   - buildArchitectureStatusPayload(profile, hasDoc, wasDetached)
 *     → 'architectureStatus' 메시지의 active/inactive/hidden 분기
 *   - buildProjectArchitectureContext(profile)
 *     → agent.ts 가 prompt 에 prepend 하는 architecture context string
 */

/**
 * Sidebar chip 의 3 가지 상태:
 *   1) active — auto-attach 켜져 있고 doc 존재. 칩에 "마지막 갱신 N분 전" 표시.
 *   2) inactive (canAttach) — workspace + project 는 있으나 doc 미생성 or detached.
 *      칩에 [Attach] 버튼 노출. `detached` 플래그로 "Activate" vs "Re-attach" 구분.
 *   3) hidden — profile null. 호출자가 `{ active: false }` 만 보내고 끝.
 *
 * 빌더는 (1)(2) 만 만들고, hidden 은 호출자가 직접 보낸다 (profile 이 없는데
 * 빌더에 넘겨봤자 의미 없음).
 */
export function buildArchitectureStatusPayload(profile: ProjectProfile, hasDoc: boolean, wasDetached: boolean) {
    const fullyActive = hasDoc && !wasDetached;
    if (fullyActive) {
        return {
            type: 'architectureStatus' as const,
            value: {
                active: true,
                projectId: profile.projectId,
                projectName: profile.projectName,
                docPath: profile.architectureDocPath,
                lastUpdated: profile.architectureLastUpdated || '',
                autoUpdate: profile.architectureAutoUpdate !== false,
            },
        };
    }
    return {
        type: 'architectureStatus' as const,
        value: {
            active: false,
            canAttach: !!profile.projectRoot,
            projectId: profile.projectId,
            projectName: profile.projectName,
            // "never activated" 와 "detached" 구분 — chip 라벨 결정용.
            detached: wasDetached,
        },
    };
}

/** Workspace 도 profile 도 없는 hidden 상태 — chip 자체 숨김. */
export function buildArchitectureHiddenPayload() {
    return {
        type: 'architectureStatus' as const,
        value: { active: false as const },
    };
}

/**
 * Refresh / Attach 가 사전 가드에서 실패 (활성 project 없음 / projectRoot 없음).
 * webview 는 spinner 를 해제하고 사용자에게 안내 띄움.
 */
export function buildArchitectureRefreshFailedPayload(reason: string) {
    return {
        type: 'architectureRefreshFailed' as const,
        value: { reason },
    };
}

/**
 * Refresh 가 성공적으로 수행된 후 webview 에 보낼 결과. 3가지 숫자 (newly /
 * cached / deleted) 가 함께 가야 사용자가 "Refresh 가 실제로 뭘 했는가" 를
 * 신뢰할 수 있다 — 그냥 timestamp 만 바뀐 경우와 분 단위로 큰 작업이 일어난
 * 경우를 구분.
 */
export function buildArchitectureRefreshResultPayload(opts: {
    projectName: string;
    docPath: string;
    newlyAnalyzed: number;
    cached: number;
    deleted: number;
    durationMs: number;
}) {
    return {
        type: 'architectureRefreshResult' as const,
        value: opts,
    };
}

/**
 * Agent 의 prompt 에 prepend 되는 architecture context block. auto-attach 가 off
 * 거나 doc 이 없거나 디스크에서 사라졌으면 빈 문자열 (agent.ts 가 알아서 skip).
 */
export function buildProjectArchitectureContext(profile: ProjectProfile | null): string {
    if (!profile || profile.architectureAutoAttach === false || !profile.architectureDocPath) return '';
    if (!fs.existsSync(profile.architectureDocPath)) return '';
    return formatArchitectureContextForPrompt({
        projectName: profile.projectName,
        docPath: profile.architectureDocPath,
        // project root 를 같이 넘겨 Source: 헤더가 workspace-relative 로 출력되게.
        projectRoot: profile.projectRoot,
        lastUpdated: profile.architectureLastUpdated,
    });
}
