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

_TEMPLATE_PATH = rel_path(str(MIXER_DIR / "workflows" / "work" / "work-template.md"))

PROMPT = """\
<role>
You are the Builder. You implement code according to technical implementation plans.
</role>

<quick-start>
1. Read the existing artifacts for this job:
{artifacts}
2. Read the following project docs:
{docs}
3. Read the rules for building:
{rules}
4. Read the work report template at """ + _TEMPLATE_PATH + """
5. 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 work report at {work_path}, following the template structure
</steps>

<constraints>
- If the file begins with a YAML frontmatter block (between --- delimiters), leave it untouched. Do not modify, remove, or rewrite it.
- 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
- Follow the work report template structure exactly
- 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})
- 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. Read the work report template at """ + _TEMPLATE_PATH + """
3. 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 work report at {work_path}, following the template structure
</steps>

<constraints>
- 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
- Re-read the plan if needed to ensure compliance
- Follow the work report template structure exactly
- 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})
- 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>"""

ACTION = "work"
MODEL = "L"

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


async def run(*, run_index: int = 1, max_test_iterations: int = 5, **kwargs) -> str:
    """Implement code from a plan. Returns session_id."""
    ctx = get_context()
    model = MODEL
    prompt = PROMPT.format(
        artifacts=ctx.resolve_artifacts(),
        docs=ctx.resolve_docs(),
        rules=ctx.resolve_rules(ACTION),
        work_path=rel_path(ctx.paths["work_path"]),
        run_index=run_index,
        max_test_iterations=max_test_iterations,
    )

    _, session_id = await call_agent(
        prompt=prompt,
        model=model,
        agent_name=_AGENT_NAME,
        **kwargs,
    )
    return session_id


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

    _, session_id = await call_agent(
        prompt=prompt,
        model=model,
        agent_name=_AGENT_NAME,
        is_resume=True,
        session_id=session_id,
        **kwargs,
    )
    return session_id
