"""Affinity CRM tools for ecs-mcp."""

import os
from typing import Any

import httpx

from ecs_mcp import mcp

AFFINITY_BASE_URL = "https://api.affinity.co"


# ---------------------------------------------------------------------------
# Affinity API client helpers
# ---------------------------------------------------------------------------

def _get_api_key() -> str:
    key = os.environ.get("AFFINITY_API_KEY", "").strip()
    if not key:
        raise ValueError(
            "AFFINITY_API_KEY environment variable is not set. "
            "Add it to your Claude Desktop config under 'env'."
        )
    return key


def _client() -> httpx.AsyncClient:
    return httpx.AsyncClient(
        base_url=AFFINITY_BASE_URL,
        auth=("", _get_api_key()),
        headers={"Content-Type": "application/json"},
        timeout=30.0,
    )


async def _find_list_by_name(client: httpx.AsyncClient, list_name: str) -> dict[str, Any] | None:
    response = await client.get("/lists")
    response.raise_for_status()
    for lst in response.json():
        if lst.get("name", "").lower() == list_name.lower():
            return lst
    return None


async def _find_organization(client: httpx.AsyncClient, org_name: str) -> dict[str, Any] | None:
    response = await client.get("/organizations", params={"term": org_name})
    response.raise_for_status()
    orgs = response.json().get("organizations", [])
    if not orgs:
        return None
    for org in orgs:
        if org.get("name", "").lower() == org_name.lower():
            return org
    return orgs[0]


async def _create_organization(client: httpx.AsyncClient, org_name: str) -> dict[str, Any]:
    slug = "".join(c for c in org_name.lower() if c.isalnum())
    response = await client.post(
        "/organizations",
        json={"name": org_name, "domain": f"{slug}.com"},
    )
    response.raise_for_status()
    return response.json()


async def _create_list_entry(
    client: httpx.AsyncClient, list_id: int, entity_id: int
) -> dict[str, Any]:
    response = await client.post(
        f"/lists/{list_id}/list-entries",
        json={"entity_id": entity_id},
    )
    response.raise_for_status()
    return response.json()


# ---------------------------------------------------------------------------
# MCP tool
# ---------------------------------------------------------------------------

@mcp.tool()
async def create_deal(list_name: str, organization_name: str) -> str:
    """Add a company as a new deal entry on an Affinity CRM list.

    Finds or creates the organization in Affinity, then adds it to the
    specified list. Avoids creating duplicate organizations.

    Args:
        list_name: The exact name of the Affinity list (e.g. "ALL DEALS ECS").
        organization_name: The company name to add (e.g. "Acme Corp").
    """
    async with _client() as client:
        lst = await _find_list_by_name(client, list_name)
        if lst is None:
            return (
                f"Error: No Affinity list found with name '{list_name}'. "
                "Check the list name in Affinity and try again."
            )

        org = await _find_organization(client, organization_name)
        created_new = org is None
        if created_new:
            org = await _create_organization(client, organization_name)

        org_id: int = org["id"]
        entry = await _create_list_entry(client, lst["id"], org_id)

        org_status = "created new organization" if created_new else "found existing organization"
        return (
            f"Successfully added '{org.get('name', organization_name)}' to '{lst['name']}'.\n"
            f"  - Organization: {org_status} (id={org_id})\n"
            f"  - List entry id: {entry.get('id', '?')}\n"
            f"  - List: '{lst['name']}' (id={lst['id']})"
        )
