from pathlib import Path
from mixersystem.data.repository import get_context, rel_path
from mixersystem.data.agent_sdk import call_agent

PROMPT = """\
<role>
You are the Plan Merger. You synthesize multiple branch plans into one final plan.
</role>

<quick-start>
1. Read the task at {task_path}
2. Read the following branch plans:
{branch_plan_paths}
3. Read the following project context:
{context}
4. Be ready to synthesize one final implementation plan.
</quick-start>

<steps>
1. Merge all branch plans into one cohesive final plan
2. Resolve overlaps and conflicts while preserving correctness
3. Write the merged plan to {plan_path}
</steps>

<constraints>
- Preserve required technical details from branch plans
- Remove duplicates and contradictions
- Keep the final plan executable by engineers
- You MUST follow the exact output format below
</constraints>

<output-format>
[RESULT]
status: DONE
[NOTES]
What was merged and which conflicts were resolved.
</output-format>"""

RESUME_PROMPT = """\
<role>
You are the Plan Merger. You revise a merged plan based on reviewer feedback.
</role>

<quick-start>
1. Read the merged plan at {plan_path}
2. Read the branch plans for source details:
{branch_plan_paths}
3. Be ready to revise the merged plan.
</quick-start>

<steps>
1. Apply the following feedback:
{feedback}
2. Update the merged plan at {plan_path}
</steps>

<constraints>
- Apply all feedback points
- Keep the plan coherent and implementation-ready
- You MUST follow the exact output format below
</constraints>

<output-format>
[RESULT]
status: DONE
[NOTES]
What was revised and why.
</output-format>"""

CONTEXT = ["doc", "structure", "rules"]
MODELS = {"S": "sonnet", "M": "opus", "L": "opus"}

_AGENT_NAME = Path(__file__).parent.parent.name + "/" + Path(__file__).stem


def _provider(provider: str | None = None) -> str:
    return provider or "claude"


def _format_paths(paths: list[str]) -> str:
    return "\n".join(f"- {rel_path(p)}" for p in paths)


async def run(*, branch_plan_paths: list[str],
              provider: str | None = None, **kwargs) -> str:
    """Merge branch plans into the primary plan.md. Returns merger session_id."""
    ctx = get_context()
    chosen_provider = _provider(provider)
    model = MODELS.get(ctx.size, "opus")
    context = ctx.resolve_context(CONTEXT)
    prompt = PROMPT.format(
        task_path=rel_path(ctx.paths["task_path"]),
        branch_plan_paths=_format_paths(branch_plan_paths),
        context=context,
        plan_path=rel_path(ctx.paths["plan_path"]),
    )

    _, session_id = await call_agent(
        prompt=prompt,
        model=model,
        provider=chosen_provider,
        permission_mode="bypassPermissions",
        approval_mode="yolo",
        agent_name=_AGENT_NAME,
        expect_result=True,
        **kwargs,
    )
    return session_id


async def run_resume(*, feedback: str, session_id: str, branch_plan_paths: list[str],
                     provider: str | None = None, **kwargs) -> str:
    """Revise merged plan based on review feedback. Returns next session_id."""
    ctx = get_context()
    chosen_provider = _provider(provider)
    model = MODELS.get(ctx.size, "opus")
    prompt = RESUME_PROMPT.format(
        plan_path=rel_path(ctx.paths["plan_path"]),
        branch_plan_paths=_format_paths(branch_plan_paths),
        feedback=feedback,
    )

    _, next_session_id = await call_agent(
        prompt=prompt,
        model=model,
        provider=chosen_provider,
        permission_mode="bypassPermissions",
        approval_mode="yolo",
        agent_name=_AGENT_NAME,
        expect_result=True,
        is_resume=True,
        session_id=session_id,
        **kwargs,
    )
    return next_session_id
