from django.db import models
from django.utils import timezone
from attendance.models import RegisteredUser
from registration.models import Event

class FeedbackCategory(models.Model):
    name = models.CharField(max_length=100, unique=True)
    description = models.TextField(blank=True, null=True)
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    
    class Meta:
        verbose_name_plural = "Feedback Categories"
        ordering = ['name']
    
    def __str__(self):
        return self.name

class FeedbackTag(models.Model):
    name = models.CharField(max_length=50, unique=True)
    count = models.PositiveIntegerField(default=1)  # To track frequency for word cloud
    created_at = models.DateTimeField(auto_now_add=True)
    
    def __str__(self):
        return self.name
    
    class Meta:
        ordering = ['-count']  # Order by frequency

class Feedback(models.Model):
    RATING_CHOICES = (
        (1, '1 - Very Poor'),
        (2, '2 - Poor'),
        (3, '3 - Average'),
        (4, '4 - Good'),
        (5, '5 - Excellent'),
    )
    
    # User information
    registered_user = models.ForeignKey(RegisteredUser, on_delete=models.SET_NULL, null=True, blank=True)
    name = models.CharField(max_length=255, blank=True, null=True)
    email = models.EmailField(blank=True, null=True)
    registration_code = models.CharField(max_length=100, blank=True, null=True)
    is_anonymous = models.BooleanField(default=False)
    
    # Event information - NEW: Link to Event model
    event = models.ForeignKey(Event, on_delete=models.CASCADE, related_name='feedbacks', null=True, blank=True)
    event_name = models.CharField(max_length=255, blank=True, null=True)  # Backup field for legacy data
    
    # Feedback content
    category = models.ForeignKey(FeedbackCategory, on_delete=models.SET_NULL, null=True, blank=True)
    rating = models.PositiveSmallIntegerField(choices=RATING_CHOICES, default=3)
    comment = models.TextField()
    tags = models.ManyToManyField(FeedbackTag, blank=True)
    
    # Metadata
    ip_address = models.GenericIPAddressField(blank=True, null=True)  # For tracking
    created_at = models.DateTimeField(default=timezone.now)
    is_published = models.BooleanField(default=True)  # For moderation
    
    def __str__(self):
        event_info = f" for {self.get_event_name()}" if self.get_event_name() else ""
        if self.registered_user:
            return f'Feedback from {self.registered_user.full_name}{event_info}'
        elif self.name:
            return f'Feedback from {self.name}{event_info}'
        else:
            return f'Anonymous Feedback #{self.id}{event_info}'
    
    def get_event_name(self):
        """Get event name, preferring the linked event over the legacy event_name field"""
        if self.event:
            return self.event.name
        elif self.event_name:
            return self.event_name
        else:
            return "Legacy Feedback"
    
    @property
    def display_event(self):
        """Property to get event for display purposes"""
        return self.event if self.event else None
    
    def save(self, *args, **kwargs):
        # If registration code is provided but no registered user, try to find the user
        if not self.registered_user and self.registration_code:
            try:
                # First try to find in RegisteredUser (attendance module)
                user = RegisteredUser.objects.get(registration_code=self.registration_code)
                self.registered_user = user
                if not self.event_name:
                    self.event_name = user.event_name
            except RegisteredUser.DoesNotExist:
                # Try to find in Registration model
                try:
                    from registration.models import Registration
                    registration = Registration.objects.get(registration_code=self.registration_code)
                    if not self.event:
                        self.event = registration.event
                    if not self.event_name:
                        self.event_name = registration.event.name
                except Registration.DoesNotExist:
                    pass
        
        # If we have an event but no event_name, set it
        if self.event and not self.event_name:
            self.event_name = self.event.name
            
        super().save(*args, **kwargs)
    
    class Meta:
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['event', 'created_at']),
            models.Index(fields=['event_name', 'created_at']),
        ]

