"""Stock market data module using Yahoo Finance."""

from __future__ import annotations

from typing import TYPE_CHECKING

from savvy._client import call_tool, extract_data_from_response, extract_metadata_from_response
from savvy.models import DataResult

if TYPE_CHECKING:
    import pandas as pd


def fetch(
    symbol: str,
    *,
    period: str = "1y",
    interval: str = "1d",
    start: str | None = None,
    end: str | None = None,
) -> "pd.DataFrame":
    """
    Fetch stock price data from Yahoo Finance.

    Args:
        symbol: Stock ticker symbol (e.g., "AAPL", "MSFT", "GOOGL").
        period: Historical period ("1d", "5d", "1mo", "3mo", "6mo", "1y", "2y", "5y", "max").
                Ignored if start/end are provided.
        interval: Data interval ("1m", "5m", "15m", "1h", "1d", "1wk", "1mo").
        start: Start date in YYYY-MM-DD format (overrides period).
        end: End date in YYYY-MM-DD format.

    Returns:
        DataFrame with columns: date, open, high, low, close, volume, adj_close.

    Raises:
        AuthenticationError: If API key is invalid or missing.
        DataNotFoundError: If the symbol is not found.

    Example:
        >>> import savvy
        >>> df = savvy.stock_data.fetch("AAPL", period="1y")
        >>> print(df.head())
                 date    open    high     low   close     volume
        0  2024-01-02  185.12  186.48  183.92  185.64  58414500
    """
    kwargs: dict = {
        "action": "fetch",
        "series_id": symbol.upper(),
        "provider": "yahoo_finance",
        "period": period,
        "interval": interval,
    }

    if start:
        kwargs["start_date"] = start
    if end:
        kwargs["end_date"] = end

    response = call_tool("economic_data", **kwargs)

    records = extract_data_from_response(response)
    metadata = extract_metadata_from_response(response)

    result = DataResult.from_response(records, metadata)
    return result.to_dataframe()


def quote(symbol: str) -> dict:
    """
    Get the current quote for a stock.

    Args:
        symbol: Stock ticker symbol (e.g., "AAPL", "MSFT").

    Returns:
        Dictionary with current price information:
        - symbol: The ticker symbol
        - price: Current price
        - change: Price change
        - change_percent: Percentage change
        - volume: Trading volume
        - market_cap: Market capitalization (if available)

    Example:
        >>> import savvy
        >>> q = savvy.stock_data.quote("AAPL")
        >>> print(f"AAPL: ${q['price']:.2f} ({q['change_percent']:+.2f}%)")
        AAPL: $185.64 (+1.23%)
    """
    # Fetch the most recent data point
    kwargs: dict = {
        "action": "fetch",
        "series_id": symbol.upper(),
        "provider": "yahoo_finance",
        "period": "1d",
        "interval": "1d",
    }

    response = call_tool("economic_data", **kwargs)

    records = extract_data_from_response(response)

    if not records:
        from savvy.exceptions import DataNotFoundError

        raise DataNotFoundError(f"No data found for symbol: {symbol}", series_id=symbol)

    # Get the most recent record
    latest = records[-1] if records else {}

    # Calculate change if we have previous day
    change = None
    change_percent = None
    if len(records) >= 2:
        prev = records[-2]
        if "close" in latest and "close" in prev and prev["close"]:
            change = latest["close"] - prev["close"]
            change_percent = (change / prev["close"]) * 100

    return {
        "symbol": symbol.upper(),
        "price": latest.get("close") or latest.get("value"),
        "open": latest.get("open"),
        "high": latest.get("high"),
        "low": latest.get("low"),
        "volume": latest.get("volume"),
        "date": latest.get("date"),
        "change": change,
        "change_percent": change_percent,
    }


def history(
    symbol: str,
    *,
    period: str = "1y",
    interval: str = "1d",
) -> "pd.DataFrame":
    """
    Alias for fetch() - get historical stock data.

    Args:
        symbol: Stock ticker symbol.
        period: Historical period.
        interval: Data interval.

    Returns:
        DataFrame with price history.
    """
    return fetch(symbol, period=period, interval=interval)
