from __future__ import annotations

import logging
import shutil
import time
from pathlib import Path

from claude_teams import acpx_client, messaging, teams
from claude_teams.models import COLOR_PALETTE, InboxMessage, TeammateMember
from claude_teams.teams import _VALID_NAME_RE

logger = logging.getLogger(__name__)


def discover_harness_binary(name: str) -> str | None:
    return shutil.which(name)


def assign_color(team_name: str, base_dir: Path | None = None) -> str:
    config = teams.read_config(team_name, base_dir)
    count = sum(1 for m in config.members if isinstance(m, TeammateMember))
    return COLOR_PALETTE[count % len(COLOR_PALETTE)]


async def kill_acpx_session(agent: str, session_name: str, acpx_binary: str, cwd: str) -> None:
    """Best-effort: close an acpx session. Logs on failure, never raises."""
    try:
        await acpx_client.close_session(agent, session_name, cwd, acpx_binary=acpx_binary)
    except Exception as exc:
        logger.warning("Failed to close acpx session %r: %s", session_name, exc)


def spawn_teammate(
    team_name: str,
    name: str,
    acpx_binary: str,
    lead_session_id: str,
    *,
    model: str = "sonnet",
    subagent_type: str = "kiro",
    cwd: str | None = None,
    plan_mode_required: bool = False,
    base_dir: Path | None = None,
) -> TeammateMember:
    if not _VALID_NAME_RE.match(name):
        raise ValueError(
            f"Invalid agent name: {name!r}. Use only letters, numbers, hyphens, underscores."
        )
    if len(name) > 64:
        raise ValueError(f"Agent name too long ({len(name)} chars, max 64)")
    if name == "team-lead":
        raise ValueError("Agent name 'team-lead' is reserved")

    resolved_cwd = cwd or str(Path.cwd())
    session_name = f"{name}@{team_name}"

    color = assign_color(team_name, base_dir)
    now_ms = int(time.time() * 1000)

    member = TeammateMember(
        agent_id=session_name,
        name=name,
        agent_type=subagent_type,
        model=model,
        color=color,
        plan_mode_required=plan_mode_required,
        joined_at=now_ms,
        acpx_session_name=session_name,
        cwd=resolved_cwd,
        is_active=False,
    )

    # Create the acpx session first (before adding to config)
    acpx_client.create_session(subagent_type, session_name, resolved_cwd, acpx_binary=acpx_binary)

    member_added = False
    try:
        teams.add_member(team_name, member, base_dir)
        member_added = True

        messaging.ensure_inbox(team_name, name, base_dir)
    except Exception:
        kill_acpx_session(subagent_type, session_name, acpx_binary, resolved_cwd)
        if member_added:
            try:
                teams.remove_member(team_name, name, base_dir)
            except Exception:
                pass
        raise

    return member
