from django.db import models
from django.conf import settings
from django.utils import timezone


class Wallet(models.Model):
    user       = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="wallet")
    balance    = models.PositiveIntegerField(default=100)  # starting bonus
    last_spin  = models.DateTimeField(null=True, blank=True)
    last_login_bonus = models.DateField(null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.user.username} — {self.balance} pts"

    def can_spin(self):
        if not self.last_spin: return True
        return timezone.now() - self.last_spin >= timezone.timedelta(hours=24)

    def can_claim_login_bonus(self):
        if not self.last_login_bonus: return True
        return self.last_login_bonus < timezone.now().date()


class Transaction(models.Model):
    TYPE_CHOICES = [
        ("daily_login",  "Daily Login Bonus"),
        ("spin",         "Daily Spin"),
        ("post",         "Created Post"),
        ("follower",     "New Follower"),
        ("prediction_win",  "Prediction Win"),
        ("prediction_loss", "Prediction Loss"),
        ("prediction_stake","Prediction Stake"),
        ("boost",        "Boosted Content"),
        ("admin_adjust", "Admin Adjustment"),
        ("profile_complete", "Profile Completed"),
    ]
    wallet      = models.ForeignKey(Wallet, on_delete=models.CASCADE, related_name="transactions")
    amount      = models.IntegerField()  # can be negative
    tx_type     = models.CharField(max_length=30, choices=TYPE_CHOICES)
    description = models.CharField(max_length=200, blank=True)
    created_at  = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["-created_at"]


# ── PREDICTION ARENA ──
class Prediction(models.Model):
    STATUS_CHOICES = [
        ("open",     "Open"),
        ("locked",   "Locked"),
        ("settled",  "Settled"),
        ("cancelled","Cancelled"),
    ]
    creator     = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="created_predictions")
    title       = models.CharField(max_length=200)
    description = models.TextField(blank=True)
    option_a    = models.CharField(max_length=100)
    option_b    = models.CharField(max_length=100)
    category    = models.CharField(max_length=30, default="general")
    closes_at   = models.DateTimeField()
    status      = models.CharField(max_length=20, choices=STATUS_CHOICES, default="open")
    winning_option = models.CharField(max_length=1, blank=True, null=True)  # 'a' or 'b'
    created_at  = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["-created_at"]

    @property
    def total_pool(self):
        return sum(s.amount for s in self.stakes.all())

    @property
    def pool_a(self):
        return sum(s.amount for s in self.stakes.filter(option="a"))

    @property
    def pool_b(self):
        return sum(s.amount for s in self.stakes.filter(option="b"))


class PredictionStake(models.Model):
    prediction = models.ForeignKey(Prediction, on_delete=models.CASCADE, related_name="stakes")
    user       = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="prediction_stakes")
    option     = models.CharField(max_length=1)  # 'a' or 'b'
    amount     = models.PositiveIntegerField()
    payout     = models.PositiveIntegerField(default=0)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ["prediction", "user"]


# ── CARD DUELS ──
class Duel(models.Model):
    STATUS_CHOICES = [
        ("pending",  "Pending"),
        ("drafting", "Drafting"),
        ("declined", "Declined"),
        ("expired",  "Expired"),
        ("finished", "Finished"),
    ]
    challenger = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="duels_sent")
    opponent   = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="duels_received")
    stake      = models.PositiveIntegerField()
    status     = models.CharField(max_length=20, choices=STATUS_CHOICES, default="pending")
    winner     = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name="duels_won")
    rounds     = models.JSONField(default=list, blank=True)  # list of round results
    hand_c     = models.JSONField(default=list, blank=True)  # challenger's 5 cards
    hand_o     = models.JSONField(default=list, blank=True)  # opponent's 5 cards
    order_c    = models.JSONField(null=True, blank=True)     # challenger's chosen card indices [r1,r2,r3]
    order_o    = models.JSONField(null=True, blank=True)     # opponent's chosen card indices [r1,r2,r3]
    created_at = models.DateTimeField(auto_now_add=True)
    resolved_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        ordering = ["-created_at"]


# ── COIN FLIP ──
class CoinFlip(models.Model):
    user       = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="coin_flips")
    stake      = models.PositiveIntegerField()
    choice     = models.CharField(max_length=6)   # 'heads' or 'tails'
    result     = models.CharField(max_length=6)   # 'heads' or 'tails'
    won        = models.BooleanField()
    payout     = models.IntegerField(default=0)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["-created_at"]


