"""Entity health and plan details tools."""

from __future__ import annotations

from cube_common.apollo_client import ApolloClient, ApolloError
from cube_common import apollo_queries as Q
from cube_common.apollo_models import format_entity_health, format_plan_details

from cube_cloud.tools.environments import _resolve_environment


async def entity_health(
    client: ApolloClient, environment: str, entity_id: str | None = None
) -> str:
    env_info = await _resolve_environment(client, environment)
    environment_id = env_info["id"]
    env_name = env_info.get("name", environment)

    data = await client.graphql(Q.ENVIRONMENT_ENTITIES, {"id": environment_id})
    env = data.get("apollo", {}).get("environmentById")
    if not env:
        return f"Environment not found: {environment_id}"

    all_entities = env.get("entities", {}).get("entities", [])
    if not all_entities:
        return f"No entities found in environment: {env.get('name', env_name)}"

    if entity_id:
        search = entity_id.lower()
        matched = [
            e for e in all_entities
            if search in (e.get("displayName") or e.get("id") or "").lower()
        ]
        if not matched:
            names = [e.get("displayName") or e.get("id") for e in all_entities]
            return (
                f"Entity '{entity_id}' not found. Available entities:\n"
                + "\n".join(f"  - {n}" for n in names)
            )
        entities = matched
    else:
        entities = all_entities

    lines = [f"Entity Health: {env.get('name', env_name)}", "=" * 50]
    lines.append(f"{len(entities)} entit{'y' if len(entities) == 1 else 'ies'}\n")

    for entity in entities:
        lines.extend(format_entity_health(entity))
        lines.append("")

    return "\n".join(lines)


async def plan_details(
    client: ApolloClient,
    environment: str,
    entity_name: str,
    plan_index: int = 0,
) -> str:
    env_info = await _resolve_environment(client, environment)
    env_id = env_info["id"]
    env_name = env_info.get("name", environment)

    data = await client.graphql(Q.PLAN_DETAILS, {"id": env_id})
    env = data.get("apollo", {}).get("environmentById")
    if not env:
        return f"Environment not found: {env_id}"

    all_entities = env.get("entities", {}).get("entities", [])
    if not all_entities:
        return f"No entities in environment: {env_name}"

    search = entity_name.lower()
    matched = [
        e for e in all_entities
        if search in (e.get("displayName") or "").lower()
        or search in (e.get("entityLocator", {}).get("entityName") or "").lower()
    ]

    if not matched:
        names = sorted(set(
            e.get("displayName") or e.get("entityLocator", {}).get("entityName", "") or e.get("id", "")
            for e in all_entities
        ))
        return (
            f"Entity '{entity_name}' not found in {env_name}.\n\n"
            f"Available entities:\n" + "\n".join(f"  - {n}" for n in names)
        )

    if len(matched) > 1:
        exact = [
            e for e in matched
            if (e.get("displayName") or "").lower() == search
            or (e.get("entityLocator", {}).get("entityName") or "").lower() == search
        ]
        if len(exact) == 1:
            matched = exact
        else:
            names = [e.get("displayName") or e.get("id") for e in matched]
            return (
                f"Multiple entities match '{entity_name}':\n"
                + "\n".join(f"  - {n}" for n in names)
                + "\n\nPlease be more specific."
            )

    return format_plan_details(matched[0], env_name, plan_index)
