import logging
from datetime import datetime
from typing import Any, Dict, Optional

from fastapi import HTTPException

from app.v1.services.zerodha.client import ZerodhaClient
from app.v1.services.tegpt.config import MAX_POSITION_SIZE

logger = logging.getLogger(__name__)


def place_order_service(
    db,
    zerodha_client: ZerodhaClient,
    user_id: str,
    symbol: str,
    action: str,
    quantity: int,
    order_type: str,
    price: Optional[float] = None,
    analysis_id: Optional[str] = None,
    confirmed: bool = False,
) -> Dict[str, Any]:
    """Place trading order with basic safety validation."""

    if not confirmed:
        raise HTTPException(status_code=400, detail="Order confirmation required")

    if action not in ["BUY", "SELL"]:
        raise HTTPException(status_code=400, detail="Action must be BUY or SELL")

    if quantity <= 0:
        raise HTTPException(status_code=400, detail="Quantity must be positive")

    if order_type == "LIMIT" and not price:
        raise HTTPException(status_code=400, detail="Price required for LIMIT orders")

    estimated_value = (price or 0) * quantity
    if estimated_value > MAX_POSITION_SIZE:
        raise HTTPException(status_code=400, detail=f"Position size exceeds limit of ₹{MAX_POSITION_SIZE}")

    try:
        quote_data = zerodha_client.get_quote([f"NSE:{symbol}"])
        current_price = quote_data.get(f"NSE:{symbol}", {}).get("last_price", 0)

        if not current_price:
            raise HTTPException(status_code=400, detail="Unable to get current market price")

        if order_type == "LIMIT" and price:
            price_diff_pct = abs(price - current_price) / current_price * 100
            if price_diff_pct > 10:
                raise HTTPException(status_code=400, detail="LIMIT price too far from market price")

        order_payload: Dict[str, Any] = {
            "tradingsymbol": symbol,
            "exchange": "NSE",
            "transaction_type": action,
            "quantity": quantity,
            "product": "MIS",
            "order_type": order_type,
            "validity": "DAY",
        }

        if order_type == "LIMIT" and price:
            order_payload["price"] = price

        try:
            zerodha_response = zerodha_client.place_order(**order_payload)
            order_id = zerodha_response if isinstance(zerodha_response, str) else zerodha_response.get("order_id")

        except Exception as e:
            logger.exception("Zerodha order placement failed for %s", symbol)
            raise HTTPException(status_code=502, detail=f"Order placement failed: {str(e)}")

        order_doc = {
            "user_id": user_id,
            "symbol": symbol,
            "action": action,
            "quantity": quantity,
            "order_type": order_type,
            "price": price,
            "current_market_price": current_price,
            "zerodha_order_id": order_id,
            "zerodha_response": zerodha_response,
            "order_payload": order_payload,
            "analysis_id": analysis_id,
            "status": "PLACED",
            "created_at": datetime.utcnow(),
        }

        result = db["orders"].insert_one(order_doc)

        return {
            "order_id": str(result.inserted_id),
            "zerodha_order_id": order_id,
            "symbol": symbol,
            "action": action,
            "quantity": quantity,
            "price": price,
            "status": "PLACED",
            "timestamp": order_doc["created_at"].isoformat(),
        }

    except HTTPException:
        raise
    except Exception as e:
        logger.exception("Order service failed for %s", symbol)
        raise HTTPException(status_code=500, detail=str(e))
