from __future__ import annotations

import uuid
from dataclasses import asdict, dataclass
from datetime import datetime

from investly.domain import Market, Recommendation, Strategy
from investly.engine.baseline import make_recommendation
from investly.engine.features import feature_set
from investly.providers.base import MarketDataProvider


@dataclass
class AnalysisService:
    provider: MarketDataProvider

    def analyze(
        self,
        market: Market,
        symbols: list[str],
        decision_at: datetime | None = None,
    ) -> list[Recommendation]:
        run_id = str(uuid.uuid4())
        recommendations: list[Recommendation] = []
        for symbol in dict.fromkeys(symbols):
            quote = self.provider.quote(market, symbol)
            bars = self.provider.history(market, symbol, 260)
            if len(bars) < 65:
                continue
            features = feature_set(bars)
            fundamentals = self.provider.fundamentals(market, symbol)
            sources = [quote.source, fundamentals.source]
            evidence_snapshot = {
                "quote": {
                    **asdict(quote),
                    "market": quote.market.value,
                    "as_of": quote.as_of.isoformat(),
                },
                "bars": [
                    {
                        "ts": bar.ts.isoformat(),
                        "open": bar.open,
                        "high": bar.high,
                        "low": bar.low,
                        "close": bar.close,
                        "volume": bar.volume,
                    }
                    for bar in bars
                ],
                "fundamentals": {
                    **asdict(fundamentals),
                    "as_of": fundamentals.as_of.isoformat(),
                },
                "features": features,
            }
            for strategy in (Strategy.INVESTMENT, Strategy.SWING):
                recommendations.append(
                    make_recommendation(
                        run_id=run_id,
                        market=market,
                        symbol=symbol,
                        name=quote.name,
                        strategy=strategy,
                        features=features,
                        bars=bars,
                        fundamentals=fundamentals,
                        sources=sources,
                        evidence_snapshot=evidence_snapshot,
                        decision_at=decision_at,
                    )
                )
        return recommendations
