import type { CompanyTurnEvent } from '../../features/company';

/**
 * 1인 기업 turn 의 `CompanyTurnEvent` emit 사이드이펙트 묶음. dispatcher 가 매
 * phase 마다 호출하는 `onEvent` 콜백을 *3가지 사이드이펙트 (webview 송신 + summary
 * 기록 + pixel office hook)* 와 *turn 종료 후 caller 가 읽을 mutable state* 로
 * 분리해 한 factory 로 격리.
 *
 * 옛 코드: sidebarProvider 의 `_runCompanyTurn` 안 16줄짜리 closure. 사이드이펙트
 * 와 mutable 캡처가 한 함수에 섞여 있어 가독성/테스트성 모두 낮았다.
 *
 * 사용:
 *   const emitter = createCompanyTurnEmit({ postWebview, recordSummary, onPixelOffice });
 *   const deps = buildDispatcherDeps({ ..., onEvent: emitter.emit });
 *   await runCompanyTurn(prompt, deps);
 *   const report = emitter.getFinalReport();
 */

export interface CompanyTurnEmitDeps {
    /** dispatcher event 를 webview 에 `companyTurnUpdate` 로 그대로 전달. */
    postWebview: (msg: { type: string; value: unknown }) => void;
    /**
     * Turn 의 *완료된* 결과 (plan brief + report tail) 를 caller 측 cache 에 기록.
     * 다음 메시지의 intent classifier 가 "follow-up 인가?" 판단할 때 사용. abort
     * 된 turn 은 호출 안 됨 (report-done 이 안 옴).
     */
    recordSummary: (brief: string, reportTail: string) => void;
    /** Pixel Office 같은 read-only 모니터링 hub 알림. throw 해도 turn 흐름엔 영향 없음. */
    onPixelOffice: (event: CompanyTurnEvent) => void;
}

export interface CompanyTurnEmitter {
    emit: (event: CompanyTurnEvent) => void;
    /** Turn 완료 후 caller 가 final report 읽기 — abort 된 turn 은 빈 문자열. */
    getFinalReport: () => string;
}

export function createCompanyTurnEmit(deps: CompanyTurnEmitDeps): CompanyTurnEmitter {
    let stagingBrief = '';
    let finalReport = '';
    return {
        emit(event: CompanyTurnEvent) {
            deps.postWebview({ type: 'companyTurnUpdate', value: event });
            if (event.phase === 'plan-ready') {
                stagingBrief = event.plan?.brief || '';
            } else if (event.phase === 'report-done') {
                finalReport = (event.report || '').trim();
                deps.recordSummary(stagingBrief, finalReport.slice(-600));
            }
            try { deps.onPixelOffice(event); } catch { /* never break the turn */ }
        },
        getFinalReport: () => finalReport,
    };
}
