from django.db import models
from django.contrib.auth import get_user_model

User = get_user_model()


class Category(models.Model):
    name = models.CharField(max_length=120, unique=True)
    slug = models.SlugField(max_length=140, unique=True)
    is_active = models.BooleanField(default=True)

    class Meta:
        ordering = ["name"]

    def __str__(self):
        return self.name


class Question(models.Model):
    category = models.ForeignKey(Category, on_delete=models.PROTECT, related_name="questions")
    prompt = models.TextField()
    correct_answer = models.CharField(max_length=255)
    is_active = models.BooleanField(default=True)

    class Meta:
        indexes = [models.Index(fields=["category", "is_active"])]

    def __str__(self):
        return f"{self.category.name}: {self.prompt[:60]}"


class GameSession(models.Model):
    class Status(models.TextChoices):
        LOBBY = "lobby", "Lobby"
        LIE = "lie", "Løgnfase"
        GUESS = "guess", "Gættefase"
        REVEAL = "reveal", "Reveal"
        FINISHED = "finished", "Afsluttet"

    host = models.ForeignKey(User, on_delete=models.PROTECT, related_name="hosted_sessions")
    code = models.CharField(max_length=8, unique=True)
    status = models.CharField(max_length=16, choices=Status.choices, default=Status.LOBBY)
    current_round = models.PositiveIntegerField(default=1)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["-created_at"]

    def __str__(self):
        return f"{self.code} ({self.status})"


class Player(models.Model):
    session = models.ForeignKey(GameSession, on_delete=models.CASCADE, related_name="players")
    nickname = models.CharField(max_length=40)
    score = models.IntegerField(default=0)
    is_connected = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = (("session", "nickname"),)
        ordering = ["-score", "nickname"]

    def __str__(self):
        return f"{self.nickname} ({self.session.code})"


class RoundConfig(models.Model):
    session = models.ForeignKey(GameSession, on_delete=models.CASCADE, related_name="rounds")
    number = models.PositiveIntegerField()
    category = models.ForeignKey(Category, on_delete=models.PROTECT)
    questions_count = models.PositiveIntegerField(default=3)
    points_correct = models.IntegerField(default=5)
    points_bluff = models.IntegerField(default=2)
    lie_seconds = models.PositiveIntegerField(default=45)
    guess_seconds = models.PositiveIntegerField(default=30)

    class Meta:
        unique_together = (("session", "number"),)
        ordering = ["number"]


class RoundQuestion(models.Model):
    session = models.ForeignKey(GameSession, on_delete=models.CASCADE, related_name="round_questions")
    round_number = models.PositiveIntegerField()
    question = models.ForeignKey(Question, on_delete=models.PROTECT)
    correct_answer = models.CharField(max_length=255)


class LieAnswer(models.Model):
    round_question = models.ForeignKey(RoundQuestion, on_delete=models.CASCADE, related_name="lies")
    player = models.ForeignKey(Player, on_delete=models.CASCADE)
    text = models.CharField(max_length=255)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = (("round_question", "player"),)


class Guess(models.Model):
    round_question = models.ForeignKey(RoundQuestion, on_delete=models.CASCADE, related_name="guesses")
    player = models.ForeignKey(Player, on_delete=models.CASCADE)
    selected_text = models.CharField(max_length=255)
    is_correct = models.BooleanField(default=False)
    fooled_player = models.ForeignKey(Player, on_delete=models.SET_NULL, null=True, blank=True, related_name="fooled_guesses")
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = (("round_question", "player"),)


class ScoreEvent(models.Model):
    session = models.ForeignKey(GameSession, on_delete=models.CASCADE, related_name="score_events")
    player = models.ForeignKey(Player, on_delete=models.CASCADE, related_name="score_events")
    delta = models.IntegerField()
    reason = models.CharField(max_length=80)
    meta = models.JSONField(default=dict, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