class FeedbackConfiguration(models.Model):
    SINGLE_EVENT = 'single'
    MULTI_EVENT = 'multi'
    
    EVENT_SELECTION_CHOICES = [
        (SINGLE_EVENT, 'Single Active Event'),
        (MULTI_EVENT, 'Multiple Active Events (User Choice)'),
    ]
    
    # Event selection mode
    event_selection_mode = models.CharField(
        max_length=10, 
        choices=EVENT_SELECTION_CHOICES, 
        default=SINGLE_EVENT,
        help_text="Choose whether to allow single or multiple active events for feedback"
    )
    
    # Single event mode (legacy)
    active_event = models.ForeignKey(
        Event, 
        on_delete=models.SET_NULL, 
        null=True, 
        blank=True,
        related_name='feedback_config_single',
        help_text="Primary active event (used in single mode or as default in multi mode)"
    )
    
    # Multi-event mode
    active_events = models.ManyToManyField(
        Event, 
        blank=True,
        related_name='feedback_config_multi',
        help_text="Multiple events that can receive feedback simultaneously"
    )
    
    # Configuration settings
    feedback_enabled = models.BooleanField(default=True)
    auto_enable_events = models.BooleanField(
        default=False,
        help_text="Automatically enable events happening today for feedback collection"
    )
    
    # Messages
    welcome_message = models.TextField(
        default="Welcome to our feedback system! Your input helps us improve future events.",
        help_text="Message shown to users on the feedback form"
    )
    thank_you_message = models.TextField(
        default="Thank you for your feedback! Your input is valuable to us.",
        help_text="Message shown after successful feedback submission"
    )
    disabled_message = models.TextField(
        default="Feedback collection is currently disabled. Please check back later.",
        help_text="Message shown when feedback is disabled"
    )
    
    # Metadata
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    class Meta:
        verbose_name = "Feedback Configuration"
        verbose_name_plural = "Feedback Configurations"
    
    def __str__(self):
        if self.event_selection_mode == self.MULTI_EVENT:
            count = self.active_events.count()
            return f"Multi-Event Config ({count} active events)"
        elif self.active_event:
            return f"Single Event Config: {self.active_event.name}"
        else:
            return "Feedback Configuration (No active event)"
    
    @classmethod
    def get_active_config(cls):
        """Get or create the active feedback configuration"""
        config, created = cls.objects.get_or_create(
            id=1,  # Singleton pattern
            defaults={
                'feedback_enabled': True,
                'event_selection_mode': cls.SINGLE_EVENT,
            }
        )
        
        # Auto-enable today's events if configured
        if config.auto_enable_events:
            config.auto_enable_todays_events()
        
        return config
    
    def get_available_events(self):
        """Get list of events available for feedback based on current mode"""
        if not self.feedback_enabled:
            return []
            
        if self.event_selection_mode == self.MULTI_EVENT:
            # In multi-event mode, return all active events
            events = list(self.active_events.filter(is_active=True))
            
            # Also include the primary active_event if it's not already in the list
            if self.active_event and self.active_event.is_active and self.active_event not in events:
                events.insert(0, self.active_event)
                
            return events
        else:
            # In single event mode, return only the active_event
            if self.active_event and self.active_event.is_active:
                return [self.active_event]
            return []
    
    def is_event_active(self, event):
        """Check if a specific event is active for feedback"""
        if not self.feedback_enabled or not event.is_active:
            return False
            
        available_events = self.get_available_events()
        return event in available_events
    
    def auto_enable_todays_events(self):
        """Automatically enable events happening today"""
        if not self.auto_enable_events:
            return
            
        today = timezone.now().date()
        todays_events = Event.objects.filter(
            start_date__date=today,
            is_active=True
        )
        
        if self.event_selection_mode == self.MULTI_EVENT:
            # Add today's events to active_events
            for event in todays_events:
                self.active_events.add(event)
        else:
            # Set the first today's event as active_event
            first_event = todays_events.first()
            if first_event:
                self.active_event = first_event
                self.save()
    
    def add_active_event(self, event):
        """Add an event to active events (switches to multi-event mode if needed)"""
        if self.event_selection_mode == self.SINGLE_EVENT:
            # If in single mode, just set as active_event
            self.active_event = event
            self.save()
        else:
            # If in multi mode, add to active_events
            self.active_events.add(event)
    
    def remove_active_event(self, event):
        """Remove an event from active events"""
        if self.event_selection_mode == self.MULTI_EVENT:
            self.active_events.remove(event)
        
        # If this was the primary active_event, clear it
        if self.active_event == event:
            self.active_event = None
            self.save()
