"""
Tests for public API endpoints.

This module tests the public API endpoints for predictions and matches.
"""

import pytest
from fastapi.testclient import TestClient
from sqlalchemy.orm import Session

from app.main import app
from app.database import get_db
from app.models.prediction import Prediction
from app.models.match import Match
from datetime import datetime


client = TestClient(app)


@pytest.fixture
def sample_match(db: Session):
    """Create a sample match for testing."""
    match = Match(
        home_team="PSG",
        away_team="Olympique de Marseille",
        date=datetime.utcnow(),
        league="Ligue 1",
        status="scheduled"
    )
    db.add(match)
    db.commit()
    db.refresh(match)
    return match


@pytest.fixture
def sample_prediction(db: Session, sample_match: Match):
    """Create a sample prediction for testing."""
    prediction = Prediction(
        match_id=sample_match.id,
        energy_score="high",
        confidence="70.5%",
        predicted_winner="PSG",
        created_at=datetime.utcnow()
    )
    db.add(prediction)
    db.commit()
    db.refresh(prediction)
    return prediction


class TestPublicPredictionsEndpoint:
    """Tests for GET /api/public/v1/predictions endpoint."""

    def test_get_public_predictions_success(self, sample_prediction: Prediction):
        """Test successful retrieval of public predictions."""
        response = client.get("/api/public/v1/predictions")
        assert response.status_code == 200
        data = response.json()
        assert "data" in data
        assert "meta" in data
        assert isinstance(data["data"], list)
        assert len(data["data"]) > 0
        assert data["meta"]["version"] == "v1"

    def test_get_public_predictions_with_limit(self, sample_prediction: Prediction):
        """Test retrieval of public predictions with limit parameter."""
        response = client.get("/api/public/v1/predictions?limit=5")
        assert response.status_code == 200
        data = response.json()
        assert "data" in data
        assert "meta" in data
        assert data["meta"]["limit"] == 5

    def test_get_public_predictions_data_structure(self, sample_prediction: Prediction):
        """Test that public predictions have correct structure without sensitive data."""
        response = client.get("/api/public/v1/predictions")
        assert response.status_code == 200
        data = response.json()
        prediction = data["data"][0]
        
        # Required fields
        assert "id" in prediction
        assert "match" in prediction
        assert "energy_score" in prediction
        assert "confidence" in prediction
        assert "predicted_winner" in prediction
        
        # Match details
        match = prediction["match"]
        assert "id" in match
        assert "home_team" in match
        assert "away_team" in match
        assert "date" in match
        assert "league" in match
        assert "status" in match

    def test_get_public_predictions_empty_database(self):
        """Test retrieval when no predictions exist."""
        # Clear database for this test
        response = client.get("/api/public/v1/predictions")
        assert response.status_code == 200
        data = response.json()
        assert "data" in data
        assert isinstance(data["data"], list)


class TestPublicMatchesEndpoint:
    """Tests for GET /api/public/v1/matches endpoint."""

    def test_get_public_matches_success(self, sample_match: Match):
        """Test successful retrieval of public matches."""
        response = client.get("/api/public/v1/matches")
        assert response.status_code == 200
        data = response.json()
        assert "data" in data
        assert "meta" in data
        assert isinstance(data["data"], list)
        assert len(data["data"]) > 0
        assert data["meta"]["version"] == "v1"

    def test_get_public_matches_with_filters(self, sample_match: Match):
        """Test retrieval of public matches with league filter."""
        response = client.get(f"/api/public/v1/matches?league=Ligue%201")
        assert response.status_code == 200
        data = response.json()
        assert "data" in data
        assert "meta" in data

    def test_get_public_matches_data_structure(self, sample_match: Match):
        """Test that public matches have correct structure."""
        response = client.get("/api/public/v1/matches")
        assert response.status_code == 200
        data = response.json()
        match = data["data"][0]
        
        # Required fields (public only, no sensitive data)
        assert "id" in match
        assert "home_team" in match
        assert "away_team" in match
        assert "date" in match
        assert "league" in match
        assert "status" in match

    def test_get_public_matches_empty_database(self):
        """Test retrieval when no matches exist."""
        response = client.get("/api/public/v1/matches")
        assert response.status_code == 200
        data = response.json()
        assert "data" in data
        assert isinstance(data["data"], list)


class TestPublicApiResponseFormat:
    """Tests for standardized API response format."""

    def test_response_format_success(self, sample_prediction: Prediction):
        """Test that successful responses follow {data, meta} format."""
        response = client.get("/api/public/v1/predictions")
        assert response.status_code == 200
        data = response.json()
        
        assert "data" in data
        assert "meta" in data
        assert "timestamp" in data["meta"]
        assert "version" in data["meta"]

    def test_response_meta_timestamp_format(self, sample_prediction: Prediction):
        """Test that timestamp is in ISO 8601 format."""
        response = client.get("/api/public/v1/predictions")
        assert response.status_code == 200
        data = response.json()
        timestamp = data["meta"]["timestamp"]
        
        # ISO 8601 format check (simplified)
        assert "T" in timestamp
        assert "Z" in timestamp
