from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from django.utils import timezone
import uuid
import random
from django.contrib.auth.models import Group as DjangoGroup # Import Django's built-in Group for potential reference if needed


class CustomPermission(models.Model):
    ACTION_CHOICES = [
        ("insert", "Insert"),
        ("view", "View"),
        ("edit", "Edit"),
        ("delete", "Delete"),
    ]
    action = models.CharField(max_length=10, choices=ACTION_CHOICES, unique=True)

    def __str__(self):
        return self.action


class CustomRoleGroup(models.Model):
    role = models.CharField(max_length=150, unique=True)

class CustomGroup(models.Model):
    name = models.CharField(max_length=150, unique=True)

class RoleGroupPermission(models.Model):
    role = models.ForeignKey(CustomRoleGroup, on_delete=models.CASCADE)
    group = models.ForeignKey(CustomGroup, on_delete=models.CASCADE)
    permissions = models.ManyToManyField(CustomPermission)

    class Meta:
        unique_together = ('role', 'group')

class UserManager(BaseUserManager):
    def create_user(self, email, password=None, **extra_fields):
        if not email:
            raise ValueError('The Email field must be set')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_active', True)
        extra_fields.setdefault('email_verified', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        return self.create_user(email, password, **extra_fields)

class User(AbstractBaseUser, PermissionsMixin):
    ROLE_CHOICES = (
        ('admin', 'Admin'),
        ('manager', 'Manager'),
        ('client', 'Client'),
        ('employee', 'Employee'),
        ('agent', 'Agent'),
        ('sub_admin', 'Sub_Admin'),
    )
    STATUS_CHOICES = (
        ('Accepted', 'accepted'),
        ('Pending', 'pending'),
        ('Rejected', 'rejected'),
    )

    id = models.BigAutoField(primary_key=True)
    email = models.EmailField(unique=True)
    full_name = models.CharField(max_length=30, blank=True, null=True)
    role = models.CharField(max_length=20, default='client')
    is_active = models.BooleanField(default=False)  # False until email verified
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    date_joined = models.DateTimeField(default=timezone.now)
    email_verified = models.BooleanField(default=False)
    country = models.ForeignKey('country.Country', on_delete=models.SET_NULL,blank=True,null=True)

    # Common fields
    created_by = models.SmallIntegerField(null=True, blank=True)
    updated_at = models.DateTimeField(null=True, blank=True)
    updated_by = models.SmallIntegerField(null=True, blank=True)

    # Token fields
    verification_token = models.CharField(max_length=100, blank=True, null=True)
    verification_token_expires = models.DateTimeField(blank=True, null=True)

    reset_token = models.CharField(max_length=100, blank=True, null=True)
    reset_token_expires = models.DateTimeField(blank=True, null=True)

    groups = models.ManyToManyField(CustomGroup, blank=True,null=True)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []  # Email is already required by default
    status = models.CharField(max_length=20, default="pending",blank=True,null=True)

    def __str__(self):
        return self.email

    def get_full_name(self):
        return self.full_name if self.full_name else self.email

    def create_verification_token(self):
        # Generate a random token instead of UUID
        token = ''.join([str(random.randint(0, 9)) for _ in range(6)])
        self.verification_token = token
        self.verification_token_expires = timezone.now() + timezone.timedelta(days=1)
        self.save()
        return token

    def verify_email(self):
        self.email_verified = True
        self.verification_token = None
        self.verification_token_expires = None
        self.is_active=True
        self.save()

    def create_reset_token(self):
        # Generate a random token instead of UUID
        token = ''.join([str(random.randint(0, 9)) for _ in range(6)])
        self.verification_token = token
        self.verification_token_expires = timezone.now() + timezone.timedelta(hours=1)
        self.reset_token = token
        self.reset_token_expires = timezone.now() + timezone.timedelta(hours=1)
        self.save()
        return token

    def reset_password(self, password):
        self.set_password(password)
        self.reset_token = None
        self.reset_token_expires = None
        self.save()