"""find_customer -- Search for a customer in the License Portal.

Uses SOQL LIKE as primary search, falling back to SOSL (fuzzy/phonetic)
when SOQL returns no results. Returns matches for the AI to present.
On confirmation, returns account_id and account_name for the AI to
pass explicitly to downstream tools.
"""

import logging
import re
from typing import Any

from ..utils import sf_cli, state

logger = logging.getLogger(__name__)

TOOL_DEFINITION = {
    "name": "find_customer",
    "description": (
        "Search for a customer by name in the CloudSense License Management "
        "Portal. Uses SOQL LIKE search with SOSL fuzzy fallback. Returns "
        "matching accounts for the AI to present to the user. "
        "Once the user confirms a customer, call this tool again with "
        "confirm_account_id and confirm_account_name — the tool returns "
        "account_id and account_name for you to pass to downstream tools. "
        "Requires connect_lma first."
    ),
    "inputSchema": {
        "type": "object",
        "properties": {
            "customer_name": {
                "type": "string",
                "description": (
                    "Customer name to search for. Handles partial matches "
                    "and misspellings. Examples: 'nbnco', 'NBN Co', 'starhub'"
                ),
            },
            "confirm_account_id": {
                "type": "string",
                "description": (
                    "Account ID to confirm. Pass this after the user has "
                    "confirmed the correct account from search results."
                ),
            },
            "confirm_account_name": {
                "type": "string",
                "description": (
                    "Account name corresponding to confirm_account_id."
                ),
            },
            "working_directory": {
                "type": "string",
                "description": "Workspace directory. The AI passes this automatically.",
            },
        },
        "required": [],
    },
}


def _get_lma_alias() -> str:
    """Read the LMA org alias from state, or return default."""
    existing = state.load()
    return existing.get("lma_org_alias") or "cs-lma"


def _sosl_search(name: str, lma_alias: str) -> list[dict[str, Any]]:
    """SOSL fuzzy search against Account, excluding Prospects."""
    try:
        return sf_cli.sosl_search(
            search_term=name,
            returning="Account(Id, Name, Type WHERE Type != 'Prospect')",
            target_org=lma_alias,
        )
    except sf_cli.SfCliError as e:
        logger.warning("SOSL search failed: %s", e)
        return []


def _soql_search(name: str, lma_alias: str) -> list[dict[str, Any]]:
    """SOQL LIKE search against Account, excluding Prospects."""
    safe_name = name.replace("'", "\\'")
    query = (
        f"SELECT Id, Name, Type FROM Account "
        f"WHERE Name LIKE '%{safe_name}%' "
        f"AND (Type != 'Prospect' OR Type = null) "
        f"ORDER BY Name LIMIT 25"
    )
    return sf_cli.lma_query(query, lma_alias)


async def run(arguments: dict[str, Any]) -> str:
    """Execute the find_customer tool."""
    state.set_working_dir(arguments.get("working_directory"))

    lma_alias = _get_lma_alias()
    confirm_id = arguments.get("confirm_account_id")
    confirm_name = arguments.get("confirm_account_name")

    if confirm_id and confirm_name:
        slug = re.sub(r"[^a-z0-9]+", "-", confirm_name.lower().strip()).strip("-") or "unknown"
        return (
            f"## Customer Confirmed\n\n"
            f"- **Name:** {confirm_name}\n"
            f"- **Account ID:** {confirm_id}\n"
            f"- **Folder:** customers/{slug}/\n\n"
            f"Pass account_id='{confirm_id}' and "
            f"account_name='{confirm_name}' to subsequent tools."
        )

    customer_name = arguments.get("customer_name")
    if not customer_name:
        return (
            "## Error\n\n"
            "Provide either `customer_name` to search, or "
            "`confirm_account_id` + `confirm_account_name` to confirm."
        )

    results = _soql_search(customer_name, lma_alias)
    method = "SOQL LIKE"

    if not results:
        results = _sosl_search(customer_name, lma_alias)
        method = "SOSL (fallback)"

    lines = [
        f"## Find Customer\n",
        f"- **Search term:** {customer_name}",
        f"- **Method:** {method}",
        f"- **Matches:** {len(results)}\n",
    ]

    if not results:
        lines.append(
            "No accounts found. Try a shorter or different search term."
        )
        return "\n".join(lines)

    lines.append("| # | Account Name | Type | Account ID |")
    lines.append("|---|-------------|------|------------|")
    for i, acct in enumerate(results, 1):
        aid = acct.get("Id", "")
        name = acct.get("Name", "")
        atype = acct.get("Type") or "—"
        lines.append(f"| {i} | {name} | {atype} | {aid} |")

    return "\n".join(lines)
