from __future__ import annotations

from investly.domain import Bar, Fundamentals, Market, Quote
from investly.providers.base import MarketDataProvider


class ProviderRouter:
    name = "router"

    def __init__(
        self,
        primary: MarketDataProvider,
        fallbacks: list[MarketDataProvider] | None = None,
    ) -> None:
        self.primary = primary
        self.fallbacks = fallbacks or []

    @property
    def providers(self) -> list[MarketDataProvider]:
        return [self.primary, *self.fallbacks]

    def quote(self, market: Market, symbol: str) -> Quote:
        errors: list[str] = []
        for provider in self.providers:
            try:
                return provider.quote(market, symbol)
            except Exception as exc:
                errors.append(f"{provider.name}: {type(exc).__name__}: {exc}")
        raise RuntimeError(f"all providers failed for quote: {' | '.join(errors)}")

    def history(self, market: Market, symbol: str, days: int = 260) -> list[Bar]:
        errors: list[str] = []
        for provider in self.providers:
            try:
                return provider.history(market, symbol, days)
            except Exception as exc:
                errors.append(f"{provider.name}: {type(exc).__name__}: {exc}")
        raise RuntimeError(f"all providers failed for history: {' | '.join(errors)}")

    def fundamentals(self, market: Market, symbol: str) -> Fundamentals:
        errors: list[str] = []
        for provider in self.providers:
            try:
                return provider.fundamentals(market, symbol)
            except Exception as exc:
                errors.append(f"{provider.name}: {type(exc).__name__}: {exc}")
        raise RuntimeError(f"all providers failed for fundamentals: {' | '.join(errors)}")
