from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
from django.core.validators import EmailValidator
import random
import string

class TicketStatus(models.Model):
    name = models.CharField(max_length=50, unique=True)
    color = models.CharField(max_length=7, default='#667eea', help_text='Hex color code')
    description = models.TextField(blank=True)
    is_closed = models.BooleanField(default=False, help_text='Whether this status represents a closed ticket')
    is_active = models.BooleanField(default=True)
    display_order = models.PositiveIntegerField(default=0)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['display_order', 'name']
        verbose_name_plural = 'Ticket Statuses'

    def __str__(self):
        return self.name


class TicketPriority(models.Model):
    name = models.CharField(max_length=50, unique=True)
    level = models.PositiveIntegerField(unique=True, help_text='Lower number = higher priority')
    color = models.CharField(max_length=7, default='#667eea', help_text='Hex color code')
    description = models.TextField(blank=True)
    sla_hours = models.PositiveIntegerField(default=24, help_text='SLA response time in hours')
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['level']
        verbose_name_plural = 'Ticket Priorities'

    def __str__(self):
        return self.name


class TicketCategory(models.Model):
    name = models.CharField(max_length=100, unique=True)
    description = models.TextField(blank=True)
    color = models.CharField(max_length=7, default='#667eea', help_text='Hex color code')
    icon = models.CharField(max_length=50, default='fa-question-circle', help_text='FontAwesome icon class')
    is_active = models.BooleanField(default=True)
    display_order = models.PositiveIntegerField(default=0)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['display_order', 'name']
        verbose_name_plural = 'Ticket Categories'

    def __str__(self):
        return self.name


class SupportTicket(models.Model):
    TICKET_TYPES = [
        ('technical', 'Technical Issue'),
        ('billing', 'Billing Question'),
        ('feature_request', 'Feature Request'),
        ('bug_report', 'Bug Report'),
        ('general', 'General Inquiry'),
        ('account', 'Account Issue'),
    ]

    ticket_number = models.CharField(max_length=20, unique=True, editable=False)
    title = models.CharField(max_length=200)
    description = models.TextField()
    ticket_type = models.CharField(max_length=20, choices=TICKET_TYPES, default='general')
    
    # User information
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='support_tickets', null=True, blank=True)
    user_name = models.CharField(max_length=100)
    user_email = models.EmailField()
    user_phone = models.CharField(max_length=20, blank=True)
    company = models.CharField(max_length=100, blank=True)
    
    # Ticket management
    category = models.ForeignKey(TicketCategory, on_delete=models.SET_NULL, null=True, blank=True)
    priority = models.ForeignKey(TicketPriority, on_delete=models.SET_NULL, null=True, blank=True)
    status = models.ForeignKey(TicketStatus, on_delete=models.SET_NULL, null=True, blank=True)
    assigned_to = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='assigned_tickets')
    assigned_at = models.DateTimeField(null=True, blank=True)
    
    # Timestamps
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    closed_at = models.DateTimeField(null=True, blank=True)
    last_activity = models.DateTimeField(auto_now=True)
    first_response_at = models.DateTimeField(null=True, blank=True)
    sla_deadline = models.DateTimeField(null=True, blank=True)
    
    # Additional fields
    tags = models.CharField(max_length=500, blank=True, help_text='Comma-separated tags')
    internal_notes = models.TextField(blank=True, help_text='Internal notes visible only to staff')
    is_escalated = models.BooleanField(default=False)
    escalation_reason = models.TextField(blank=True)
    attachments = models.JSONField(default=list, blank=True, help_text='List of file paths')

    class Meta:
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['ticket_number']),
            models.Index(fields=['user_email']),
            models.Index(fields=['status']),
            models.Index(fields=['priority']),
            models.Index(fields=['assigned_to']),
            models.Index(fields=['created_at']),
        ]

    def __str__(self):
        return f"{self.ticket_number} - {self.title}"

    def save(self, *args, **kwargs):
        if not self.ticket_number:
            self.ticket_number = self.generate_ticket_number()
        
        # Set SLA deadline based on priority
        if not self.sla_deadline and self.priority:
            self.sla_deadline = timezone.now() + timezone.timedelta(hours=self.priority.sla_hours)
        
        super().save(*args, **kwargs)

    @staticmethod
    def generate_ticket_number():
        """Generate a unique ticket number in format: TKT-YYYYMMDD-XXXXX"""
        today = timezone.now().strftime('%Y%m%d')
        random_str = ''.join(random.choices(string.ascii_uppercase + string.digits, k=5))
        ticket_number = f'TKT-{today}-{random_str}'
        
        # Ensure uniqueness
        while SupportTicket.objects.filter(ticket_number=ticket_number).exists():
            random_str = ''.join(random.choices(string.ascii_uppercase + string.digits, k=5))
            ticket_number = f'TKT-{today}-{random_str}'
        
        return ticket_number


