import uuid
from django.db import models


class BaseModel(models.Model):
    uuid = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True


class Market(BaseModel):
    class Status(models.TextChoices):
        DRAFT = "draft", "Draft"
        OPEN = "open", "Open"
        CLOSED = "closed", "Closed"
        RESOLVED = "resolved", "Resolved"

    title = models.CharField(max_length=255)
    description = models.TextField(blank=True)
    status = models.CharField(
        max_length=10, choices=Status.choices, default=Status.DRAFT
    )
    end_date = models.DateTimeField()
    multiplier = models.FloatField(default=1.0)
    created_by = models.ForeignKey("accounts.CustomUser", on_delete=models.PROTECT)
    winning_option = models.ForeignKey(
        "MarketOption",
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="market_won",
    )

    class Meta:
        ordering = ["-created_at"]
        indexes = [
            models.Index(fields=["status", "-created_at"]),
            models.Index(fields=["end_date"]),
        ]

    def __str__(self):
        return self.title


class MarketOption(BaseModel):
    market = models.ForeignKey(Market, on_delete=models.CASCADE, related_name="options")
    text = models.CharField(max_length=255)

    class Meta:
        ordering = ["text"]
        constraints = [
            models.UniqueConstraint(
                fields=["market", "text"],
                name="unique_market_option_text",
            ),
        ]
        indexes = [
            models.Index(fields=["market"]),
        ]

    def __str__(self):
        return f"{self.market.title} - {self.text}"


class UserBet(BaseModel):
    user = models.ForeignKey(
        "accounts.CustomUser", on_delete=models.CASCADE, related_name="bets"
    )
    option = models.ForeignKey(
        MarketOption, on_delete=models.CASCADE, related_name="user_bets"
    )
    amount = models.PositiveIntegerField()

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=["user", "option"],
                name="unique_user_bet_per_option",
            ),
        ]
        indexes = [
            models.Index(fields=["user", "option"]),
        ]

    def __str__(self):
        return f"{self.user.username} bet {self.amount} on {self.option.text}"


class UserPointChange(BaseModel):
    class Reason(models.TextChoices):
        BET_PLACED = "bet_placed", "Bet Placed"
        BET_WON = "bet_won", "Bet Won"
        BET_LOST = "bet_lost", "Bet Lost"

    user = models.ForeignKey(
        "accounts.CustomUser", on_delete=models.CASCADE, related_name="point_changes"
    )
    market = models.ForeignKey(
        Market, on_delete=models.CASCADE, related_name="point_changes"
    )
    amount = models.IntegerField()
    reason = models.CharField(max_length=20, choices=Reason.choices)

    class Meta:
        ordering = ["-created_at"]
        indexes = [
            models.Index(fields=["user", "-created_at"]),
        ]

    def __str__(self):
        return f"{self.user.username} {self.reason}: {self.amount} pts on {self.market.title}"
