import asyncio
import logging
from datetime import datetime

from fastapi import APIRouter, HTTPException
from app.data_layer.market_data import get_current_price, fetch_multi_timeframe
from app.core.market_condition import detect_market_condition
from app.data_layer.binance_client import binance_client

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/api/v1/market", tags=["market"])

# decision_engine is injected at startup via app.state
_decision_engine = None


def set_decision_engine(engine):
    global _decision_engine
    _decision_engine = engine


@router.get("/price/{pair:path}")
async def get_price(pair: str):
    """Get the current market price for a trading pair (e.g. BTC/USDT)."""
    pair = pair.upper().replace("-", "/")
    price = get_current_price(pair)
    if price is None:
        raise HTTPException(status_code=503, detail=f"Could not fetch price for {pair}")
    return {"pair": pair, "price": price}


@router.get("/signal/{pair:path}")
async def get_signal(pair: str):
    """
    Run the decision engine on demand for a pair and return the signal.
    Does NOT open any trade.
    """
    if _decision_engine is None:
        raise HTTPException(status_code=503, detail="Decision engine not initialised")

    pair = pair.upper().replace("-", "/")
    try:
        market_data = fetch_multi_timeframe(pair, timeframes=["15m", "1h"])
    except Exception as e:
        raise HTTPException(status_code=503, detail=f"Market data error: {e}")

    current_price = get_current_price(pair)
    decision = _decision_engine.analyze(
        pair=pair,
        market_data=market_data,
        current_price=current_price,
    )
    return decision


@router.get("/condition/{pair:path}")
async def get_market_condition(pair: str):
    """Return the detected market condition for a pair."""
    pair = pair.upper().replace("-", "/")
    try:
        market_data = fetch_multi_timeframe(pair, timeframes=["1h"])
        df = market_data.get("1h")
        condition = detect_market_condition(df)
    except Exception as e:
        raise HTTPException(status_code=503, detail=str(e))
    return {"pair": pair, "condition": condition}


@router.get("/account/balance")
async def get_account_balance():
    """Fetch real account balance from Binance Spot"""
    try:
        balance = await binance_client.fetch_balance()

        # Filter non-zero balances
        assets = []
        for asset, total in balance['total'].items():
            if total > 0:
                free = balance['free'].get(asset, 0)
                used = balance['used'].get(asset, 0)
                assets.append({
                    "asset": asset,
                    "free": free,
                    "used": used,
                    "total": total,
                })

        usdt_balance = balance['total'].get('USDT', 0)

        return {
            "success": True,
            "usdt_balance": usdt_balance,
            "assets": assets,
            "timestamp": datetime.utcnow().isoformat()
        }
    except Exception as e:
        logger.error(f"Failed to fetch balance: {e}")
        return {
            "success": False,
            "usdt_balance": 0,
            "assets": [],
            "error": str(e)
        }
