"""
User Prediction API Routes.

This module provides REST endpoints for tracking user predictions
and retrieving user statistics.
"""

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

from app.database import get_db
from app.services.user_prediction_service import UserPredictionService
from app.schemas.user_prediction import (
    UserPredictionResponse,
    UserPredictionListResponse,
    UserStatsResponse
)

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


@router.post("", status_code=status.HTTP_201_CREATED)
def record_prediction_view(
    user_id: int,
    prediction_id: int,
    db: Session = Depends(get_db)
):
    """
    Record that a user viewed a prediction.
    
    This endpoint tracks when a user views a prediction for ROI and accuracy calculations.
    Duplicate views are ignored (unique constraint on user_id + prediction_id).
    
    Args:
        user_id: ID of the user
        prediction_id: ID of the prediction viewed
        db: Database session (injected)
    
    Returns:
        Created user prediction record
    
    Raises:
        404: If user or prediction doesn't exist
        422: If validation fails
    
    Example Request:
        POST /api/v1/user-predictions?user_id=1&prediction_id=5
    
    Example Response:
        {
            "id": 1,
            "user_id": 1,
            "prediction_id": 5,
            "viewed_at": "2026-01-18T10:00:00Z",
            "was_correct": null
        }
    """
    try:
        service = UserPredictionService(db)
        user_prediction = service.record_prediction_view(user_id, prediction_id)
        return user_prediction.to_dict()
    except ValueError as e:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=str(e)
        )
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to record prediction view: {str(e)}"
        )


@router.get("/history/{user_id}", response_model=UserPredictionListResponse)
def get_prediction_history(
    user_id: int,
    limit: int = Query(50, ge=1, le=100, description="Maximum number of records to return (max 100)"),
    offset: int = Query(0, ge=0, description="Number of records to skip"),
    db: Session = Depends(get_db)
):
    """
    Get a user's prediction viewing history.
    
    This endpoint retrieves all predictions a user has viewed, sorted by most recent.
    Includes full prediction and match details.
    
    Args:
        user_id: ID of the user
        limit: Maximum number of records to return (1-100, default: 50)
        offset: Number of records to skip (default: 0)
        db: Database session (injected)
    
    Returns:
        Paginated list of user predictions with full details
    
    Example Request:
        GET /api/v1/user-predictions/history/1?limit=10&offset=0
    
    Example Response:
        {
            "data": [
                {
                    "id": 5,
                    "user_id": 1,
                    "prediction_id": 10,
                    "viewed_at": "2026-01-18T10:00:00Z",
                    "was_correct": true,
                    "prediction": {
                        "id": 10,
                        "match_id": 3,
                        "energy_score": "high",
                        "confidence": "75.0%",
                        "predicted_winner": "PSG",
                        "created_at": "2026-01-17T12:00:00Z"
                    },
                    "match": {
                        "id": 3,
                        "home_team": "PSG",
                        "away_team": "Marseille",
                        "date": "2026-01-18T20:00:00Z",
                        "league": "Ligue 1",
                        "status": "completed",
                        "actual_winner": "PSG"
                    }
                }
            ],
            "meta": {
                "total": 25,
                "limit": 10,
                "offset": 0,
                "timestamp": "2026-01-18T15:30:00Z"
            }
        }
    """
    from datetime import datetime
    
    service = UserPredictionService(db)
    predictions, total = service.get_user_prediction_history(
        user_id=user_id,
        limit=limit,
        offset=offset
    )
    
    return {
        "data": predictions,
        "meta": {
            "total": total,
            "limit": limit,
            "offset": offset,
            "timestamp": datetime.utcnow().isoformat() + "Z"
        }
    }


@router.get("/stats/{user_id}", response_model=UserStatsResponse)
def get_user_statistics(
    user_id: int,
    db: Session = Depends(get_db)
):
    """
    Get user statistics including accuracy and ROI.
    
    This endpoint calculates:
    - Total predictions viewed
    - Number of correct/incorrect predictions
    - Accuracy rate percentage
    - ROI (Return on Investment) in EUR
    
    Args:
        user_id: ID of the user
        db: Database session (injected)
    
    Returns:
        User statistics
    
    Raises:
        404: If user doesn't exist
    
    Example Request:
        GET /api/v1/user-predictions/stats/1
    
    Example Response:
        {
            "total_predictions_viewed": 25,
            "correct_predictions": 18,
            "incorrect_predictions": 5,
            "accuracy_rate": 78.3,
            "roi": 1550.0
        }
    """
    service = UserPredictionService(db)
    stats = service.get_user_stats(user_id)
    
    return UserStatsResponse(**stats)


@router.put("/result/{prediction_id}")
def update_prediction_result(
    prediction_id: int,
    actual_winner: Optional[str] = Query(None, description="Actual winner: home, away, draw, or null"),
    db: Session = Depends(get_db)
):
    """
    Update prediction result when match completes.
    
    This endpoint is called when a match finishes to update all user
    predictions that referenced this prediction.
    
    Args:
        prediction_id: ID of the prediction
        actual_winner: Actual winner of the match (home/away/draw or null)
        db: Database session (injected)
    
    Returns:
        Success message
    
    Example Request:
        PUT /api/v1/user-predictions/result/10?actual_winner=home
    
    Example Response:
        {
            "message": "Prediction results updated successfully",
            "prediction_id": 10,
            "actual_winner": "home"
        }
    """
    try:
        service = UserPredictionService(db)
        service.update_prediction_result(prediction_id, actual_winner)
        
        return {
            "message": "Prediction results updated successfully",
            "prediction_id": prediction_id,
            "actual_winner": actual_winner
        }
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to update prediction result: {str(e)}"
        )
