"""HTTP-based FoundryGraph client for company enrichment.

This module provides a lightweight HTTP client for the FoundryGraph API.
It implements the IFoundryGraphClient interface for use with the
resolution module.

Note: Local DuckDB serving and GCS artifact management are not included
here - those stay in fmatch.saas.adapters.
"""

from __future__ import annotations

import logging
import os
from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional

from ..types import CompanyProfile

logger = logging.getLogger(__name__)

# Default API endpoint
DEFAULT_API_BASE = (
    os.getenv("FOUNDRYGRAPH_API_BASE")
    or os.getenv("FM_FOUNDRYGRAPH_API")
    or "https://fuzzy-matcher-api-5pkec6diha-uc.a.run.app"
)
REMOTE_API_PREFIX = "/api/v2/foundrygraph"


class FoundryGraphError(RuntimeError):
    """Raised when FoundryGraph operations fail."""


@dataclass
class FoundryGraphConfig:
    """FoundryGraph client configuration."""
    api_base: str = field(default_factory=lambda: DEFAULT_API_BASE)
    api_token: Optional[str] = None
    timeout: float = 30.0


class FoundryGraphClient:
    """HTTP-based FoundryGraph client implementing IFoundryGraphClient.

    This client provides company lookup via the FoundryGraph remote API.
    It implements the IFoundryGraphClient protocol for use with the
    resolution module.

    Args:
        config: Optional configuration. If not provided, uses defaults.
        http_client: Optional HTTP client (requests.Session or similar).
                    If not provided, creates a new session.

    Example:
        >>> client = FoundryGraphClient()
        >>> profile = client.lookup_by_domain("microsoft.com")
        >>> print(profile.canonical_name)
        "Microsoft Corporation"
    """

    def __init__(
        self,
        config: Optional[FoundryGraphConfig] = None,
        http_client: Optional[Any] = None,
    ) -> None:
        self.config = config or FoundryGraphConfig()
        self._session = http_client
        self._session_created = False

    def _get_session(self) -> Any:
        """Get or create HTTP session."""
        if self._session is None:
            try:
                import requests
                self._session = requests.Session()
                self._session_created = True
            except ImportError:
                raise FoundryGraphError(
                    "requests library not installed. Run: pip install requests"
                )
        return self._session

    def _call_api(self, endpoint: str, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
        """Make an API call to FoundryGraph.

        Args:
            endpoint: API endpoint (e.g., "/lookup")
            params: Query parameters

        Returns:
            JSON response as dict

        Raises:
            FoundryGraphError: If the API call fails
        """
        session = self._get_session()
        url = f"{self.config.api_base}{REMOTE_API_PREFIX}{endpoint}"

        headers = {}
        if self.config.api_token:
            headers["Authorization"] = f"Bearer {self.config.api_token}"

        try:
            response = session.get(
                url,
                params=params,
                headers=headers,
                timeout=self.config.timeout,
            )
            response.raise_for_status()
            return response.json()
        except Exception as e:
            logger.debug("FoundryGraph API call failed: %s", e)
            raise FoundryGraphError(f"API call failed: {e}") from e

    def lookup_by_domain(self, domain: str) -> Optional[CompanyProfile]:
        """Look up a company by domain.

        Args:
            domain: Domain to look up (e.g., "microsoft.com")

        Returns:
            CompanyProfile if found, None otherwise
        """
        from ..normalization import normalize_domain

        normalized = normalize_domain(domain)
        if not normalized:
            return None

        try:
            data = self._call_api("/lookup", {"domain": normalized})
        except FoundryGraphError:
            return None

        if not data or not data.get("domain"):
            return None

        return CompanyProfile(
            domain=data.get("domain", ""),
            canonical_name=data.get("label") or data.get("canonical_name") or "",
            wikidata_id=data.get("wikidata_id"),
            description=data.get("description"),
            industry=data.get("industry"),
            employee_count=data.get("employee_count"),
            revenue=data.get("revenue"),
            country=data.get("country"),
            state=data.get("state"),
            city=data.get("city"),
            parent_domain=data.get("parent_domain"),
            ultimate_parent_domain=data.get("ultimate_parent_domain"),
        )

    def search_by_name(self, name: str, limit: int = 10) -> List[CompanyProfile]:
        """Search for companies by name.

        Args:
            name: Company name to search for
            limit: Maximum number of results

        Returns:
            List of matching CompanyProfiles
        """
        query = name.strip()
        if not query:
            return []

        try:
            data = self._call_api("/search", {"q": query, "limit": limit})
        except FoundryGraphError:
            return []

        results = data.get("results") or []
        profiles = []

        for item in results[:limit]:
            if not item.get("domain"):
                continue
            profiles.append(CompanyProfile(
                domain=item.get("domain", ""),
                canonical_name=item.get("label") or item.get("canonical_name") or "",
                wikidata_id=item.get("wikidata_id"),
                description=item.get("description"),
                industry=item.get("industry"),
            ))

        return profiles

    def ping(self) -> bool:
        """Check if the FoundryGraph API is reachable.

        Returns:
            True if the API responds, False otherwise
        """
        try:
            self._call_api("/ping")
            return True
        except FoundryGraphError:
            return False

    def close(self) -> None:
        """Close the HTTP session if we created it."""
        if self._session_created and self._session is not None:
            try:
                self._session.close()
            except Exception:
                pass
            self._session = None
            self._session_created = False

    def __enter__(self) -> "FoundryGraphClient":
        return self

    def __exit__(self, *args: Any) -> None:
        self.close()
