"""
Public API endpoints for predictions.

This module provides public endpoints for retrieving predictions without authentication.
"""

from datetime import datetime
from typing import Optional
from fastapi import APIRouter, Query, Depends
from sqlalchemy.orm import Session

from app.database import get_db
from app.services.prediction_service import PredictionService
from app.schemas.public import (
    PublicPredictionResponse,
    SuccessResponse,
    SuccessMeta
)

router = APIRouter(prefix="/api/public/v1", tags=["public-predictions"])


@router.get("/predictions", response_model=SuccessResponse)
def get_public_predictions(
    limit: int = Query(20, ge=1, le=100, description="Maximum number of predictions to return (max 100)"),
    offset: int = Query(0, ge=0, description="Number of predictions to skip"),
    league: Optional[str] = Query(None, description="Filter by league name (case-insensitive)"),
    db: Session = Depends(get_db)
):
    """
    Get public predictions with pagination and filters.
    
    This endpoint provides publicly accessible predictions without authentication.
    Data is limited to non-sensitive information only.
    
    Args:
        limit: Maximum number of predictions to return (1-100, default: 20)
        offset: Number of predictions to skip (default: 0)
        league: Optional filter by league name (case-insensitive partial match)
        db: Database session (injected)
    
    Returns:
        Paginated list of public predictions with match details
    
    Example Requests:
        GET /api/public/v1/predictions
        GET /api/public/v1/predictions?limit=10&offset=0
        GET /api/public/v1/predictions?league=Ligue%201
    
    Example Response:
        {
            "data": [
                {
                    "id": 1,
                    "match_id": 1,
                    "match": {
                        "id": 1,
                        "home_team": "PSG",
                        "away_team": "Olympique de Marseille",
                        "date": "2026-01-18T20:00:00Z",
                        "league": "Ligue 1",
                        "status": "scheduled"
                    },
                    "energy_score": "high",
                    "confidence": "65.0%",
                    "predicted_winner": "PSG",
                    "created_at": "2026-01-17T12:00:00Z"
                }
            ],
            "meta": {
                "total": 45,
                "limit": 20,
                "offset": 0,
                "timestamp": "2026-01-17T14:30:00Z",
                "version": "v1"
            }
        }
    """
    service = PredictionService(db)
    predictions, total = service.get_predictions_with_pagination(
        limit=limit,
        offset=offset,
        team_id=None,  # No team filter for public API
        league=league,
        date_min=None,  # No date filter for public API
        date_max=None
    )
    
    # Build response with match details
    prediction_responses = []
    for prediction in predictions:
        match = prediction.match
        prediction_responses.append({
            "id": prediction.id,
            "match_id": prediction.match_id,
            "match": {
                "id": match.id,
                "home_team": match.home_team,
                "away_team": match.away_team,
                "date": match.date.isoformat() if match.date else None,
                "league": match.league,
                "status": match.status
            },
            "energy_score": prediction.energy_score,
            "confidence": prediction.confidence,
            "predicted_winner": prediction.predicted_winner,
            "created_at": prediction.created_at.isoformat() if prediction.created_at else None
        })
    
    return {
        "data": prediction_responses,
        "meta": {
            "total": total,
            "limit": limit,
            "offset": offset,
            "timestamp": datetime.utcnow().isoformat() + "Z",
            "version": "v1"
        }
    }


@router.get("/predictions/{prediction_id}", response_model=PublicPredictionResponse)
def get_public_prediction(
    prediction_id: int,
    db: Session = Depends(get_db)
):
    """
    Get a specific public prediction by ID.
    
    This endpoint provides a publicly accessible prediction without authentication.
    
    Args:
        prediction_id: ID of the prediction
        db: Database session (injected)
    
    Returns:
        Public prediction with match details
    
    Raises:
        404: If prediction doesn't exist
    
    Example Request:
        GET /api/public/v1/predictions/1
    
    Example Response:
        {
            "id": 1,
            "match_id": 1,
            "match": {
                "id": 1,
                "home_team": "PSG",
                "away_team": "Olympique de Marseille",
                "date": "2026-01-18T20:00:00Z",
                "league": "Ligue 1",
                "status": "scheduled"
            },
            "energy_score": "high",
            "confidence": "65.0%",
            "predicted_winner": "PSG",
            "created_at": "2026-01-17T12:00:00Z"
        }
    """
    service = PredictionService(db)
    prediction = service.get_prediction_by_id(prediction_id)
    
    if not prediction:
        from fastapi import HTTPException, status
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Prediction with id {prediction_id} not found"
        )
    
    match = prediction.match
    return {
        "id": prediction.id,
        "match_id": prediction.match_id,
        "match": {
            "id": match.id,
            "home_team": match.home_team,
            "away_team": match.away_team,
            "date": match.date.isoformat() if match.date else None,
            "league": match.league,
            "status": match.status
        },
        "energy_score": prediction.energy_score,
        "confidence": prediction.confidence,
        "predicted_winner": prediction.predicted_winner,
        "created_at": prediction.created_at.isoformat() if prediction.created_at else None
    }
