import json
import structlog

from app.configs import settings
from app.state import EngineeringState
from app.executors import get_executor, ExecutorResult

logger = structlog.get_logger()


class DeveloperAgent:
    """
    Developer Agent
    职责：代码开发、代码修改、功能实现
    支持多执行器：Claude Code、Codex、OpenHands
    """

    def __init__(self):
        self.logger = structlog.get_logger().bind(agent="developer")

    def develop(self, state: EngineeringState) -> ExecutorResult:
        """执行开发任务"""
        executor_name = state.get("selected_executor", settings.default_executor)
        sandbox_path = state.get("sandbox_path") or state.get("repo_path", ".")

        self.logger.info(
            "Developer starting",
            executor=executor_name,
            path=sandbox_path,
        )

        executor = get_executor(executor_name, sandbox_path)

        # Build the development task prompt
        task_prompt = self._build_task_prompt(state)
        context = {
            "architecture_plan": state.get("architecture_plan", {}),
            "project_analysis": state.get("project_analysis", {}),
        }

        result = executor.run(task_prompt, context)
        self.logger.info(
            "Developer finished",
            success=result.success,
            exit_code=result.exit_code,
        )
        return result

    def _build_task_prompt(self, state: EngineeringState) -> str:
        arch = state.get("architecture_plan", {})
        impl_plan = state.get("implementation_plan", [])
        current_task = state.get("current_task", "")

        lines = [f"## Development Task\n{state['user_request']}"]

        if current_task:
            lines.append(f"\n## Current Sub-task\n{current_task}")

        if impl_plan:
            lines.append("\n## Implementation Plan")
            for i, task in enumerate(impl_plan, 1):
                if isinstance(task, dict):
                    lines.append(f"{i}. [{task.get('agent', '')}] {task.get('title', '')}: {task.get('description', '')}")
                else:
                    lines.append(f"{i}. {task}")

        if arch:
            lines.append(f"\n## Architecture\n```json\n{json.dumps(arch, indent=2, ensure_ascii=False)[:3000]}\n```")

        lines.append("\nImplement the above. Write clean, well-commented, production-quality code.")
        return "\n".join(lines)

    def fix_bug(self, state: EngineeringState, bug_description: str) -> ExecutorResult:
        """修复 Bug"""
        executor_name = state.get("selected_executor", settings.default_executor)
        sandbox_path = state.get("sandbox_path") or state.get("repo_path", ".")
        executor = get_executor(executor_name, sandbox_path)

        review = state.get("review_result", {})
        test_output = state.get("test_result", {}).get("output", "")

        prompt = f"""## Bug Fix Task

### Original Request
{state['user_request']}

### Bug Description
{bug_description}

### Test Failure Output
```
{test_output[:2000]}
```

### Review Issues
{json.dumps(review, indent=2, ensure_ascii=False)[:2000]}

Fix all the bugs above. Do not break existing functionality.
"""
        return executor.run(prompt)
