"""
Pre-built multi-agent team configurations.

Provides ready-to-use Team presets built on Agno's Team class:
  - research_team()  — web research → analysis → report writing
  - code_team()      — architect → implementer → reviewer
  - data_team()      — data fetcher → analyst → visualizer/reporter

Each preset uses Agno's TeamMode.coordinate by default (leader decomposes,
delegates, and synthesizes). All members share a storage backend.

Usage:
    from agnoclaw.teams import research_team

    team = research_team(model_id="claude-sonnet-4-6")
    team.print_response("Research the state of fusion energy in 2026", stream=True)
"""

from __future__ import annotations

from pathlib import Path

from agno.team import Team, TeamMode

from .agent import AgentHarness, _make_db, _resolve_model
from .backends import RuntimeBackend
from .config import HarnessConfig, get_config
from .skills.backends import SkillInstallApprover
from .tools import (
    FilesToolkit,
    TodoToolkit,
    WebToolkit,
    make_bash_tool,
)


def _tool_workspace_dir(cfg: HarnessConfig) -> Path:
    return Path(cfg.workspace_dir).expanduser().resolve()


def _build_member_agent(
    *,
    name: str,
    role: str,
    model: str,
    cfg: HarnessConfig,
    db,
    tools: list,
    backend: RuntimeBackend | None = None,
    skill_install_approver: SkillInstallApprover | None = None,
    learning=None,
    enable_learning: bool = False,
):
    harness = AgentHarness(
        model=model,
        config=cfg,
        db=db,
        workspace_dir=_tool_workspace_dir(cfg),
        include_default_tools=False,
        tools=tools,
        name=name,
        instructions=role,
        enable_learning=enable_learning,
        debug=cfg.debug,
        backend=backend,
        skill_install_approver=skill_install_approver,
    )
    harness._agent.role = role
    if learning is not None:
        harness._agent.learning = learning
        harness._agent.add_learnings_to_context = enable_learning
    return harness._agent


def research_team(
    model_id: str | None = None,
    provider: str | None = None,
    config: HarnessConfig | None = None,
    session_id: str | None = None,
    enable_learning: bool = False,
    backend: RuntimeBackend | None = None,
    skill_install_approver: SkillInstallApprover | None = None,
) -> Team:
    """
    A three-agent research team:
      - Researcher: web search + source gathering
      - Analyst: synthesis + critical evaluation
      - Writer: final report production

    TeamMode: coordinate (leader delegates, synthesizes final output)
    """
    cfg = config or get_config()
    model_id = model_id or cfg.default_model
    provider = provider or cfg.default_provider
    db = _make_db(cfg)

    model = _resolve_model(model_id, provider, cfg)
    web = WebToolkit()

    # Learning machine for research patterns (namespaced to this team)
    _learning = None
    if enable_learning:
        from .memory import build_learning_machine
        _learning = build_learning_machine(db=db, namespace="research-team")

    researcher = _build_member_agent(
        name="Researcher",
        role=(
            "Find factual information from multiple sources. Search broadly, "
            "read deeply. Always cite URLs."
        ),
        model=model,
        tools=[web, TodoToolkit()],
        db=db,
        cfg=cfg,
        backend=backend,
        skill_install_approver=skill_install_approver,
        learning=_learning,
        enable_learning=enable_learning,
    )

    analyst = _build_member_agent(
        name="Analyst",
        role=(
            "Critically evaluate research findings. Identify consensus vs. contested claims. "
            "Note gaps, contradictions, and confidence levels. Do not fabricate."
        ),
        model=model,
        tools=[TodoToolkit()],
        db=db,
        cfg=cfg,
        backend=backend,
        skill_install_approver=skill_install_approver,
        learning=_learning,
        enable_learning=enable_learning,
    )

    writer = _build_member_agent(
        name="Writer",
        role=(
            "Produce clear, structured, well-cited reports from analysis. "
            "Use Markdown with headers, bullet points, and inline citations [Title](URL). "
            "Write for an expert audience — no fluff."
        ),
        model=model,
        tools=[],
        db=db,
        cfg=cfg,
        backend=backend,
        skill_install_approver=skill_install_approver,
        learning=_learning,
        enable_learning=enable_learning,
    )

    return Team(
        name="Research Team",
        model=model,
        mode=TeamMode.coordinate,
        members=[researcher, analyst, writer],
        instructions=(
            "1. Have the Researcher gather comprehensive information from multiple sources.\n"
            "2. Have the Analyst evaluate and synthesize the findings critically.\n"
            "3. Have the Writer produce a well-structured final report with citations.\n"
            "Do not skip steps. The final output must include sources."
        ),
        db=db,
        session_id=session_id,
        show_members_responses=True,
        markdown=True,
        learning=_learning,
        add_learnings_to_context=enable_learning,
    )


