from __future__ import annotations

from fastapi import APIRouter, HTTPException
from pydantic import BaseModel, Field, validator

from app.services.broker_bridge import BrokerError, broker_bridge_service

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


class ConnectRequest(BaseModel):
    provider_id: str = Field(..., description="Broker provider identifier")
    api_key: str = Field(..., description="API key or session token")
    account_id: str = Field(..., description="Broker account identifier/login")
    demo: bool = Field(True, description="If true, stays in practice/demo mode when supported")

    @validator("provider_id")
    def _trim(cls, value: str) -> str:
        value = value.strip()
        if not value:
            raise ValueError("provider_id is required")
        return value


class OrderRequest(BaseModel):
    action: str
    symbol: str
    quantity: float
    price: float
    type: str | None = None
    stopLoss: float | None = None
    takeProfit: float | None = None


@router.get("/providers")
async def list_providers():
    return broker_bridge_service.list_providers()


@router.get("/session")
async def get_session():
    return broker_bridge_service.get_session()


@router.post("/connect")
async def connect(request: ConnectRequest):
    try:
        return await broker_bridge_service.connect(
            request.provider_id,
            {
                "api_key": request.api_key,
                "account_id": request.account_id,
                "demo": request.demo,
            },
        )
    except BrokerError as exc:  # pragma: no cover - depends on environment
        raise HTTPException(status_code=400, detail=str(exc)) from exc


@router.post("/disconnect")
async def disconnect():
    await broker_bridge_service.disconnect()
    return {"status": "disconnected"}


@router.post("/orders")
async def place_order(request: OrderRequest):
    try:
        return await broker_bridge_service.place_order(request.dict())
    except BrokerError as exc:  # pragma: no cover
        raise HTTPException(status_code=400, detail=str(exc)) from exc


@router.post("/sync")
async def sync_positions():
    try:
        return await broker_bridge_service.sync_positions()
    except BrokerError as exc:  # pragma: no cover
        raise HTTPException(status_code=400, detail=str(exc)) from exc
