from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import gettext_lazy as _
from django.utils import timezone
from datetime import timedelta
import secrets


class UserRole(models.TextChoices):
    SUPER_ADMIN = 'super_admin', _('Super Admin')
    ADMIN = 'admin', _('Admin')
    PLACE_ADMIN = 'place_admin', _('Place Admin')
    USER = 'user', _('User')


class User(AbstractUser):
    """Custom User Model"""
    role = models.CharField(
        max_length=20,
        choices=UserRole.choices,
        default=UserRole.USER,
        verbose_name=_('Role')
    )
    phone = models.CharField(
        max_length=20,
        blank=True,
        null=True,
        verbose_name=_('Phone')
    )
    avatar = models.ImageField(
        upload_to='avatars/',
        blank=True,
        null=True,
        verbose_name=_('Avatar')
    )
    is_verified = models.BooleanField(
        default=False,
        verbose_name=_('Is Verified')
    )
    email_verified = models.BooleanField(
        default=False,
        verbose_name=_('Email Verified')
    )
    phone_verified = models.BooleanField(
        default=False,
        verbose_name=_('Phone Verified')
    )
    language = models.CharField(
        max_length=10,
        default='ar',
        choices=[('ar', 'Arabic'), ('ku', 'Kurdish'), ('en', 'English')],
        verbose_name=_('Language')
    )
    theme = models.CharField(
        max_length=10,
        default='system',
        choices=[('system', 'System'), ('light', 'Light'), ('dark', 'Dark')],
        verbose_name=_('Theme')
    )
    notifications_enabled = models.BooleanField(
        default=True,
        verbose_name=_('Notifications Enabled')
    )
    fcm_token = models.CharField(
        max_length=255,
        blank=True,
        null=True,
        verbose_name=_('FCM Token')
    )
    # Social Login fields
    social_provider = models.CharField(
        max_length=20,
        blank=True,
        null=True,
        choices=[('google', 'Google'), ('apple', 'Apple'), ('facebook', 'Facebook')],
        verbose_name=_('Social Provider')
    )
    social_id = models.CharField(
        max_length=255,
        blank=True,
        null=True,
        unique=True,
        verbose_name=_('Social ID')
    )
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = _('User')
        verbose_name_plural = _('Users')
        ordering = ['-created_at']

    def __str__(self):
        return self.username

    @property
    def is_super_admin(self):
        return self.role == UserRole.SUPER_ADMIN

    @property
    def is_admin(self):
        return self.role == UserRole.ADMIN

    @property
    def is_place_admin(self):
        return self.role == UserRole.PLACE_ADMIN


class PasswordResetToken(models.Model):
    """Password Reset Token Model"""
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='password_reset_tokens',
        verbose_name=_('User')
    )
    token = models.CharField(max_length=100, unique=True, verbose_name=_('Token'))
    created_at = models.DateTimeField(auto_now_add=True)
    expires_at = models.DateTimeField(verbose_name=_('Expires At'))
    used = models.BooleanField(default=False, verbose_name=_('Used'))

    class Meta:
        verbose_name = _('Password Reset Token')
        verbose_name_plural = _('Password Reset Tokens')
        ordering = ['-created_at']

    def __str__(self):
        return f'{self.user.username} - {self.token[:10]}...'

    def is_valid(self):
        """Check if token is valid"""
        return not self.used and timezone.now() < self.expires_at

    @classmethod
    def generate_token(cls, user):
        """Generate a new password reset token"""
        token = secrets.token_urlsafe(32)
        expires_at = timezone.now() + timedelta(hours=1)
        return cls.objects.create(
            user=user,
            token=token,
            expires_at=expires_at
        )


class VerificationCode(models.Model):
    """Verification Code Model for Email/Phone"""
    class VerificationType(models.TextChoices):
        EMAIL = 'email', _('Email')
        PHONE = 'phone', _('Phone')

    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='verification_codes',
        verbose_name=_('User')
    )
    type = models.CharField(
        max_length=10,
        choices=VerificationType.choices,
        verbose_name=_('Type')
    )
    code = models.CharField(max_length=6, verbose_name=_('Code'))
    created_at = models.DateTimeField(auto_now_add=True)
    expires_at = models.DateTimeField(verbose_name=_('Expires At'))
    used = models.BooleanField(default=False, verbose_name=_('Used'))

    class Meta:
        verbose_name = _('Verification Code')
        verbose_name_plural = _('Verification Codes')
        ordering = ['-created_at']

    def __str__(self):
        return f'{self.user.username} - {self.type} - {self.code}'

    def is_valid(self):
        """Check if code is valid"""
        return not self.used and timezone.now() < self.expires_at

    @classmethod
    def generate_code(cls, user, verification_type):
        """Generate a new verification code"""
        code = ''.join([str(secrets.randbelow(10)) for _ in range(6)])
        expires_at = timezone.now() + timedelta(minutes=10)
        return cls.objects.create(
            user=user,
            type=verification_type,
            code=code,
            expires_at=expires_at
        )


class PlaceAdmin(models.Model):
    """Place Admin - Links User to Place"""
    user = models.OneToOneField(
        User,
        on_delete=models.CASCADE,
        related_name='place_admin_profile',
        verbose_name=_('User')
    )
    place = models.ForeignKey(
        'places.Place',
        on_delete=models.CASCADE,
        related_name='admins',
        verbose_name=_('Place')
    )
    permissions = models.JSONField(
        default=dict,
        blank=True,
        verbose_name=_('Permissions')
    )
    can_manage_bookings = models.BooleanField(
        default=True,
        verbose_name=_('Can Manage Bookings')
    )
    can_manage_reviews = models.BooleanField(
        default=True,
        verbose_name=_('Can Manage Reviews')
    )
    can_manage_offers = models.BooleanField(
        default=True,
        verbose_name=_('Can Manage Offers')
    )
    can_manage_place_info = models.BooleanField(
        default=True,
        verbose_name=_('Can Manage Place Info')
    )
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = _('Place Admin')
        verbose_name_plural = _('Place Admins')
        unique_together = ['user', 'place']

    def __str__(self):
        return f'{self.user.username} - {self.place.name}'
