from typing import Any

from fastapi import APIRouter, HTTPException, Query

from config import settings
from models.signal import ApproveSignalRequest, RejectSignalRequest, SignalStatus
from services.paper_executor import paper_executor
from services.signal_queue import signal_queue

router = APIRouter(prefix="/signals", tags=["signals"])


@router.get("")
def list_signals(
    status: SignalStatus | None = Query(default=None),
) -> dict[str, Any]:
    signals = signal_queue.list_signals(status=status)
    return {
        "count": len(signals),
        "execution_mode": settings.execution_mode,
        "signals": [s.model_dump(mode="json") for s in signals],
    }


@router.get("/{signal_id}")
def get_signal(signal_id: str) -> dict[str, Any]:
    signal = signal_queue.get(signal_id)
    if signal is None:
        raise HTTPException(status_code=404, detail="Signal not found")
    return signal.model_dump(mode="json")


@router.post("/{signal_id}/approve")
def approve_signal(signal_id: str, body: ApproveSignalRequest) -> dict[str, Any]:
    try:
        signal = signal_queue.approve(signal_id, body)
    except KeyError as exc:
        raise HTTPException(status_code=404, detail=str(exc)) from exc
    except ValueError as exc:
        raise HTTPException(status_code=409, detail=str(exc)) from exc
    return signal.model_dump(mode="json")


@router.post("/{signal_id}/reject")
def reject_signal(signal_id: str, body: RejectSignalRequest) -> dict[str, Any]:
    try:
        signal = signal_queue.reject(signal_id, body)
    except KeyError as exc:
        raise HTTPException(status_code=404, detail=str(exc)) from exc
    except ValueError as exc:
        raise HTTPException(status_code=409, detail=str(exc)) from exc
    return signal.model_dump(mode="json")


@router.get("/paper/positions")
def paper_positions() -> dict[str, Any]:
    return {
        "open_count": paper_executor.open_positions_count(),
        "positions": [
            {
                "ticker": p.ticker,
                "side": p.side.value,
                "quantity": p.quantity,
                "entry_price": p.entry_price,
                "opened_at": p.opened_at.isoformat(),
            }
            for p in paper_executor.positions.values()
        ],
        "history": paper_executor.history[-50:],
    }
