"""Trello integration via Trello REST API."""

import os

import httpx

TRELLO_API = "https://api.trello.com/1"


def _auth_params() -> dict:
    """Return auth query params or raise with setup instructions."""
    api_key = os.environ.get("TRELLO_API_KEY")
    token = os.environ.get("TRELLO_TOKEN")

    if not api_key or not token:
        raise ValueError(
            "TRELLO_API_KEY and TRELLO_TOKEN not set. "
            "Go to https://trello.com/power-ups/admin, create a Power-Up, "
            "generate an API key, then click the Token link to authorize."
        )
    return {"key": api_key, "token": token}


async def handler(params: dict) -> dict:
    """Handle Trello operations."""
    action = params["action"]
    auth = _auth_params()

    try:
        async with httpx.AsyncClient(timeout=30) as client:
            if action == "list_boards":
                return await _list_boards(client, auth)
            elif action == "list_cards":
                return await _list_cards(client, auth, params)
            elif action == "create_card":
                return await _create_card(client, auth, params)
            elif action == "move_card":
                return await _move_card(client, auth, params)
            elif action == "add_comment":
                return await _add_comment(client, auth, params)
            elif action == "archive_card":
                return await _archive_card(client, auth, params)
            else:
                return {"success": False, "message": f"Unknown action: {action}", "data": {}}
    except ValueError:
        raise
    except httpx.HTTPStatusError as e:
        error_body = e.response.text[:500]
        return {"success": False, "message": f"Trello API error ({e.response.status_code}): {error_body}", "data": {}}
    except Exception as e:
        return {"success": False, "message": f"Error: {e}", "data": {}}


async def _list_boards(client: httpx.AsyncClient, auth: dict) -> dict:
    resp = await client.get(
        f"{TRELLO_API}/members/me/boards",
        params={**auth, "fields": "name,url,closed,dateLastActivity"},
    )
    resp.raise_for_status()
    data = resp.json()

    boards = [
        {
            "id": b["id"],
            "name": b.get("name", ""),
            "url": b.get("url", ""),
            "closed": b.get("closed", False),
            "last_activity": b.get("dateLastActivity", ""),
        }
        for b in data
        if not b.get("closed")
    ]
    return {
        "success": True,
        "message": f"Found {len(boards)} active board(s)",
        "data": {"boards": boards},
    }


async def _list_cards(client: httpx.AsyncClient, auth: dict, params: dict) -> dict:
    board_id = params.get("board_id")
    if not board_id:
        raise ValueError("'board_id' is required for list_cards")

    # Get lists first for context
    lists_resp = await client.get(
        f"{TRELLO_API}/boards/{board_id}/lists",
        params={**auth, "fields": "name"},
    )
    lists_resp.raise_for_status()
    lists_map = {item["id"]: item["name"] for item in lists_resp.json()}

    # Get cards
    resp = await client.get(
        f"{TRELLO_API}/boards/{board_id}/cards",
        params={**auth, "fields": "name,desc,idList,due,labels,closed,url,dateLastActivity"},
    )
    resp.raise_for_status()
    data = resp.json()

    cards = [
        {
            "id": c["id"],
            "name": c.get("name", ""),
            "description": (c.get("desc") or "")[:200],
            "list": lists_map.get(c.get("idList"), ""),
            "list_id": c.get("idList", ""),
            "due": c.get("due"),
            "labels": [lb.get("name") or lb.get("color", "") for lb in c.get("labels", [])],
            "url": c.get("url", ""),
        }
        for c in data
        if not c.get("closed")
    ]
    return {
        "success": True,
        "message": f"Found {len(cards)} card(s) across {len(lists_map)} list(s)",
        "data": {"lists": [{"id": k, "name": v} for k, v in lists_map.items()], "cards": cards},
    }


async def _create_card(client: httpx.AsyncClient, auth: dict, params: dict) -> dict:
    list_id = params.get("list_id")
    name = params.get("name")
    if not list_id or not name:
        raise ValueError("'list_id' and 'name' are required for create_card")

    body = {**auth, "idList": list_id, "name": name}
    if params.get("description"):
        body["desc"] = params["description"]
    if params.get("due"):
        body["due"] = params["due"]

    resp = await client.post(f"{TRELLO_API}/cards", params=body)
    resp.raise_for_status()
    data = resp.json()

    return {
        "success": True,
        "message": f"Created card '{name}'",
        "data": {"id": data["id"], "url": data.get("url", "")},
    }


async def _move_card(client: httpx.AsyncClient, auth: dict, params: dict) -> dict:
    card_id = params.get("card_id")
    list_id = params.get("list_id")
    if not card_id or not list_id:
        raise ValueError("'card_id' and 'list_id' are required for move_card")

    resp = await client.put(
        f"{TRELLO_API}/cards/{card_id}",
        params={**auth, "idList": list_id},
    )
    resp.raise_for_status()
    data = resp.json()

    return {
        "success": True,
        "message": f"Moved card '{data.get('name', '')}' to list {list_id}",
        "data": {"id": data["id"], "list_id": list_id},
    }


async def _add_comment(client: httpx.AsyncClient, auth: dict, params: dict) -> dict:
    card_id = params.get("card_id")
    comment = params.get("comment")
    if not card_id or not comment:
        raise ValueError("'card_id' and 'comment' are required for add_comment")

    resp = await client.post(
        f"{TRELLO_API}/cards/{card_id}/actions/comments",
        params={**auth, "text": comment},
    )
    resp.raise_for_status()
    data = resp.json()

    return {
        "success": True,
        "message": "Comment added",
        "data": {"id": data.get("id", "")},
    }


async def _archive_card(client: httpx.AsyncClient, auth: dict, params: dict) -> dict:
    card_id = params.get("card_id")
    if not card_id:
        raise ValueError("'card_id' is required for archive_card")

    resp = await client.put(
        f"{TRELLO_API}/cards/{card_id}",
        params={**auth, "closed": "true"},
    )
    resp.raise_for_status()

    return {
        "success": True,
        "message": f"Card {card_id} archived",
        "data": {"card_id": card_id},
    }
