from django.db import models
from django.utils import timezone
from django.core.validators import MinValueValidator
import uuid
import random
import string


def generate_unique_code(length=5):
    """Generate a unique registration code of specified length"""
    characters = string.digits
    while True:
        code = ''.join(random.choice(characters) for _ in range(length))
        if not Registration.objects.filter(registration_code=code).exists():
            return code


class EventType(models.Model):
    """Model to define different types of events (Training, Seminar, Workshop, etc.)"""
    name = models.CharField(max_length=100, unique=True)
    description = models.TextField(blank=True, null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    def __str__(self):
        return self.name
    
    class Meta:
        verbose_name = "Event Type"
        verbose_name_plural = "Event Types"


class Event(models.Model):
    """Model to define events with details like name, type, dates, location, etc."""
    name = models.CharField(max_length=255)
    event_type = models.ForeignKey(EventType, on_delete=models.CASCADE, related_name='events')
    description = models.TextField()
    start_date = models.DateTimeField()
    end_date = models.DateTimeField()
    location = models.CharField(max_length=255)
    is_paid = models.BooleanField(default=False)
    amount = models.DecimalField(max_digits=10, decimal_places=2, validators=[MinValueValidator(0)], null=True, blank=True)
    is_active = models.BooleanField(default=True)
    is_archived = models.BooleanField(default=False, help_text="Archived events are hidden from feedback dashboard dropdown")
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    def __str__(self):
        return self.name
    
    def save(self, *args, **kwargs):
        # Ensure amount is set when is_paid is True
        if self.is_paid and not self.amount:
            self.amount = 0.00
        super().save(*args, **kwargs)
    
    class Meta:
        ordering = ['-start_date']


class Registration(models.Model):
    """Model to track user registrations for events"""
    STATUS_CHOICES = (
        ('pending', 'Pending'),
        ('approved', 'Approved'),
        ('rejected', 'Rejected'),
    )
    
    PAYMENT_STATUS_CHOICES = (
        ('not_required', 'Not Required'),
        ('pending', 'Pending'),
        ('approved', 'Approved'),
        ('rejected', 'Rejected'),
    )
    
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    registration_code = models.CharField(max_length=10, unique=True, default=generate_unique_code)
    full_name = models.CharField(max_length=255)
    email = models.EmailField()
    organisation = models.CharField(max_length=255, blank=True, default='', help_text="Organisation name")
    event = models.ForeignKey(Event, on_delete=models.CASCADE, related_name='registrations')
    status = models.CharField(max_length=50, choices=STATUS_CHOICES, default='pending')
    payment_status = models.CharField(max_length=50, choices=PAYMENT_STATUS_CHOICES, default='not_required')
    registered_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    has_attended = models.BooleanField(default=False)
    attendance_timestamp = models.DateTimeField(null=True, blank=True)
    
    def __str__(self):
        return f"{self.full_name} - {self.event.name} ({self.registration_code})"
    
    def save(self, *args, **kwargs):
        # Set payment status based on whether the event is paid or not
        if not self.pk:  # Only on creation
            if self.event.is_paid:
                self.payment_status = 'pending'
            else:
                self.payment_status = 'not_required'
                self.status = 'approved'  # Auto-approve if payment not required
        
        super().save(*args, **kwargs)
    
    class Meta:
        unique_together = ['email', 'event']
        ordering = ['-registered_at']


class PaymentProof(models.Model):
    """Model to store payment proof uploads"""
    registration = models.OneToOneField(Registration, on_delete=models.CASCADE, related_name='payment_proof')
    file = models.FileField(upload_to='payment_proofs/')
    uploaded_at = models.DateTimeField(auto_now_add=True)
    notes = models.TextField(blank=True, null=True)
    
    def __str__(self):
        return f"Payment proof for {self.registration}"
