"""publishing/chapter_runner.py — 챕터 단위 3대 엔진 합의도출 실행 진입점.

CLI 인터페이스: python3 chapter_runner.py --chapter N --task-id task-XXX
출처: memory/specs/three-engine-consensus.md

4개 검토시각: 자산관리전문가, 세금/연금전문가, 집필/편집전문가, 레드팀
"""

from __future__ import annotations

import argparse
import asyncio
import logging
import sys
from pathlib import Path

from engine_v2.engine_result import EngineResult
from publishing.consensus_pipeline import MAX_CONSENSUS_ROUNDS, ConsensusPipeline
from publishing.publishing_adapter import PublishingAdapter
from publishing.step_templates import (
    step1_parallel_draft,
    step2_gemini_synthesis,
    step3_chatgpt_review,
    step4_gemini_feedback,
    step5_claude_final,
)

logger = logging.getLogger(__name__)

_OUTPUT_DIR = Path("/home/jay/workspace/memory/publishing")


class ChapterRunner:
    """챕터 단위 3대 엔진 합의도출 파이프라인."""

    def __init__(self, chapter: int, task_id: str, guide: str = "", chapter_info: str = "") -> None:
        self._chapter = chapter
        self._task_id = task_id
        self._guide = guide
        self._chapter_info = chapter_info
        self._adapter = PublishingAdapter()
        self._consensus = ConsensusPipeline()
        self._results: dict[str, list[EngineResult]] = {}

    async def run(self) -> dict[str, list[EngineResult]]:
        """전체 파이프라인 실행."""
        output_dir = _OUTPUT_DIR / f"chapter-{self._chapter}"
        output_dir.mkdir(parents=True, exist_ok=True)

        # Step 1: 병렬 초안 (Claude + Gemini)
        logger.info("Step 1: 병렬 초안 생성 (Claude + Gemini)")
        prompt = step1_parallel_draft(self._guide, self._chapter_info)
        step1_results = await self._adapter.run_step(
            prompts=[prompt, prompt],
            engines=["claude", "gemini"],
            task_id=self._task_id,
            step=1,
        )
        self._results["step1"] = step1_results
        self._save_step(output_dir, 1, step1_results)

        draft_claude = step1_results[0].content if len(step1_results) > 0 else ""
        draft_gemini = step1_results[1].content if len(step1_results) > 1 else ""

        # Step 2: Gemini 집대성 (비교분석 → 집대성 → 검증)
        logger.info("Step 2: Gemini 집대성")
        step2_prompts = step2_gemini_synthesis(draft_claude, draft_gemini)
        current_content = ""
        step2_results: list[EngineResult] = []
        for sub_prompt in step2_prompts:
            full_prompt = sub_prompt if not current_content else f"{sub_prompt}\n\n## 이전 결과\n{current_content}"
            results = await self._adapter.run_step(
                prompts=[full_prompt],
                engines=["gemini"],
                task_id=self._task_id,
                step=2,
            )
            step2_results.extend(results)
            if results and not results[0].error:
                current_content = results[0].content
        self._results["step2"] = step2_results
        self._save_step(output_dir, 2, step2_results)

        # Step 3-4: 반복 수렴 (최대 3라운드)
        logger.info("Step 3-4: ChatGPT 비평 → Gemini 반영 (최대 %d 라운드)", MAX_CONSENSUS_ROUNDS)
        self._consensus.reset()
        for round_num in range(1, MAX_CONSENSUS_ROUNDS + 1):
            # Step 3: ChatGPT 비평
            review_prompt = step3_chatgpt_review(current_content)
            step3_results = await self._adapter.run_step(
                prompts=[review_prompt],
                engines=["codex"],  # ChatGPT = Codex engine
                task_id=self._task_id,
                step=3,
            )
            self._results[f"step3_round{round_num}"] = step3_results

            if not self._consensus.should_continue(step3_results):
                logger.info("Round %d: 합의 달성 또는 최대 라운드 도달", round_num)
                break

            # Step 4: Gemini 피드백 반영
            feedback = step3_results[0].content if step3_results else ""
            fb_prompt = step4_gemini_feedback(current_content, feedback)
            step4_results = await self._adapter.run_step(
                prompts=[fb_prompt],
                engines=["gemini"],
                task_id=self._task_id,
                step=4,
            )
            self._results[f"step4_round{round_num}"] = step4_results
            if step4_results and not step4_results[0].error:
                current_content = step4_results[0].content
            self._save_step(output_dir, 4, step4_results)

        # Step 5: Claude 최종 통합
        logger.info("Step 5: Claude 최종 통합")
        final_prompt = step5_claude_final(current_content)
        step5_results = await self._adapter.run_step(
            prompts=[final_prompt],
            engines=["claude"],
            task_id=self._task_id,
            step=5,
        )
        self._results["step5"] = step5_results
        self._save_step(output_dir, 5, step5_results)

        return self._results

    def _save_step(self, output_dir: Path, step: int, results: list[EngineResult]) -> None:
        """Step 결과를 파일로 저장."""
        for i, result in enumerate(results):
            suffix = f"-{i}" if len(results) > 1 else ""
            filepath = output_dir / f"step-{step}{suffix}.md"
            filepath.write_text(result.content if not result.error else f"ERROR: {result.content}", encoding="utf-8")


def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
    """CLI 인수 파싱."""
    parser = argparse.ArgumentParser(description="3대 엔진 합의도출 챕터 실행")
    parser.add_argument("--chapter", type=int, required=True, help="챕터 번호")
    parser.add_argument("--task-id", type=str, required=True, help="작업 ID (예: task-XXX)")
    parser.add_argument("--guide", type=str, default="", help="집필가이드 텍스트 또는 파일 경로")
    parser.add_argument("--chapter-info", type=str, default="", help="챕터 정보")
    return parser.parse_args(argv)


async def main(argv: list[str] | None = None) -> None:
    """메인 진입점."""
    args = parse_args(argv)
    guide = args.guide
    if guide and Path(guide).is_file():
        guide = Path(guide).read_text(encoding="utf-8")

    runner = ChapterRunner(
        chapter=args.chapter,
        task_id=args.task_id,
        guide=guide,
        chapter_info=args.chapter_info,
    )
    results = await runner.run()
    logger.info("챕터 %d 완료. Step 수: %d", args.chapter, len(results))


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    asyncio.run(main())
