from typing import List
from ninja import Router
from ninja.errors import HttpError
from django.shortcuts import get_object_or_404

from market.models import Market, MarketOption, UserBet
from market.schemas import (
    MarketListSchema,
    ResolveMarketSchema,
    UserBetCreateSchema,
    UserBetSchema,
)


router = Router(tags=["market"])


@router.get("/", response=List[MarketListSchema])
def list_markets(request):
    """List all markets."""
    return Market.objects.prefetch_related("options").all()


@router.get("/user/bets", response=List[UserBetSchema])
def list_user_bets(request):
    """List all bets placed by the current user."""
    if not request.user.is_authenticated:
        raise HttpError(401, "Authentication required")

    return UserBet.objects.filter(user=request.user).select_related(
        "option__market"
    ).prefetch_related("option__market__options")


@router.post("/{market_uuid}/actions/close")
def close_market(request, market_uuid: str):
    """Close a market. Admin only."""
    if not request.user.is_staff:
        raise HttpError(403, "Permission denied")

    market = get_object_or_404(Market, uuid=market_uuid)
    market.status = Market.Status.CLOSED
    market.save(update_fields=["status", "updated_at"])
    return {"status": "closed"}


@router.post("/{market_uuid}/actions/resolve", response=MarketListSchema)
def resolve_market(request, market_uuid: str, payload: ResolveMarketSchema):
    """Resolve a market with a winning option. Admin only."""
    if not request.user.is_staff:
        raise HttpError(403, "Permission denied")

    market = get_object_or_404(Market, uuid=market_uuid)
    winning_option = get_object_or_404(MarketOption, uuid=payload.winning_option_uuid)

    if winning_option.market_id != market.id:
        raise HttpError(400, "Option does not belong to this market")

    market.winning_option = winning_option
    market.status = Market.Status.RESOLVED
    market.save(update_fields=["winning_option", "status", "updated_at"])
    return market


@router.post("/{market_uuid}/bets", response=UserBetSchema)
def create_bet(request, market_uuid: str, payload: UserBetCreateSchema):
    """Place a bet on a market option."""
    if not request.user.is_authenticated:
        raise HttpError(401, "Authentication required")

    market = get_object_or_404(Market, uuid=market_uuid)
    option = get_object_or_404(MarketOption, uuid=payload.option_uuid)

    if option.market_id != market.id:
        raise HttpError(400, "Option does not belong to this market")

    if market.status != Market.Status.OPEN:
        raise HttpError(400, "Market is not open for betting")

    # Check if user already has a bet on a different option in this market
    existing_bet_on_market = UserBet.objects.filter(
        user=request.user,
        option__market=market
    ).exclude(option=option).first()
    if existing_bet_on_market:
        raise HttpError(400, "You can only bet on one option per market")

    # Check if user already has a bet on this option
    existing_bet = UserBet.objects.filter(user=request.user, option=option).first()
    if existing_bet and payload.amount < existing_bet.amount:
        raise HttpError(400, "Cannot decrease bet amount. You can only increase it.")

    user_bet, created = UserBet.objects.update_or_create(
        user=request.user,
        option=option,
        defaults={"amount": payload.amount},
    )

    return user_bet
