"""
MongoDB Models using MongoEngine
These models store data in MongoDB instead of relational database.
"""

from mongoengine import Document, StringField, BooleanField, DateTimeField, EmailField, IntField
from django.contrib.auth.hashers import make_password, check_password
from django.utils import timezone
import random
import string


class User(Document):
    """
    User model stored in MongoDB.
    Uses email as the primary identifier.
    """
    email = EmailField(required=True, unique=True)
    first_name = StringField(required=True, max_length=150)
    last_name = StringField(max_length=150)
    phone_number = StringField(max_length=20)
    password = StringField(required=True)

    # Authentication fields
    is_email_verified = BooleanField(default=False)
    is_active = BooleanField(default=True)
    is_staff = BooleanField(default=False)
    is_superuser = BooleanField(default=False)

    # OAuth fields
    is_google_user = BooleanField(default=False)
    google_id = StringField()

    # Timestamps
    date_joined = DateTimeField(default=timezone.now)
    last_login = DateTimeField()

    # Profile fields
    profile_picture = StringField()  # Store URL or path
    bio = StringField()

    meta = {
        'collection': 'users',
        'indexes': ['email']
    }

    def set_password(self, raw_password):
        """Hash and set the password"""
        self.password = make_password(raw_password)

    def check_password(self, raw_password):
        """Check if the provided password is correct"""
        return check_password(raw_password, self.password)

    def get_full_name(self):
        """Return the user's full name"""
        if self.last_name:
            return f"{self.first_name} {self.last_name}"
        return self.first_name

    def __str__(self):
        return self.email


class EmailVerificationOTP(Document):
    """
    Model to store OTP for email verification during registration.
    """
    email = EmailField(required=True)
    otp = StringField(required=True, max_length=6)
    created_at = DateTimeField(default=timezone.now)
    is_verified = BooleanField(default=False)

    # Store temporary user data
    first_name = StringField(required=True, max_length=150)
    last_name = StringField(max_length=150)
    phone_number = StringField(max_length=20)
    password_hash = StringField(required=True)

    meta = {
        'collection': 'email_verification_otps',
        'indexes': ['email', 'created_at']
    }

    @staticmethod
    def generate_otp():
        """Generate a random 6-digit OTP"""
        return ''.join(random.choices(string.digits, k=6))

    def is_expired(self):
        """Check if OTP is expired (10 minutes)"""
        from datetime import timedelta
        from django.conf import settings
        expiry_time = getattr(settings, 'OTP_EXPIRY_MINUTES', 10)
        return timezone.now() > self.created_at + timedelta(minutes=expiry_time)

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


class PasswordResetToken(Document):
    """
    Model to store temporary passwords for password reset.
    """
    user_email = EmailField(required=True)
    temp_password = StringField(required=True, max_length=12)
    created_at = DateTimeField(default=timezone.now)
    is_used = BooleanField(default=False)

    meta = {
        'collection': 'password_reset_tokens',
        'indexes': ['user_email', 'created_at']
    }

    @staticmethod
    def generate_temp_password():
        """Generate a random temporary password"""
        return ''.join(random.choices(string.ascii_letters + string.digits, k=12))

    def is_expired(self):
        """Check if token is expired (30 minutes)"""
        from datetime import timedelta
        return timezone.now() > self.created_at + timedelta(minutes=30)

    def __str__(self):
        return f"Password reset for {self.user_email}"
