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

_TEMPLATE_PATH = rel_path(str(Path(__file__).parent / "plan-template.md"))
MODEL = "L"
_AGENT_NAME = "plan_builder"

PROMPT = """\
{role}

<quick-start>
0. When reading any file, ignore everything after the `<!-- appendix -->` marker and inside `<ignore>` tags — that content is internal metadata, not input for your work.
1. Read the existing artifacts for this job:
{artifacts}
2. Read the following project docs:
{docs}
3. Read the rules for creating plans:
{rules}
4. Read the specific instructions (if any):
{instructions}
5. Read the plan template at """ + _TEMPLATE_PATH + """
6. Be ready to design a thorough implementation plan.
</quick-start>
{merger_section}
<steps>
1. Design a plan that addresses all requirements, following the template structure and rules
2. Write your complete plan to {plan_path}
</steps>

<constraints>
- When reading files, ignore all content after `<!-- appendix -->` and inside `<ignore>` tags
- Follow the template structure exactly
- Be thorough — this plan will be used by engineers to build the feature
- You MUST follow the exact output format below
</constraints>

<output-format>
[RESULT]
status: DONE
[NOTES]
Summary of the plan.
</output-format>"""

RESUME_PROMPT = """\
<role>
You are the Plan Builder. You revise plans based on reviewer feedback.
</role>

<quick-start>
0. When reading any file, ignore everything after the `<!-- appendix -->` marker and inside `<ignore>` tags — that content is internal metadata, not input for your work.
1. Read the plan at {plan_path}
2. Be ready to revise the plan.
</quick-start>

<steps>
1. Apply the following feedback:
{feedback}
2. Write the updated plan back to {plan_path}
</steps>

<constraints>
- When reading files, ignore all content after `<!-- appendix -->` and inside `<ignore>` tags
- If the file begins with a YAML frontmatter block (between --- delimiters), leave it untouched. Do not modify, remove, or rewrite it.
- Apply all feedback points
- Write the updated plan back to the same path
- You MUST follow the exact output format below
</constraints>

<output-format>
[RESULT]
status: DONE
[NOTES]
Summary of what was revised.
</output-format>"""


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


async def run(*, provider: str | None = None,
              merger_feedback: str | None = None,
              instructions: str | None = None, **kwargs) -> str:
    """Build a plan. Returns session_id."""
    ctx = get_context()
    chosen_provider = _provider(provider)
    model = MODEL

    merger_section = ""
    if merger_feedback:
        merger_section = (
            "\n<merger-feedback>\n"
            "Multiple branch plans were drafted and reviewed by the merger agent. "
            "Use this synthesis feedback to inform your plan:\n\n"
            f"{merger_feedback}\n"
            "</merger-feedback>\n"
        )

    plan_path = ctx.paths["plan_path"]
    task_path = ctx.paths["task_path"]

    role_lines = ["You are the Plan Builder. You must read all provided inputs."]
    if Path(task_path).is_file():
        role_lines.append("Follow the task requirements.")
    if Path(plan_path).is_file():
        role_lines.append(f"A previous version of {rel_path(plan_path)} exists. Revise it based on the new inputs — do not start from scratch.")
    if instructions:
        role_lines.append("Follow the additional instructions provided.")
    role_lines.append("The instructions always take priority over other inputs.")
    role = "<role>\n" + "\n".join(role_lines) + "\n</role>"

    extra_prompt = PROMPT.format(
        role=role,
        artifacts=ctx.resolve_artifacts(),
        docs=ctx.resolve_docs(),
        rules=ctx.resolve_rules(_AGENT_NAME.split("_", 1)[0]),
        instructions=instructions or "",
        plan_path=rel_path(plan_path),
        merger_section=merger_section,
    )

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


async def run_resume(*, feedback: str, session_id: str,
                     provider: str | None = None, **kwargs) -> str:
    """Revise a plan based on feedback."""
    ctx = get_context()
    chosen_provider = _provider(provider)
    model = MODEL
    extra_prompt = RESUME_PROMPT.format(
        plan_path=rel_path(ctx.paths["plan_path"]),
        feedback=feedback,
    )

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