from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
from typing import List, Dict, Optional
import uvicorn
import logging
import datetime
from app.db import SessionLocal, TournamentDeco, PayoutDeco
from app.nofloor_decay import simulate_and_round

app = FastAPI(
    title="Prize Pool Calculator - No Floor Decay",
    version="1.0.0",
    description="Calculate tournament prize distributions with no floor decay"
)

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s",
    handlers=[
        logging.StreamHandler(),
    ]
)
logger = logging.getLogger(__name__)

class PayoutRequest(BaseModel):
    price: float = Field(..., gt=0)
    minprize: float = Field(..., gt=0)
    prizes: int = Field(..., gt=0)
    tickets: int = Field(..., gt=0)
    pool: float = Field(..., gt=0)
    first: float = Field(0)
    competition_id: str = Field(...)
    sport: str = Field(...)

class PayoutResult(BaseModel):
    rank: int
    amount: float
    tier: str

class StorePayoutResponse(BaseModel):
    competition_id: str
    sport: str
    payouts: List[PayoutResult]
    pool: float
    first: float
    minprize: float
    tickets: int
    price: float
    prizes: int

@app.post("/calculate_and_store_payout_nofloor", response_model=StorePayoutResponse)
async def calculate_and_store_payout_nofloor(request: PayoutRequest):
    try:
        logger.info(f"Received payout request: {request.dict()}")
        result = simulate_and_round(
            price=request.price,
            minprize=request.minprize,
            prizes=request.prizes,
            tickets=request.tickets,
            pool=request.pool,
            first=request.first
        )
        payouts = result["payouts"]
        logger.info(f"Calculated payouts: {payouts}")
        db = SessionLocal()
        try:
            tournament = db.query(TournamentDeco).filter_by(CompetitionId=request.competition_id).first()
            if not tournament:
                tournament = TournamentDeco(
                    CompetitionId=request.competition_id,
                    Sport=request.sport,
                    InitialPool=request.pool,
                    TicketPrice=request.price,
                    TicketsSold=request.tickets,
                    PrizeCount=request.prizes,
                    CreatedAt=datetime.datetime.utcnow(),
                    UpdatedAt=datetime.datetime.utcnow()
                )
                db.add(tournament)
                db.commit()
                logger.info(f"Created new tournament record for {request.competition_id}")
            else:
                logger.info("Tournament already exists, skipping creation.")
            for payout in payouts:
                db.add(PayoutDeco(
                    CompetitionId=request.competition_id,
                    Rank=payout["rank"],
                    Amount=payout["final"],
                    Tier=payout["tier"],
                    Sport=request.sport,
                    CreatedAt=datetime.datetime.utcnow(),
                    UpdatedAt=datetime.datetime.utcnow()
                ))
            db.commit()
            logger.info(f"Saved {len(payouts)} payout records")
        except Exception as e:
            db.rollback()
            logger.error(f"Database error: {e}")
            raise HTTPException(status_code=500, detail=f"Database error: {str(e)}")
        finally:
            db.close()
            logger.info("Database session closed.")
        return StorePayoutResponse(
            competition_id=request.competition_id,
            sport=request.sport,
            payouts=[PayoutResult(rank=p["rank"], amount=p["final"], tier=p["tier"]) for p in payouts],
            pool=request.pool,
            first=request.first,
            minprize=request.minprize,
            tickets=request.tickets,
            price=request.price,
            prizes=request.prizes
        )
    except Exception as e:
        logger.error(f"Error in payout calculation: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))

def start():
    uvicorn.run("main_api_nofloor:app", host="0.0.0.0", port=8000, reload=True)

if __name__ == "__main__":
    start() 