class TicketMessage(models.Model):
    MESSAGE_TYPES = [
        ('user_message', 'User Message'),
        ('agent_response', 'Agent Response'),
        ('system_note', 'System Note'),
        ('status_change', 'Status Change'),
        ('assignment_change', 'Assignment Change'),
        ('escalation', 'Escalation'),
    ]

    ticket = models.ForeignKey(SupportTicket, on_delete=models.CASCADE, related_name='messages')
    message_type = models.CharField(max_length=20, choices=MESSAGE_TYPES, default='user_message')
    content = models.TextField()
    
    # Author information
    author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='ticket_messages')
    author_name = models.CharField(max_length=100, blank=True)
    author_email = models.EmailField(blank=True)
    
    # Message metadata
    is_internal = models.BooleanField(default=False, help_text='Internal message not visible to user')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    attachments = models.JSONField(default=list, blank=True, help_text='List of file paths')
    
    # Read status
    is_read = models.BooleanField(default=False)
    read_at = models.DateTimeField(null=True, blank=True)
    read_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='read_messages')

    class Meta:
        ordering = ['created_at']
        indexes = [
            models.Index(fields=['ticket', 'created_at']),
            models.Index(fields=['author']),
            models.Index(fields=['message_type']),
        ]

    def __str__(self):
        return f"Message on {self.ticket.ticket_number} at {self.created_at}"


class TicketActivity(models.Model):
    ACTIVITY_TYPES = [
        ('created', 'Ticket Created'),
        ('updated', 'Ticket Updated'),
        ('status_changed', 'Status Changed'),
        ('assigned', 'Ticket Assigned'),
        ('message_added', 'Message Added'),
        ('escalated', 'Ticket Escalated'),
        ('closed', 'Ticket Closed'),
        ('reopened', 'Ticket Reopened'),
    ]

    ticket = models.ForeignKey(SupportTicket, on_delete=models.CASCADE, related_name='activities')
    activity_type = models.CharField(max_length=20, choices=ACTIVITY_TYPES)
    description = models.TextField()
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='ticket_activities')
    user_name = models.CharField(max_length=100, blank=True)
    old_value = models.TextField(blank=True)
    new_value = models.TextField(blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['ticket', 'created_at']),
            models.Index(fields=['activity_type']),
        ]

    def __str__(self):
        return f"{self.activity_type} - {self.ticket.ticket_number}"


class KnowledgeBaseCategory(models.Model):
    name = models.CharField(max_length=100, unique=True)
    slug = models.SlugField(max_length=120, unique=True)
    description = models.TextField(blank=True)
    icon = models.CharField(max_length=50, default='fa-book', help_text='FontAwesome icon class')
    color = models.CharField(max_length=7, default='#667eea', help_text='Hex color code')
    is_active = models.BooleanField(default=True)
    display_order = models.PositiveIntegerField(default=0)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['display_order', 'name']
        verbose_name_plural = 'Knowledge Base Categories'

    def __str__(self):
        return self.name


class KnowledgeBaseArticle(models.Model):
    title = models.CharField(max_length=200)
    slug = models.SlugField(max_length=220, unique=True)
    category = models.ForeignKey(KnowledgeBaseCategory, on_delete=models.SET_NULL, null=True, related_name='articles')
    content = models.TextField()
    summary = models.TextField(blank=True, help_text='Short summary of the article')
    
    # SEO and metadata
    meta_description = models.CharField(max_length=160, blank=True)
    keywords = models.CharField(max_length=500, blank=True, help_text='Comma-separated keywords')
    
    # Article management
    author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='kb_articles')
    is_published = models.BooleanField(default=False)
    is_featured = models.BooleanField(default=False)
    view_count = models.PositiveIntegerField(default=0)
    helpful_count = models.PositiveIntegerField(default=0)
    not_helpful_count = models.PositiveIntegerField(default=0)
    
    # Timestamps
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    published_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['slug']),
            models.Index(fields=['category']),
            models.Index(fields=['is_published']),
            models.Index(fields=['created_at']),
        ]

    def __str__(self):
        return self.title


class SupportSettings(models.Model):
    setting_name = models.CharField(max_length=100, unique=True)
    setting_value = models.TextField()
    description = models.TextField(blank=True)
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name_plural = 'Support Settings'

    def __str__(self):
        return self.setting_name


class RegisteredEmail(models.Model):
    """
    Email addresses that are authorized to submit support tickets
    Only admins can add/remove emails from this list
    """
    email = models.EmailField(unique=True, validators=[EmailValidator()])
    company_name = models.CharField(max_length=200, blank=True, help_text='Company or organization name')
    contact_name = models.CharField(max_length=200, blank=True, help_text='Primary contact name')
    notes = models.TextField(blank=True, help_text='Internal notes about this registration')
    is_active = models.BooleanField(default=True, help_text='Whether this email can submit tickets')
    added_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='registered_emails')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    last_ticket_date = models.DateTimeField(null=True, blank=True, help_text='Last time this email submitted a ticket')
    ticket_count = models.PositiveIntegerField(default=0, help_text='Total number of tickets submitted')

    class Meta:
        ordering = ['-created_at']
        verbose_name = 'Registered Email'
        verbose_name_plural = 'Registered Emails'
        indexes = [
            models.Index(fields=['email']),
            models.Index(fields=['is_active']),
        ]

    def __str__(self):
        return f"{self.email} ({self.company_name or 'No company'})"
    
    def increment_ticket_count(self):
        """Increment ticket count and update last ticket date"""
        self.ticket_count += 1
        self.last_ticket_date = timezone.now()
        self.save(update_fields=['ticket_count', 'last_ticket_date'])
