from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.core.validators import FileExtensionValidator
from django.db.models import Max
from datetime import timedelta

class Membership(models.Model):
    # Constants for membership types and their prefixes
    FULL_MEMBER = 'full'
    ASSOCIATE_MEMBER = 'associate'
    STUDENT_MEMBER = 'student'
    HONORARY_MEMBER = 'honorary'

    MEMBERSHIP_TYPE = (
        (FULL_MEMBER, 'Full Member'),
        (ASSOCIATE_MEMBER, 'Associate Member'),
        (STUDENT_MEMBER, 'Student Member'),
        (HONORARY_MEMBER, 'Honorary Member'),
    )

    # Mapping of membership types to their prefixes
    MEMBERSHIP_PREFIXES = {
        FULL_MEMBER: 'FM',
        ASSOCIATE_MEMBER: 'AS',
        STUDENT_MEMBER: 'ST',
        HONORARY_MEMBER: 'HO',
    }

    QUALIFICATION_CHOICES = [
        ('certificate', 'Certificate'),
        ('diploma', 'Diploma'),
        ('bachelors', "Bachelor's Degree"),
        ('masters', "Master's Degree"),
        ('doctorate', 'Doctorate/PhD'),
        ('other', 'Other'),
    ]

    STATUS_CHOICES = [
        ('pending', 'Pending'),
        ('approved', 'Approved'),
        ('rejected', 'Rejected'),
        ('expired', 'Expired'),
    ]

    # User Information
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
    membership_number = models.CharField(max_length=8, unique=True, null=True, blank=True, help_text=_('Unique membership number'))
    base_number = models.IntegerField(null=True, blank=True, help_text=_('Base number without prefix'))
    membership_type = models.CharField(max_length=20, choices=MEMBERSHIP_TYPE, null=True, blank=True)
    membership_status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
    rejection_reason = models.TextField(blank=True, null=True, help_text=_('Reason for rejecting the membership application'))
    membership_fee = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
    membership_valid_until = models.DateField(null=True, blank=True)
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    email = models.EmailField(unique=True)
    phone_number = models.CharField(max_length=20, blank=True)
    date_of_birth = models.DateField()
    nationality = models.CharField(max_length=100, blank=True)
    nrc_number = models.CharField(
        _('NRC/Passport Number'),
        max_length=50,
        unique=True,
        help_text=_('Enter your NRC number or Passport number'),
        null=True,
        blank=True
    )
    nrc_file = models.FileField(
        _('Copy of NRC/Passport'),
        upload_to='nrc_files/',
        validators=[FileExtensionValidator(allowed_extensions=['pdf', 'jpg', 'jpeg', 'png'])],
        help_text=_('Upload a copy of your NRC or Passport'),
        null=True,
        blank=True
    )
    residential_address = models.TextField(blank=True)
    postal_address = models.TextField(blank=True)

    # Professional Information
    occupation = models.CharField(max_length=100, blank=True, help_text="Your current job title or role")
    employer = models.CharField(max_length=200, blank=True, help_text="Name of your current employer or organization")
    highest_qualification = models.CharField(max_length=20, choices=QUALIFICATION_CHOICES, blank=True)
    field_of_study = models.CharField(max_length=100, blank=True)
    institution = models.CharField(max_length=200, blank=True)
    graduation_year = models.IntegerField(null=True, blank=True)

    # Documents
    profile_picture = models.ImageField(
        upload_to='membership/profile_pictures/',
        validators=[FileExtensionValidator(allowed_extensions=['jpg', 'jpeg', 'png'])],
        null=True,
        blank=True
    )
    cv = models.FileField(
        upload_to='membership/cvs/',
        validators=[FileExtensionValidator(allowed_extensions=['pdf', 'doc', 'docx'])],
        null=True,
        blank=True
    )
    degree_certificate = models.FileField(
        upload_to='membership/certificates/',
        validators=[FileExtensionValidator(allowed_extensions=['pdf', 'jpg', 'jpeg', 'png'])],
        null=True,
        blank=True
    )
    transcript = models.FileField(
        upload_to='membership/transcripts/',
        validators=[FileExtensionValidator(allowed_extensions=['pdf'])],
        null=True,
        blank=True
    )

    # Payment
    payment_proof = models.FileField(
        upload_to='membership/payment_proofs/',
        validators=[FileExtensionValidator(allowed_extensions=['pdf', 'jpg', 'jpeg', 'png'])],
        null=True,
        blank=True
    )
    payment_verified = models.BooleanField(default=False)
    payment_verified_at = models.DateTimeField(null=True, blank=True)
    payment_verified_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='verified_payments')

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=['email', 'nrc_number'],
                condition=models.Q(membership_status='pending') | models.Q(membership_status='approved'),
                name='unique_active_membership'
            )
        ]

    def save(self, *args, **kwargs):
        # Set membership fee based on type
        if self.membership_type == 'full':
            self.membership_fee = 600
        elif self.membership_type == 'associate':
            self.membership_fee = 300
        elif self.membership_type in ['student', 'honorary']:
            self.membership_fee = 200

        # Generate or update membership number when payment is verified and status is approved
        if self.membership_status == 'approved' and self.payment_verified:
            if not self.base_number:
                last_number = Membership.objects.aggregate(Max('base_number'))['base_number__max'] or 0
                self.base_number = last_number + 1
            self.membership_number = f"{self.MEMBERSHIP_PREFIXES[self.membership_type]}{str(self.base_number).zfill(6)}"

            # Set membership validity period
            if not self.membership_valid_until:
                self.membership_valid_until = timezone.now().date() + timedelta(days=365)

        super().save(*args, **kwargs)

    def is_active(self):
        if not (self.membership_status == 'approved' and self.payment_verified):
            return False
        
        # Check if membership has expired
        if self.membership_valid_until and self.membership_valid_until < timezone.now().date():
            self.membership_status = 'expired'
            self.payment_verified = False
            self.save(update_fields=['membership_status', 'payment_verified'])
            return False
            
        return True

    def __str__(self):
        return f"{self.first_name} {self.last_name} - {self.get_membership_type_display() or 'No Type'}"

    @property
    def status_display(self):
        """Return a user-friendly status message based on membership state."""
        if self.membership_status == 'approved' and self.is_active:
            return f"Active Member\nValid until: {self.membership_valid_until.strftime('%d %B %Y')}"
        elif self.membership_status == 'expired':
            return "Membership Expired"
        elif self.membership_status == 'pending':
            if not self.payment_proof:
                return "Payment Required"
            else:
                return "Payment Under Review"
        elif self.membership_status == 'rejected':
            return f"Application Rejected: {self.rejection_reason}"
        return "Unknown Status"