/**
 * Learning Queue — 승인 기반 학습 대기열 (설계서 9장).
 *
 * Self-Evolving OS 마스터 플랜 Phase 3 / Track 3-5. Need Engine 의 우선순위를
 * 사람이 승인 가능한 큐로 영속화한다.
 *
 * Constitution 준수 (Track 8-2, Permission Based Learning):
 *   - 시스템은 항목을 *proposed* 로만 추가한다 — 승인은 사람만.
 *   - 사용자가 파일에서 status 를 approved 로 바꾸면 학습 실행 대상이 된다
 *     (실행은 Research Agent — Phase 6 후속 증분).
 *   - mergeNeedsIntoQueue 는 proposed 항목만 갱신하고, 사람이 정한 상태
 *     (approved/in-progress/done/rejected)는 절대 건드리지 않는다.
 *
 * 저장: <brain>/.astra/growth/learning-queue.json (사람이 직접 편집 가능하도록
 * pretty-print JSON 단일 파일 — md-first ASTRA 철학과 동일한 "파일이 UI" 접근).
 */

import * as fs from 'fs';
import * as path from 'path';
import type { NeedItem } from './needEngine';

export const LEARNING_QUEUE_REL_PATH = path.join('.astra', 'growth', 'learning-queue.json');

export type QueueStatus = 'proposed' | 'approved' | 'in-progress' | 'done' | 'rejected';

export interface QueueItem {
    /** 안정 키 — 업무유형 기반 (v1). 같은 키는 한 항목으로 유지·갱신. */
    id: string;
    topic: string;
    /** Need Score 0~100 — 갱신 시 최신값으로 교체 (proposed 한정). */
    priority: number;
    reason: string;
    status: QueueStatus;
    createdAt: string;
    updatedAt: string;
}

const VALID_STATUSES: QueueStatus[] = ['proposed', 'approved', 'in-progress', 'done', 'rejected'];

export function loadQueue(brainPath: string): QueueItem[] {
    try {
        const file = path.join(brainPath, LEARNING_QUEUE_REL_PATH);
        if (!fs.existsSync(file)) return [];
        const arr = JSON.parse(fs.readFileSync(file, 'utf8'));
        if (!Array.isArray(arr)) return [];
        return arr.filter((it: any) =>
            it && typeof it.id === 'string' && VALID_STATUSES.includes(it.status),
        ) as QueueItem[];
    } catch {
        return [];
    }
}

export function saveQueue(brainPath: string, queue: QueueItem[]): boolean {
    try {
        const file = path.join(brainPath, LEARNING_QUEUE_REL_PATH);
        fs.mkdirSync(path.dirname(file), { recursive: true });
        // 우선순위 높은 순 정렬 저장 — 파일을 열면 위가 가장 급한 학습.
        const sorted = queue.slice().sort((a, b) => b.priority - a.priority);
        fs.writeFileSync(file, JSON.stringify(sorted, null, 2) + '\n', 'utf8');
        return true;
    } catch {
        return false;
    }
}

/**
 * Need 결과를 큐에 병합.
 *   - 새 주제 → proposed 로 추가
 *   - 기존 proposed → priority/reason 최신화
 *   - 사람이 정한 상태(approved 등) → 변경하지 않음 (Human Override)
 *   - done/rejected 항목은 Need 가 다시 높아져도 재제안하지 않음 (v1 — 의도적 보수성;
 *     재제안이 필요하면 사용자가 항목을 지우면 된다)
 */
export function mergeNeedsIntoQueue(queue: QueueItem[], needs: NeedItem[], nowIso: string): QueueItem[] {
    const byId = new Map(queue.map((q) => [q.id, q] as const));
    for (const need of needs) {
        const id = `need-${need.taskId}`;
        const existing = byId.get(id);
        if (!existing) {
            byId.set(id, {
                id,
                topic: `${need.taskLabel} 역량 보강${need.topMisses.length ? ` (자주 누락: ${need.topMisses.join(', ')})` : ''}`,
                priority: need.score,
                reason: need.reason,
                status: 'proposed',
                createdAt: nowIso,
                updatedAt: nowIso,
            });
        } else if (existing.status === 'proposed') {
            existing.priority = need.score;
            existing.reason = need.reason;
            existing.updatedAt = nowIso;
        }
        // approved/in-progress/done/rejected — 사람이 정한 상태, 불변.
    }
    return Array.from(byId.values());
}

export function formatQueueMarkdown(queue: QueueItem[]): string {
    const lines: string[] = [];
    lines.push('# Learning Queue');
    lines.push('');
    lines.push('상태 변경은 learning-queue.json 에서 직접: proposed → **approved** (학습 승인) / rejected.');
    lines.push('approved 항목은 Research Agent(후속 증분)가 처리합니다. 시스템은 proposed 만 추가/갱신합니다.');
    lines.push('');
    if (queue.length === 0) {
        lines.push('큐가 비어 있습니다.');
        return lines.join('\n');
    }
    lines.push('| 우선순위 | 주제 | 상태 | 근거 |');
    lines.push('|---|---|---|---|');
    for (const q of queue.slice().sort((a, b) => b.priority - a.priority)) {
        lines.push(`| ${q.priority} | ${q.topic} | ${q.status} | ${q.reason} |`);
    }
    lines.push('');
    return lines.join('\n');
}
