# /home/ram/aparsoft/backend/apps/accounts/models/custom_user.py

"""
Custom Django user model for chatbot application.
Supports basic user management with email authentication, roles, and profile features.
"""

from django.db import models
from django.contrib.auth.models import AbstractUser
from django.conf import settings
import logging
from django.utils.translation import gettext_lazy as _
from django.utils import timezone
from django.contrib.postgres.indexes import GinIndex

from core.models import TimestampedModel, Country

from ..utils import helper

logger = logging.getLogger(__name__)


class CustomUser(AbstractUser):
    """Custom user model for chatbot application with email-based authentication."""

    ROLE_CHOICES = [
        ('user', 'User'),
        ('admin', 'Administrator'),
    ]

    # Core fields
    email = models.EmailField(
        _('email address'),
        unique=True,
        help_text=_('Primary email address used for account identification')
    )

    # Role field
    role = models.CharField(
        max_length=20,
        choices=ROLE_CHOICES,
        default='user',
        help_text=_('User role determines access level')
    )

    # Profile management
    profile_picture = models.ImageField(
        upload_to='avatars/',
        blank=True,
        null=True,
        help_text=_('User profile picture/avatar')
    )

    # Verification and security
    email_verified = models.BooleanField(
        default=False,
        help_text=_('Indicates if the email address has been verified')
    )
    phone_verified = models.BooleanField(
        default=False,
        help_text=_('Indicates if the phone number has been verified')
    )
    two_factor_enabled = models.BooleanField(
        default=False,
        help_text=_('Indicates if two-factor authentication is enabled')
    )
    last_password_change = models.DateTimeField(
        auto_now_add=True,
        help_text=_('Timestamp of the last password change')
    )

    # Social auth
    social_auth_providers = models.JSONField(
        default=helper.get_default_social_auth_providers,
        help_text=_('Connected social authentication providers')
    )

    # Activity tracking
    last_active = models.DateTimeField(
        null=True,
        blank=True,
        help_text=_('Timestamp of the user\'s last platform activity')
    )
    login_count = models.PositiveIntegerField(
        default=0,
        help_text=_('Number of times the user has logged in')
    )

    # Override groups and user_permissions to avoid clashes
    groups = models.ManyToManyField(
        'auth.Group',
        verbose_name=_('groups'),
        blank=True,
        help_text=_('The groups this user belongs to.'),
        related_name='customuser_set',
        related_query_name='customuser',
    )
    user_permissions = models.ManyToManyField(
        'auth.Permission',
        verbose_name=_('user permissions'),
        blank=True,
        help_text=_('Specific permissions for this user.'),
        related_name='customuser_set',
        related_query_name='customuser',
    )

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username']

    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')
        ordering = ['-date_joined']
        app_label = 'accounts'
        indexes = [
            models.Index(fields=['email'], name='user_email_idx'),
            models.Index(fields=['username'], name='user_username_idx'),
            models.Index(fields=['role'], name='user_role_idx'),
            models.Index(fields=['last_active'], name='user_last_active_idx'),
            models.Index(fields=['date_joined'], name='user_date_joined_idx'),
            models.Index(fields=['email_verified'], name='user_email_verified_idx'),
            models.Index(fields=['email_verified', 'last_active'], name='user_verified_active_idx'),
            GinIndex(fields=['social_auth_providers'], name='user_social_auth_gin_idx'),
        ]

    def __str__(self) -> str:
        return self.email

    @property
    def full_name(self) -> str:
        """Return user's full name or username."""
        if self.first_name and self.last_name:
            return f"{self.first_name} {self.last_name}"
        return self.username

    @property
    def account_age_days(self) -> int:
        """Get account age in days."""
        return (timezone.now() - self.date_joined).days

    @property
    def is_admin_user(self) -> bool:
        """Check if user is an admin."""
        return self.role == 'admin'

    def update_last_active(self, save: bool = True) -> None:
        """Update user's last active timestamp."""
        self.last_active = timezone.now()
        if save:
            self.save(update_fields=['last_active'])

    def verify_email(self) -> bool:
        """Verify user's email address."""
        if not self.email_verified:
            self.email_verified = True
            self.save(update_fields=['email_verified'])
            return True
        return False


class UserContact(TimestampedModel):
    """User contact information."""
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='contact'
    )
    address_line1 = models.CharField(max_length=255, blank=True, null=True)
    address_line2 = models.CharField(max_length=255, blank=True, null=True)
    city = models.CharField(max_length=100, blank=True, null=True)
    state = models.CharField(max_length=100, blank=True, null=True)
    postal_code = models.CharField(max_length=20, blank=True, null=True)
    country = models.ForeignKey(
        Country,
        on_delete=models.SET_DEFAULT,
        default=1,
        null=True,
        help_text=_('Country of residence')
    )
    contact_info = models.JSONField(
        default=helper.get_default_user_contact_info,
        null=True,
        blank=True,
        help_text=_('Structured contact information including phones and social profiles')
    )
    billing_details = models.JSONField(
        default=dict,
        null=True,
        blank=True,
        help_text=_('Billing information for invoicing')
    )

    timezone = models.CharField(
        max_length=100,
        blank=True,
        null=True,
        help_text=_('User timezone')
    )

    availability = models.JSONField(
        default=dict,
        null=True,
        blank=True,
        help_text=_('User availability schedule')
    )

    class Meta:
        indexes = [
            models.Index(fields=['user'], name='user_contact_user_idx'),
            GinIndex(fields=['contact_info'], name='user_contact_info_gin_idx'),
            GinIndex(fields=['billing_details'], name='user_billing_gin_idx'),
            GinIndex(fields=['availability'], name='user_availability_gin_idx'),
        ]

    def __str__(self) -> str:
        return f"Contact for {self.user.email}"
