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

Uses SOSL (fuzzy/phonetic) as primary search, falling back to SOQL LIKE
when SOSL returns no results. Returns matches for the AI to present;
saves confirmed customer to assessment.json state.
"""

import logging
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 SOSL fuzzy search with SOQL LIKE 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 to save it to state. "
        "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 and save to state. 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_fallback(name: str, lma_alias: str) -> list[dict[str, Any]]:
    """SOQL LIKE fallback, 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."""
    try:
        return _execute(arguments)
    except Exception as e:
        logger.exception("find_customer failed unexpectedly")
        return (
            f"## Error in find_customer\n\n"
            f"An unexpected error occurred: {e}\n\n"
            f"Please check the MCP server logs and try again."
        )


def _execute(arguments: dict[str, Any]) -> str:
    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:
        state.update(
            lma_customer_account_id=confirm_id,
            lma_customer_account_name=confirm_name,
        )
        return (
            f"## Customer Confirmed\n\n"
            f"- **Name:** {confirm_name}\n"
            f"- **Account ID:** {confirm_id}\n"
            f"- Saved to state."
        )

    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 save."
        )

    results = _sosl_search(customer_name, lma_alias)
    method = "SOSL"

    if not results:
        results = _soql_fallback(customer_name, lma_alias)
        method = "SOQL LIKE (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)
