import json
from openai import AsyncOpenAI

from app.core.config import settings
from app.schemas import ChallengeGenerated


class GPTService:
    """Service for generating challenges using OpenAI GPT"""

    def __init__(self):
        self.client = AsyncOpenAI(api_key=settings.OPENAI_API_KEY)

    async def generate_challenges(
        self,
        game_title: str,
        game_genre: str | None = None
    ) -> list[ChallengeGenerated]:
        """
        Generate challenges for a game using GPT.

        Args:
            game_title: Name of the game
            game_genre: Optional genre of the game

        Returns:
            List of generated challenges
        """
        genre_text = f" (жанр: {game_genre})" if game_genre else ""

        prompt = f"""Для видеоигры "{game_title}"{genre_text} сгенерируй 6 челленджей для игрового марафона.

Требования:
- 2 лёгких челленджа (15-30 минут игры)
- 2 средних челленджа (1-2 часа игры)
- 2 сложных челленджа (3+ часов или высокая сложность)

Для каждого челленджа укажи:
- title: короткое название на русском (до 50 символов)
- description: что нужно сделать на русском (1-2 предложения)
- type: один из [completion, no_death, speedrun, collection, achievement, challenge_run]
- difficulty: easy/medium/hard
- points: очки (easy: 30-50, medium: 60-100, hard: 120-200)
- estimated_time: примерное время в минутах
- proof_type: screenshot/video/steam (что лучше подойдёт для проверки)
- proof_hint: что должно быть на скриншоте/видео для подтверждения на русском

Ответь ТОЛЬКО валидным JSON объектом с ключом "challenges" содержащим массив челленджей.
Пример формата:
{{"challenges": [{{"title": "...", "description": "...", "type": "...", "difficulty": "...", "points": 50, "estimated_time": 30, "proof_type": "...", "proof_hint": "..."}}]}}"""

        response = await self.client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[{"role": "user", "content": prompt}],
            response_format={"type": "json_object"},
            temperature=0.7,
            max_tokens=2000,
        )

        content = response.choices[0].message.content
        data = json.loads(content)

        challenges = []
        for ch in data.get("challenges", []):
            # Validate and normalize type
            ch_type = ch.get("type", "completion")
            if ch_type not in ["completion", "no_death", "speedrun", "collection", "achievement", "challenge_run"]:
                ch_type = "completion"

            # Validate difficulty
            difficulty = ch.get("difficulty", "medium")
            if difficulty not in ["easy", "medium", "hard"]:
                difficulty = "medium"

            # Validate proof_type
            proof_type = ch.get("proof_type", "screenshot")
            if proof_type not in ["screenshot", "video", "steam"]:
                proof_type = "screenshot"

            # Validate points
            points = ch.get("points", 50)
            if not isinstance(points, int) or points < 1:
                points = 50

            challenges.append(ChallengeGenerated(
                title=ch.get("title", "Unnamed Challenge")[:100],
                description=ch.get("description", "Complete the challenge"),
                type=ch_type,
                difficulty=difficulty,
                points=points,
                estimated_time=ch.get("estimated_time"),
                proof_type=proof_type,
                proof_hint=ch.get("proof_hint"),
            ))

        return challenges
