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 Type(models.TextChoices):
        YES_NO = "yes_no", "Yes/No"
        MULTIPLE = "multiple", "Multiple Choice"

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

    title = models.CharField(max_length=255)
    description = models.TextField(blank=True)
    type = models.CharField(max_length=10, choices=Type.choices, default=Type.YES_NO)
    status = models.CharField(
        max_length=10, choices=Status.choices, default=Status.OPEN
    )
    end_date = models.DateTimeField()
    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)
    position = models.PositiveIntegerField(default=0)

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

    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}"
