from __future__ import annotations

import asyncio
from typing import List, Optional

import pandas as pd
import yfinance as yf

from app.schemas.schemas import PriceData

YA_SYMBOL = "XAUUSD=X"


def _format_dataframe(df: pd.DataFrame) -> List[PriceData]:
    rows: List[PriceData] = []
    if df.empty:
        return rows
    df = df.dropna(subset=["Open", "High", "Low", "Close"])
    for idx, row in df.iterrows():
        timestamp = int(pd.Timestamp(idx).timestamp())
        rows.append(
            PriceData(
                time=timestamp,
                open=float(row["Open"]),
                high=float(row["High"]),
                low=float(row["Low"]),
                close=float(row["Close"]),
                volume=float(row.get("Volume", 0.0) or 0.0),
            )
        )
    return rows


async def fetch_yfinance_history(
    symbol: str = YA_SYMBOL,
    interval: str = "1m",
    period: str = "1d",
    start: Optional[str] = None,
    end: Optional[str] = None,
) -> List[PriceData]:
    def _download() -> pd.DataFrame:
        return yf.download(
            symbol,
            interval=interval,
            period=None if start else period,
            start=start,
            end=end,
            progress=False,
            auto_adjust=False,
            threads=False,
        )

    df = await asyncio.to_thread(_download)
    return _format_dataframe(df)


async def fetch_yfinance_quote(symbol: str = YA_SYMBOL) -> Optional[dict]:
    rows = await fetch_yfinance_history(symbol=symbol, interval="1m", period="1d")
    if not rows:
        return None
    latest = rows[-1]
    previous = rows[-2] if len(rows) > 1 else latest
    return {
        "price": latest.close,
        "previous_close": previous.close,
        "high_24h": max(r.high for r in rows[-1440:]),
        "low_24h": min(r.low for r in rows[-1440:]),
        "volume": latest.volume or 0.0,
        "updated_at": latest.time,
        "rows": rows,
    }
