"""Order and Position Management Endpoints."""
from __future__ import annotations

import uuid
from decimal import Decimal
from typing import Any, Optional

from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel

from backend.app.api.v1.auth import get_current_user
from backend.app.config.settings import settings
from backend.app.database.session import db_manager
from backend.app.execution.router import execution_router
from backend.app.market_data.feed_manager import feed_manager
from backend.app.portfolio.manager import portfolio_manager
from backend.app.risk.engine import risk_engine
from backend.app.schemas.order import OrderIntent, OrderSide, OrderType
from backend.app.schemas.signal import MarketRegime, SignalAction, SignalCandidate

router = APIRouter(prefix="/orders", tags=["Orders & Positions"])


class PlaceOrderRequest(BaseModel):
    symbol: str
    side: str  # BUY or SELL
    order_type: str = "MARKET"
    quantity: Optional[float] = None  # If None, calculated automatically by risk sizer


@router.get("")
async def get_orders() -> list[dict[str, Any]]:
    """Retrieve history of placed orders."""
    return db_manager.execute_read_all(
        "SELECT * FROM orders ORDER BY created_at DESC LIMIT 50"
    )


@router.get("/positions")
async def get_positions() -> list[dict[str, Any]]:
    """Retrieve current portfolio positions."""
    return portfolio_manager.get_positions()


@router.post("/submit")
async def submit_order(
    req: PlaceOrderRequest,
    user: dict[str, Any] = Depends(get_current_user),
) -> dict[str, Any]:
    """Submit order through the independent Risk Gatekeeper and Execution Router."""
    side_enum = OrderSide.BUY if req.side.upper() == "BUY" else OrderSide.SELL
    action_enum = SignalAction.LONG if side_enum == OrderSide.BUY else SignalAction.SHORT

    ticker = feed_manager.fetch_ticker(req.symbol)
    filters = feed_manager.fetch_instrument_filters(req.symbol)
    account_state = portfolio_manager.get_account_state()

    # Determine stop loss (1.5% default for manual orders if not specified)
    price = ticker.last_price
    stop_dist = price * Decimal("0.015")
    tp_dist = price * Decimal("0.030")  # 2.0 R:R

    stop_loss = price - stop_dist if side_enum == OrderSide.BUY else price + stop_dist
    take_profit = price + tp_dist if side_enum == OrderSide.BUY else price - tp_dist

    # Construct candidate signal
    signal = SignalCandidate(
        symbol=req.symbol,
        timeframe="manual",
        action=action_enum,
        raw_probability=0.60,
        calibrated_probability=0.60,
        expected_return=0.030,
        expected_risk=0.015,
        expected_value=0.003,
        entry_price=price,
        stop_loss_price=stop_loss,
        take_profit_price=take_profit,
        regime=MarketRegime.UNCERTAIN,
        reason=f"Manual order authorized by user {user.get('sub')}",
        model_version="manual_operator",
        timestamp=str(ticker.timestamp),
    )

    # 1. Independent Risk Engine Gatekeeper Check
    decision = risk_engine.evaluate_signal(signal, account_state, filters)
    if not decision.approved:
        raise HTTPException(
            status_code=400,
            detail=f"Order rejected by Independent Risk Engine: {decision.rejection_reason}",
        )

    # 2. Construct Order Intent
    client_oid = f"aegis_{uuid.uuid4().hex[:12]}"
    order_qty = Decimal(str(req.quantity)) if req.quantity else decision.approved_quantity

    intent = OrderIntent(
        client_order_id=client_oid,
        symbol=req.symbol,
        side=side_enum,
        order_type=OrderType.MARKET if req.order_type.upper() == "MARKET" else OrderType.LIMIT,
        quantity=order_qty,
        price=price if req.order_type.upper() == "LIMIT" else None,
        stop_loss=decision.stop_loss_price,
        take_profit=decision.take_profit_price,
        mode=settings.TRADING_MODE.value,
    )

    # 3. Dispatch to Execution Router
    result = execution_router.submit_order(intent)

    return {
        "status": result.status.value,
        "client_order_id": result.client_order_id,
        "exchange_order_id": result.exchange_order_id,
        "filled_qty": float(result.filled_qty),
        "avg_price": float(result.avg_price),
        "fee_paid": float(result.fee_paid),
        "message": result.message,
    }


@router.post("/flatten")
async def flatten_positions(
    user: dict[str, Any] = Depends(get_current_user),
) -> dict[str, Any]:
    """Emergency action: close all open positions."""
    return portfolio_manager.flatten_all_positions(authorized_by=user.get("sub", "ADMIN"))
