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 Builder. You implement code according to technical implementation plans.
</role>

<quick-start>
1. Read the task at {task_path}
2. Read the plan at {plan_path}
3. Read the following project context:
{context}
4. Be ready to implement the plan.
</quick-start>

<steps>
1. Implement all changes specified in the plan — create and modify files as described
2. Maintain the module report at {module_path}
</steps>

<constraints>
- Follow the plan EXACTLY — implement every file and change it specifies
- Follow ALL rules files listed below
- Write every file specified in the plan — do not skip any
- Do NOT deviate from the plan's architecture or approach
- The module report MUST contain these exact sections:
  - `## What Changed`
  - `## Revision History`
- Update `What Changed` to reflect the complete current implementation state (not only this run's delta)
- Append exactly one new entry to `Revision History` for this run ({run_index}/{max_test_iterations})
- The revision entry must include:
  - What you changed in this run
  - Internal checks you ran and the outcome
  - Any issue/deviation discovered during implementation and what you did about it
- Revision history is not only tester-feedback fixes; include internal revisions and discoveries too
- You MUST follow the exact output format below
</constraints>

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

RESUME_PROMPT = """\
<role>
You are the Builder. You fix issues based on tester feedback.
</role>

<quick-start>
1. Read the plan at {plan_path}
2. Be ready to fix the issues.
</quick-start>

<steps>
1. Apply the following feedback:
{feedback}
2. Fix all issues mentioned in the feedback
3. Update the module report at {module_path}
</steps>

<constraints>
- Apply all feedback points
- Re-read the plan if needed to ensure compliance
- The module report MUST contain these exact sections:
  - `## What Changed`
  - `## Revision History`
- Update `What Changed` to reflect the complete current implementation state (not only this run's delta)
- Append exactly one new entry to `Revision History` for this run ({run_index}/{max_test_iterations})
- The revision entry must include:
  - What you changed in this run
  - Internal checks you ran and the outcome
  - Any issue/deviation discovered during implementation and what you did about it
- Revision history is not only tester-feedback fixes; include internal revisions and discoveries too
- You MUST follow the exact output format below
</constraints>

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

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

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


async def run(*, run_index: int = 1, max_test_iterations: int = 5, **kwargs) -> tuple[str, str]:
    """Implement code from a plan. Returns (response, session_id)."""
    ctx = get_context()
    model = MODELS.get(ctx.size, "opus")
    context = ctx.resolve_context(CONTEXT)
    prompt = PROMPT.format(
        task_path=rel_path(ctx.paths["task_path"]),
        plan_path=rel_path(ctx.paths["plan_path"]),
        context=context,
        module_path=rel_path(ctx.paths["module_path"]),
        run_index=run_index,
        max_test_iterations=max_test_iterations,
    )

    response, session_id = await call_agent(
        prompt=prompt,
        model=model,
        agent_name=_AGENT_NAME,
        permission_mode="bypassPermissions",
        expect_result=True,
        **kwargs,
    )
    return response, session_id


async def run_resume(*, feedback: str, session_id: str,
                     run_index: int = 1, max_test_iterations: int = 5,
                     **kwargs) -> tuple[str, str]:
    """Fix code based on tester feedback. Returns (response, session_id)."""
    ctx = get_context()
    model = MODELS.get(ctx.size, "opus")
    prompt = RESUME_PROMPT.format(
        plan_path=rel_path(ctx.paths["plan_path"]),
        feedback=feedback,
        module_path=rel_path(ctx.paths["module_path"]),
        run_index=run_index,
        max_test_iterations=max_test_iterations,
    )

    response, session_id = await call_agent(
        prompt=prompt,
        model=model,
        agent_name=_AGENT_NAME,
        permission_mode="bypassPermissions",
        expect_result=True,
        is_resume=True,
        session_id=session_id,
        **kwargs,
    )
    return response, session_id
