"""
Clearbit enrichment client (company-first; person can be added later).

Implements company enrichment via:
  GET https://company.clearbit.com/v2/companies/find?domain=...
Auth: HTTP Basic with API key as username, blank password.
"""

from __future__ import annotations

from typing import Any, Dict, List, Optional

import click
from g_gremlin.base import AuthenticationError, BaseIntegration, IntegrationError, RateLimitError, RetryConfig
from g_gremlin.credentials import resolve_credentials
from g_gremlin.credentials.provider import CredentialProvider, SecretNotFoundError

CLEARBIT_DEFAULT_BASE = "https://company.clearbit.com"
COMPANY_ENRICH_PATH = "/v2/companies/find"
DEFAULT_RETRY_CONFIG = RetryConfig(max_attempts=3, base_delay=1.0, max_delay=8.0)


class ClearbitError(RuntimeError):
    """Raised when Clearbit enrichment fails."""


def _load_api_settings(
    credential_provider: CredentialProvider | None = None,
    api_key: Optional[str] = None,
    api_base: Optional[str] = None,
) -> tuple[str, str]:
    """Load Clearbit API key (and optional api_base) via CredentialProvider."""
    if api_key and api_base:
        return api_key, api_base

    provider = credential_provider or CredentialProvider()
    try:
        creds = resolve_credentials(
            "clearbit",
            required_keys=["api_key"],
            optional_keys=["api_base"],
            credential_provider=provider,
        )
        return creds["api_key"], creds.get("api_base") or CLEARBIT_DEFAULT_BASE
    except SecretNotFoundError:
        raise click.ClickException(
            "Clearbit not configured. Set up with:\n"
            "  g-gremlin auth set clearbit                # Store in keychain\n"
            "  export G_GREMLIN_CLEARBIT_API_KEY=your-key # Or use env var"
        )


def _extract_company_fields(data: Dict[str, Any]) -> Dict[str, Any]:
    """Normalize Clearbit company response to common fields."""
    if not data:
        return {}

    geo = data.get("geo") or {}
    metrics = data.get("metrics") or {}

    return {
        "name": data.get("name"),
        "domain": data.get("domain") or data.get("site", {}).get("domain"),
        "website": data.get("site", {}).get("url") or data.get("url"),
        "industry": data.get("category", {}).get("industry"),
        "employee_count": metrics.get("employees"),
        "employee_range": metrics.get("employeesRange"),
        "revenue": metrics.get("annualRevenue"),
        "founded_year": metrics.get("foundedYear") or data.get("foundedYear"),
        "linkedin_url": (data.get("linkedin") or {}).get("handle"),
        "twitter_url": (data.get("twitter") or {}).get("handle"),
        "logo": data.get("logo"),
        "country": geo.get("country"),
        "region": geo.get("state"),
        "locality": geo.get("city"),
    }


class ClearbitClient(BaseIntegration):
    """Clearbit client using BaseIntegration for retries and logging."""

    SERVICE_NAME = "clearbit"

    def __init__(
        self,
        credential_provider: CredentialProvider | None = None,
        api_key: Optional[str] = None,
        api_base: Optional[str] = None,
        retry_config: RetryConfig | None = None,
    ) -> None:
        super().__init__(credential_provider=credential_provider, default_retry_config=retry_config or DEFAULT_RETRY_CONFIG)
        self.api_key, self.api_base = _load_api_settings(credential_provider, api_key, api_base)

    def enrich_company(self, domain: str, fields: Optional[List[str]] = None) -> Dict[str, Any]:
        domain_clean = (domain or "").strip()
        if not domain_clean:
            return {}

        url = f"{self.api_base.rstrip('/')}{COMPANY_ENRICH_PATH}"
        try:
            resp = self._get(
                url,
                params={"domain": domain_clean},
                auth=(self.api_key, ""),
                allow_statuses=(404,),
            )
        except (AuthenticationError, RateLimitError, IntegrationError) as exc:
            raise ClearbitError(str(exc)) from exc

        if resp.status_code == 404:
            return {}

        try:
            data = resp.json()
        except Exception as exc:  # pragma: no cover - network parsing
            raise ClearbitError(f"Failed to parse Clearbit response: {exc}") from exc

        normalized = _extract_company_fields(data)
        if fields:
            return {k: normalized.get(k) for k in fields if k in normalized}
        return normalized


def enrich_company(domain: str, fields: Optional[List[str]] = None) -> Dict[str, Any]:
    """
    Enrich a company by domain using Clearbit.

    Args:
        domain: Company domain (e.g., "slack.com").
        fields: Optional list of fields to project.

    Returns:
        Dict with normalized fields (see _extract_company_fields), or {} if not found.
    """
    client = ClearbitClient()
    try:
        return client.enrich_company(domain, fields)
    except ClearbitError as exc:
        raise click.ClickException(str(exc)) from exc


__all__ = [
    "ClearbitError",
    "ClearbitClient",
    "enrich_company",
]
