"""Protocol interfaces for dependency injection.

These protocols define the contracts that adapters must implement,
enabling core logic to remain independent of infrastructure.

Usage:
    Core code depends on these interfaces, not concrete implementations.
    Infrastructure adapters (in fmatch.saas.adapters/) implement these
    interfaces to provide actual functionality.
"""

from __future__ import annotations

from typing import Any, Dict, List, Optional, Protocol, Tuple, runtime_checkable

from .company import CompanyProfile


@runtime_checkable
class IFoundryGraphClient(Protocol):
    """Interface for FoundryGraph data access.

    Implementations may use HTTP API, local DuckDB, or other backends.
    """

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

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

        Returns:
            CompanyProfile if found, None otherwise
        """
        ...

    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 CompanyProfile objects
        """
        ...


@runtime_checkable
class ILLMProvider(Protocol):
    """Interface for LLM-based operations.

    Implementations may use Vertex AI, OpenAI, Ollama, or other providers.
    """

    def generate_json(
        self,
        prompt: str,
        schema: Optional[Dict[str, Any]] = None,
        **options: Any,
    ) -> Dict[str, Any]:
        """Generate structured JSON output from a prompt.

        Args:
            prompt: The prompt to send to the LLM
            schema: Optional JSON schema for response validation
            **options: Provider-specific options (e.g., num_predict, temperature)

        Returns:
            Parsed JSON response from the LLM
        """
        ...


@runtime_checkable
class IRegistryDataSource(Protocol):
    """Interface for domain family registry data access.

    Implementations may load from YAML files, DuckDB, or other sources.
    """

    def get_family(self, domain: str) -> Optional[str]:
        """Get the family ID for a domain.

        Args:
            domain: The domain to look up

        Returns:
            Family ID if found, None otherwise
        """
        ...

    def lookup_by_name(self, name: str) -> Tuple[Optional[str], float]:
        """Look up family by company name.

        Args:
            name: Company name to search for

        Returns:
            Tuple of (family_id, confidence_score)
        """
        ...

    def get_display_name(self, family_id: str) -> Optional[str]:
        """Get display name for a family.

        Args:
            family_id: The family identifier

        Returns:
            Display name if found, None otherwise
        """
        ...
