"""indiaopt — Enterprise-grade NSE & BSE market data library.

Public API surface — import everything you need from here:

    from indiaopt import NSEClient, BSEClient, OptionChainResult, IndiaOptError
    from indiaopt import get_client, fetch_option_chain

Example::

    import asyncio
    from indiaopt import NSEClient

    async def main():
        async with NSEClient() as client:
            result = await client.fetch_option_chain("NIFTY", is_index=True)
            print(result.spot_price, result.atm_strike)
            for row in result.data:
                print(row.strike, row.call_oi, row.put_oi)

    asyncio.run(main())
"""

from indiaopt._version import __version__
from indiaopt.config.settings import Settings, get_settings
from indiaopt.exceptions import (
    CircuitOpenError,
    ConfigurationError,
    FetchError,
    FetchTimeoutError,
    IndiaOptError,
    NetworkError,
    ParseError,
    RateLimitError,
    ValidationError,
)
from indiaopt.exchanges.bse import BSEClient
from indiaopt.exchanges.factory import get_client
from indiaopt.exchanges.nse import NSEClient
from indiaopt.models.option_chain import OptionChainResult, OptionChainRow


async def fetch_option_chain(
    symbol: str,
    *,
    is_index: bool = True,
    exchange: str = "NSE",
    settings: Settings | None = None,
) -> OptionChainResult:
    """Convenience coroutine — fetch option chain for one symbol.

    Args:
        symbol:    Instrument symbol (e.g. ``"NIFTY"``, ``"BANKNIFTY"``).
        is_index:  ``True`` for index instruments, ``False`` for equities.
        exchange:  ``"NSE"`` (default) or ``"BSE"``.
        settings:  Optional :class:`~indiaopt.config.settings.Settings` override.

    Returns:
        :class:`~indiaopt.models.option_chain.OptionChainResult`

    Raises:
        :class:`~indiaopt.exceptions.FetchError`: on unrecoverable fetch failure.
        :class:`~indiaopt.exceptions.CircuitOpenError`: when circuit breaker is open.
        :class:`~indiaopt.exceptions.FetchTimeoutError`: when fetch exceeds timeout.
    """
    client = get_client(exchange=exchange, settings=settings)
    async with client:
        return await client.fetch_option_chain(symbol, is_index=is_index)


__all__ = [
    "__version__",
    # Exceptions
    "IndiaOptError",
    "FetchError",
    "NetworkError",
    "RateLimitError",
    "ParseError",
    "CircuitOpenError",
    "FetchTimeoutError",
    "ConfigurationError",
    "ValidationError",
    # Models
    "OptionChainRow",
    "OptionChainResult",
    # Clients
    "NSEClient",
    "BSEClient",
    "get_client",
    # Config
    "Settings",
    "get_settings",
    # Convenience
    "fetch_option_chain",
]