# ── TIC TAC TOE ──
class TicTacToe(models.Model):
    STATUS_CHOICES = [
        ("waiting",  "Waiting for opponent"),
        ("playing",  "In Progress"),
        ("finished", "Finished"),
        ("cancelled","Cancelled"),
    ]
    player_x    = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="ttt_as_x")
    player_o    = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True, related_name="ttt_as_o")
    stake       = models.PositiveIntegerField(default=0)
    board       = models.JSONField(default=list)  # 9-element list
    current     = models.CharField(max_length=1, default="X")  # 'X' or 'O'
    winner      = models.CharField(max_length=1, blank=True, null=True)  # 'X','O','D' (draw)
    status      = models.CharField(max_length=20, choices=STATUS_CHOICES, default="waiting")
    rematch_of  = models.IntegerField(null=True, blank=True)  # previous game id
    created_at  = models.DateTimeField(auto_now_add=True)
    updated_at  = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-created_at"]


# ── TIC TAC TOE ──
class TicTacToe(models.Model):
    STATUS_CHOICES = [
        ("waiting",  "Waiting for opponent"),
        ("playing",  "In Progress"),
        ("finished", "Finished"),
        ("cancelled","Cancelled"),
    ]
    player_x    = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="ttt_as_x")
    player_o    = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True, related_name="ttt_as_o")
    stake       = models.PositiveIntegerField(default=0)
    board       = models.JSONField(default=list)  # 9-element list
    current     = models.CharField(max_length=1, default="X")  # 'X' or 'O'
    winner      = models.CharField(max_length=1, blank=True, null=True)  # 'X','O','D' (draw)
    status      = models.CharField(max_length=20, choices=STATUS_CHOICES, default="waiting")
    rematch_of  = models.IntegerField(null=True, blank=True)  # previous game id
    created_at  = models.DateTimeField(auto_now_add=True)
    updated_at  = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-created_at"]


# ── CHECKERS ──
class Checkers(models.Model):
    STATUS_CHOICES = [
        ("waiting",  "Waiting"),
        ("playing",  "Playing"),
        ("finished", "Finished"),
    ]
    player_r    = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="checkers_as_red")
    player_b    = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True, related_name="checkers_as_black")
    stake       = models.PositiveIntegerField(default=0)
    board       = models.JSONField(default=list)   # 64-element list
    current     = models.CharField(max_length=1, default="r")  # r or b
    winner      = models.CharField(max_length=1, blank=True, null=True)
    status      = models.CharField(max_length=20, choices=STATUS_CHOICES, default="waiting")
    rematch_of  = models.IntegerField(null=True, blank=True)
    created_at  = models.DateTimeField(auto_now_add=True)
    updated_at  = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-created_at"]


# ── MAUA (Kenyan UNO) ──
class MauaGame(models.Model):
    STATUS_CHOICES = [
        ("waiting",  "Waiting for players"),
        ("playing",  "In Progress"),
        ("finished", "Finished"),
    ]
    creator     = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="maua_created")
    players     = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name="maua_games", blank=True)
    stake       = models.PositiveIntegerField(default=0)
    max_players = models.PositiveIntegerField(default=4)
    deck        = models.JSONField(default=list)   # remaining cards
    discard     = models.JSONField(default=list)   # discard pile
    hands       = models.JSONField(default=dict)   # {user_id: [cards]}
    turn_order  = models.JSONField(default=list)   # [user_id, ...]
    current_idx = models.IntegerField(default=0)   # index in turn_order
    direction   = models.IntegerField(default=1)   # 1=clockwise, -1=reverse
    draw_stack  = models.IntegerField(default=0)   # pending draw cards
    current_suit = models.CharField(max_length=10, blank=True)  # after wild
    winner      = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name="maua_wins")
    status      = models.CharField(max_length=20, choices=STATUS_CHOICES, default="waiting")
    created_at  = models.DateTimeField(auto_now_add=True)
    updated_at  = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-created_at"]


class MauaPlayer(models.Model):
    """Track per-player state."""
    game    = models.ForeignKey(MauaGame, on_delete=models.CASCADE, related_name="player_states")
    user    = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    hand    = models.JSONField(default=list)
    score   = models.IntegerField(default=0)
    position = models.IntegerField(default=0)  # finish order

    class Meta:
        unique_together = ["game", "user"]