def code_team(
    model_id: str | None = None,
    provider: str | None = None,
    config: HarnessConfig | None = None,
    session_id: str | None = None,
    enable_learning: bool = False,
    backend: RuntimeBackend | None = None,
    skill_install_approver: SkillInstallApprover | None = None,
) -> Team:
    """
    A three-agent software development team:
      - Architect: design and planning
      - Implementer: code writing
      - Reviewer: code review and testing

    TeamMode: coordinate
    """
    cfg = config or get_config()
    model_id = model_id or cfg.default_model
    provider = provider or cfg.default_provider
    db = _make_db(cfg)

    model = _resolve_model(model_id, provider, cfg)
    workspace_dir = _tool_workspace_dir(cfg)
    resolved_backend = (backend or RuntimeBackend()).resolve(workspace_dir=workspace_dir)
    resolved_command_executor = resolved_backend.command_executor
    resolved_workspace_adapter = resolved_backend.workspace_adapter
    files = FilesToolkit(workspace_dir=workspace_dir, adapter=resolved_workspace_adapter)
    bash = make_bash_tool(
        timeout=cfg.bash_timeout_seconds,
        workspace_dir=workspace_dir,
        executor=resolved_command_executor,
    )

    # Learning for code patterns — namespaced separately from research
    _learning = None
    if enable_learning:
        from .memory import build_learning_machine
        _learning = build_learning_machine(db=db, namespace="code-team")

    architect = _build_member_agent(
        name="Architect",
        role=(
            "Design software solutions. Define interfaces, data models, module structure. "
            "Produce clear technical specs before any code is written. "
            "Consider maintainability, performance, and security."
        ),
        model=model,
        tools=[files, TodoToolkit()],
        db=db,
        cfg=cfg,
        backend=backend,
        skill_install_approver=skill_install_approver,
        learning=_learning,
        enable_learning=enable_learning,
    )

    implementer = _build_member_agent(
        name="Implementer",
        role=(
            "Write clean, correct, idiomatic code following the architect's spec. "
            "Read existing code before modifying. Write tests alongside implementation. "
            "Follow existing project conventions."
        ),
        model=model,
        tools=[files, bash, TodoToolkit()],
        db=db,
        cfg=cfg,
        backend=backend,
        skill_install_approver=skill_install_approver,
        learning=_learning,
        enable_learning=enable_learning,
    )

    reviewer = _build_member_agent(
        name="Reviewer",
        role=(
            "Review code for bugs, security issues, performance problems, and style. "
            "Run tests and verify they pass. "
            "Produce a structured review with P0/P1/P2/P3 priority issues. "
            "Approve or request changes with specific, actionable feedback."
        ),
        model=model,
        tools=[files, bash],
        db=db,
        cfg=cfg,
        backend=backend,
        skill_install_approver=skill_install_approver,
        learning=_learning,
        enable_learning=enable_learning,
    )

    return Team(
        name="Code Team",
        model=model,
        mode=TeamMode.coordinate,
        members=[architect, implementer, reviewer],
        instructions=(
            "1. Have the Architect design the solution and produce a spec.\n"
            "2. Have the Implementer write the code following the spec.\n"
            "3. Have the Reviewer review, run tests, and confirm correctness.\n"
            "The final output must include: working code + test results + review summary."
        ),
        db=db,
        session_id=session_id,
        show_members_responses=True,
        markdown=True,
        learning=_learning,
        add_learnings_to_context=enable_learning,
    )


def data_team(
    model_id: str | None = None,
    provider: str | None = None,
    config: HarnessConfig | None = None,
    session_id: str | None = None,
    backend: RuntimeBackend | None = None,
    skill_install_approver: SkillInstallApprover | None = None,
) -> Team:
    """
    A two-agent data analysis team:
      - Fetcher: data acquisition and preparation
      - Analyst: analysis, pattern finding, insight generation

    TeamMode: coordinate
    """
    cfg = config or get_config()
    model_id = model_id or cfg.default_model
    provider = provider or cfg.default_provider
    db = _make_db(cfg)

    model = _resolve_model(model_id, provider, cfg)
    workspace_dir = _tool_workspace_dir(cfg)
    resolved_backend = (backend or RuntimeBackend()).resolve(workspace_dir=workspace_dir)

    fetcher = _build_member_agent(
        name="DataFetcher",
        role=(
            "Acquire, clean, and prepare data. "
            "Fetch from APIs, files, or databases. "
            "Describe the data structure clearly for the analyst."
        ),
        model=model,
        tools=[
            WebToolkit(),
            FilesToolkit(
                workspace_dir=workspace_dir,
                adapter=resolved_backend.workspace_adapter,
            ),
            make_bash_tool(
                timeout=cfg.bash_timeout_seconds,
                workspace_dir=workspace_dir,
                executor=resolved_backend.command_executor,
            ),
        ],
        db=db,
        cfg=cfg,
        backend=backend,
        skill_install_approver=skill_install_approver,
    )

    analyst = _build_member_agent(
        name="DataAnalyst",
        role=(
            "Analyze prepared data to find patterns, trends, and insights. "
            "Be quantitative and precise. Distinguish correlation from causation. "
            "Present findings clearly with supporting numbers."
        ),
        model=model,
        tools=[
            FilesToolkit(
                workspace_dir=workspace_dir,
                adapter=resolved_backend.workspace_adapter,
            ),
            make_bash_tool(
                timeout=cfg.bash_timeout_seconds,
                workspace_dir=workspace_dir,
                executor=resolved_backend.command_executor,
            ),
        ],
        db=db,
        cfg=cfg,
        backend=backend,
        skill_install_approver=skill_install_approver,
    )

    return Team(
        name="Data Team",
        model=model,
        mode=TeamMode.coordinate,
        members=[fetcher, analyst],
        instructions=(
            "1. Have DataFetcher acquire and describe the relevant data.\n"
            "2. Have DataAnalyst perform rigorous analysis and present findings.\n"
            "Be quantitative. Include specific numbers, not vague summaries."
        ),
        db=db,
        session_id=session_id,
        show_members_responses=True,
        markdown=True,
    )
