# backend/app/routes/courts.py
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from datetime import datetime, date

from .. import crud, schemas, models
from ..constants import SUCCESS
from ..core.auth import get_admin_user
from ..database import get_db

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

@router.get("", response_model=list[schemas.CourtSchema])
def get_all_courts(db: Session = Depends(get_db)):
    """Public route to list all global courts"""
    return db.query(models.Court).all()

@router.post("", response_model=schemas.CourtSchema)
def create_global_court(
    data: schemas.CourtCreate,
    db: Session = Depends(get_db),
    user: dict = Depends(get_admin_user),
):
    """Admin route to register a new physical court"""
    return crud.create_court(db, data)

@router.delete("/{court_id}")
def delete_global_court(
    court_id: int, db: Session = Depends(get_db), user: dict = Depends(get_admin_user)
):
    success = crud.delete_court(db, court_id)
    if not success:
        raise HTTPException(404, "Court not found")
    return SUCCESS

@router.get("/{court_id}/schedule")
def get_court_schedule(court_id: int, db: Session = Depends(get_db)):
    court = db.query(models.Court).filter(models.Court.id == court_id).first()
    if not court:
        raise HTTPException(404, "Court not found")

    today = date.today()

    matches = (
        db.query(models.Match)
        .join(models.Tournament)
        .filter(models.Match.court_id == court_id)
        .filter(
            models.Tournament.timestamp >= datetime.combine(today, datetime.min.time())
        )
        .filter(
            models.Tournament.timestamp < datetime.combine(today, datetime.max.time())
        )
        .order_by(models.Match.start_time)
        .all()
    )

    t_ids = {m.tournament_id for m in matches}
    if t_ids:
        all_t_matches = db.query(models.Match).filter(models.Match.tournament_id.in_(t_ids)).all()
    else:
        all_t_matches = []

    match_by_id = {str(tm.id).lower(): tm for tm in all_t_matches}
    parent_map = {}

    for tm in all_t_matches:
        if tm.winner_next_match_id:
            parent_map[(str(tm.winner_next_match_id).lower(), tm.winner_next_match_slot)] = f"Winner of #{tm.match_number}"
        if tm.loser_next_match_id:
            parent_map[(str(tm.loser_next_match_id).lower(), tm.loser_next_match_slot)] = f"Loser of #{tm.match_number}"

    def resolve_ref(m: models.Match):
        if m.ref_team:
            return m.ref_team.name
            
        if m.ref_label and ":" in m.ref_label:
            outcome, ref_id = m.ref_label.split(":")
            ref_match = match_by_id.get(ref_id.strip().lower())
            if ref_match:
                role = "Winner" if outcome.upper() == "W" else "Loser"
                return f"{role} of #{ref_match.match_number}"
                
        return m.ref_label or "TBD"

    def get_team_label(m: models.Match, slot: int, team):
        if team:
            return team.name
        return parent_map.get((str(m.id).lower(), slot), "TBD")

    return {
        "court": court.name,
        "matches": [
            {
                "id": m.id,
                "tournament_id": m.tournament.id,
                "tournament_name": m.tournament.name,
                "duration": m.tournament.duration,
                "time": m.start_time.strftime("%H:%M") if m.start_time else None,
                "status": m.status.value if hasattr(m.status, 'value') else m.status,
                "match_number": m.match_number,
                "p1": get_team_label(m, 0, m.p1_team),
                "p2": get_team_label(m, 1, m.p2_team),
                "p1_is_real": bool(m.p1_team),
                "p2_is_real": bool(m.p2_team),
                "p1_sets": len([s for s in m.sets if s.get("p1", 0) > s.get("p2", 0)]),
                "p2_sets": len([s for s in m.sets if s.get("p2", 0) > s.get("p1", 0)]),
                "ref_name": resolve_ref(m),
            }
            for m in matches
            if m.start_time
        ],
    }