from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
from django.utils import timezone


class UserManager(BaseUserManager):

    def create_user(self, email, username, password=None, **extra_fields):
        if not email:
            raise ValueError("Users must have an email")
        if not username:
            raise ValueError("Users must have a username")
        email = self.normalize_email(email)
        user = self.model(email=email, username=username, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, username, password=None, **extra_fields):
        extra_fields.setdefault("role", "admin")
        extra_fields.setdefault("is_staff", True)
        extra_fields.setdefault("is_superuser", True)
        return self.create_user(email, username, password, **extra_fields)


NEIGHBORHOOD_CHOICES = [
    ("makongeni", "Makongeni"),
    ("township", "Township"),
    ("landless", "Landless"),
    ("kiandutu", "Kiandutu"),
    ("gatuanyaga", "Gatuanyaga"),
    ("thika_greens", "Thika Greens"),
    ("section_9", "Section 9"),
    ("ngoigwa", "Ngoigwa"),
    ("kamenu", "Kamenu"),
    ("other", "Other"),
]

WARD_CHOICES = [
    ("thika_east", "Thika East"),
    ("thika_west", "Thika West"),
    ("hospital", "Hospital"),
    ("kamenu", "Kamenu"),
    ("gatuanyaga", "Gatuanyaga"),
    ("other", "Other"),
]


class User(AbstractBaseUser, PermissionsMixin):
    ROLE_CHOICES = (
        ("resident", "Resident"),
        ("moderator", "Moderator"),
        ("admin", "Admin"),
    )

    email       = models.EmailField(unique=True)
    username    = models.CharField(max_length=50)
    role        = models.CharField(max_length=20, choices=ROLE_CHOICES, default="resident")

    bio           = models.TextField(blank=True, null=True)
    is_verified   = models.BooleanField(default=False)
    verification_status = models.CharField(max_length=20, choices=[
        ("none","None"),("pending","Pending"),("approved","Approved"),("rejected","Rejected")
    ], default="none")
    verified_at   = models.DateTimeField(null=True, blank=True)
    phone         = models.CharField(max_length=20, blank=True, null=True)
    profile_image = models.ImageField(upload_to="profiles/", blank=True, null=True)

    neighborhood = models.CharField(
        max_length=50, choices=NEIGHBORHOOD_CHOICES, blank=True, null=True
    )
    ward = models.CharField(
        max_length=50, choices=WARD_CHOICES, blank=True, null=True
    )

    followers_count = models.PositiveIntegerField(default=0)
    following_count = models.PositiveIntegerField(default=0)

    is_active = models.BooleanField(default=True)
    is_staff  = models.BooleanField(default=False)

    date_joined = models.DateTimeField(default=timezone.now)
    last_seen   = models.DateTimeField(null=True, blank=True)

    USERNAME_FIELD  = "email"
    REQUIRED_FIELDS = ["username"]

    objects = UserManager()

    def __str__(self):
        return f"{self.username} ({self.neighborhood or 'Thika'})"

    @property
    def is_online(self):
        if not self.last_seen:
            return False
        from django.utils import timezone as tz
        return (tz.now() - self.last_seen).seconds < 300


class PasswordResetToken(models.Model):
    user       = models.ForeignKey(User, on_delete=models.CASCADE, related_name="reset_tokens")
    token      = models.CharField(max_length=128, unique=True)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"ResetToken({self.user.email})"

class EmailVerification(models.Model):
    user       = models.OneToOneField(User, on_delete=models.CASCADE, related_name="email_verification")
    otp        = models.CharField(max_length=6)
    created_at = models.DateTimeField(auto_now_add=True)
    expires_at = models.DateTimeField()
    is_used    = models.BooleanField(default=False)

    def is_expired(self):
        from django.utils import timezone
        return timezone.now() > self.expires_at

    def __str__(self):
        return f"OTP({self.user.email})"
