from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
import os
from io import BytesIO
from PIL import Image
from django.core.exceptions import ValidationError
from django.core.files.base import ContentFile
from common.choices import SRI_LANKA_CITY_CHOICES, SRI_LANKA_DISTRICT_CHOICES, COUNTRY_CHOICES

def validate_dating_profile_image(image):
    ext = os.path.splitext(image.name)[1].lower()
    allowed_extensions = ['.jpg', '.jpeg', '.png', '.webp']
    if ext not in allowed_extensions:
        raise ValidationError("Only JPG, JPEG, PNG, or WEBP images are allowed.")


class DatingPartnerProfile(models.Model):
    GENDER_CHOICES = [
        ('male', 'Male'),
        ('female', 'Female'),
        ('other', 'Other'),
        ('prefer_not_to_say', 'Prefer not to say'),
    ]

    RELATIONSHIP_GOAL_CHOICES = [
        ('marriage', 'Marriage'),
        ('long_term', 'Long Term Relationship'),
        ('friendship_first', 'Friendship First'),
    ]

    STATUS_CHOICES = [
        ('pending', 'Pending Review'),
        ('approved', 'Approved'),
        ('rejected', 'Rejected'),
        ('inactive', 'Inactive'),
    ]

    user = models.OneToOneField(
        User,
        on_delete=models.CASCADE,
        related_name='dating_profile',
        null=True,
        blank=True
    )

    profile_code = models.CharField(max_length=20, unique=True, blank=True)

    full_name = models.CharField(max_length=200)
    display_name = models.CharField(max_length=100, blank=True)
    gender = models.CharField(max_length=20, choices=GENDER_CHOICES)
    date_of_birth = models.DateField()
    age = models.PositiveIntegerField(blank=True, null=True)

    city = models.CharField(
        max_length=120,
        choices=SRI_LANKA_CITY_CHOICES,
        blank=True
    )
    district = models.CharField(
        max_length=120,
        choices=SRI_LANKA_DISTRICT_CHOICES,
        blank=True
    )
    country = models.CharField(max_length=150, choices=COUNTRY_CHOICES, default='Sri Lanka')

    profile_photo = models.ImageField(
        upload_to='dating_profiles/',
        blank=True,
        null=True,
        validators=[validate_dating_profile_image]
    )
    short_intro = models.CharField(max_length=255)
    about_me = models.TextField()

    relationship_goal = models.CharField(max_length=30, choices=RELATIONSHIP_GOAL_CHOICES)
    marital_status = models.CharField(max_length=100, blank=True)
    religion = models.CharField(max_length=100, blank=True)
    profession = models.CharField(max_length=150, blank=True)

    languages_spoken = models.CharField(
        max_length=255,
        help_text="Example: English, Sinhala, Tamil, Italian"
    )

    education = models.CharField(max_length=255, blank=True)
    height = models.CharField(max_length=50, blank=True)
    hobbies = models.TextField(blank=True)
    expectations = models.TextField(blank=True)

    email = models.EmailField()
    phone_number = models.CharField(max_length=50, blank=True)
    whatsapp_number = models.CharField(max_length=50, blank=True)

    passport_ready = models.BooleanField(default=False)
    willing_to_relocate = models.BooleanField(default=False)
    willing_video_call = models.BooleanField(default=True)

    is_featured = models.BooleanField(default=False)
    is_public = models.BooleanField(default=False)
    is_confirmed = models.BooleanField(default=False)
    can_view_private_listings = models.BooleanField(default=False)
    can_book_arrangements = models.BooleanField(default=False)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')

    agreed_to_terms = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def save(self, *args, **kwargs):
        from datetime import date

        # Calculate age
        if self.date_of_birth:
            today = date.today()
            self.age = today.year - self.date_of_birth.year - (
                (today.month, today.day) < (self.date_of_birth.month, self.date_of_birth.day)
            )

        is_new = self.pk is None

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

        # Generate profile code AFTER first save (when ID exists)
        if is_new and not self.profile_code:
            self.profile_code = f"DTP{self.pk:05d}"
            super().save(update_fields=['profile_code'])

        # Compress image
        if self.profile_photo:
            self.compress_profile_photo()

    def compress_profile_photo(self):
        try:
            img = Image.open(self.profile_photo.path)

            if img.mode in ('RGBA', 'P'):
                img = img.convert('RGB')

            max_width = 600
            max_height = 600
            img.thumbnail((max_width, max_height))

            buffer = BytesIO()
            img.save(buffer, format='JPEG', quality=85, optimize=True)

            file_name = os.path.splitext(os.path.basename(self.profile_photo.name))[0] + '.jpg'
            self.profile_photo.save(
                file_name,
                ContentFile(buffer.getvalue()),
                save=False
            )

            super().save(update_fields=['profile_photo'])

        except Exception:
            pass

    def __str__(self):
        return f"{self.full_name} - {self.relationship_goal}"
    
class DatingPartnerPhoto(models.Model):
    STATUS_CHOICES = [
        ('pending', 'Pending Review'),
        ('approved', 'Approved'),
        ('rejected', 'Rejected'),
    ]

    profile = models.ForeignKey(
        DatingPartnerProfile,
        on_delete=models.CASCADE,
        related_name='additional_photos'
    )
    image = models.ImageField(
        upload_to='dating_profiles/gallery/',
        validators=[validate_dating_profile_image]
    )
    caption = models.CharField(max_length=150, blank=True)
    display_order = models.PositiveIntegerField(default=0)
    is_public = models.BooleanField(default=True)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
    uploaded_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['display_order', '-uploaded_at']

    def clean(self):
        if not self.profile_id:
            return

        if not self.pk and self.profile.additional_photos.count() >= 5:
            raise ValidationError("Maximum 5 additional photos are allowed.")

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)

        if self.image:
            self.compress_image()

    def compress_image(self):
        try:
            img = Image.open(self.image.path)

            if img.mode in ('RGBA', 'P'):
                img = img.convert('RGB')

            img.thumbnail((1000, 1000))

            buffer = BytesIO()
            img.save(buffer, format='JPEG', quality=85, optimize=True)

            file_name = os.path.splitext(os.path.basename(self.image.name))[0] + '.jpg'
            self.image.save(
                file_name,
                ContentFile(buffer.getvalue()),
                save=False
            )

            super().save(update_fields=['image'])

        except Exception:
            pass

    def __str__(self):
        return f"{self.profile.full_name} - Extra Photo {self.pk}"
    
class DatingInterest(models.Model):
    STATUS_CHOICES = [
        ('interested', 'Interested'),
        ('reviewing', 'Reviewing'),
        ('contacted', 'Contacted'),
        ('matched', 'Matched'),
        ('closed', 'Closed'),
        ('withdrawn', 'Withdrawn'),
    ]

    foreigner = models.ForeignKey(
        'expat_life.ForeignerProfile',
        on_delete=models.CASCADE,
        related_name='dating_interests'
    )
    partner = models.ForeignKey(
        'dating_app.DatingPartnerProfile',
        on_delete=models.CASCADE,
        related_name='dating_interests'
    )
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='interested')
    message = models.TextField(blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']
        verbose_name = 'Dating Interest'
        verbose_name_plural = 'Dating Interests'
        constraints = [
            models.UniqueConstraint(fields=['foreigner', 'partner'], name='unique_foreigner_dating_interest')
        ]

    def __str__(self):
        return f"{self.foreigner.user.username} -> {self.partner.display_name or self.partner.full_name}"
    
class DatingPartnerGuidanceResource(models.Model):
    LANGUAGE_CHOICES = [
        ('en', 'English'),
        ('si', 'Sinhala'),
        ('ta', 'Tamil'),
    ]

    language = models.CharField(
        max_length=2,
        choices=LANGUAGE_CHOICES,
        default='en',
        unique=True
    )

    title = models.CharField(
        max_length=200,
        default="Ensolanka Dating Partner Guidance Playbook"
    )

    full_playbook_pdf = models.FileField(
        upload_to='dating_guidance/playbooks/%Y/%m/',
        blank=True,
        null=True,
        help_text="Upload the full dating partner guidance playbook PDF."
    )

    summary_overview_pdf = models.FileField(
        upload_to='dating_guidance/summaries/%Y/%m/',
        blank=True,
        null=True,
        help_text="Upload the summary overview or quick guidance PDF."
    )

    audio_guide_file = models.FileField(
        upload_to='dating_guidance/audio/%Y/%m/',
        blank=True,
        null=True,
        help_text="Upload the audio guidance file, such as MP3."
    )

    youtube_video_link = models.URLField(
        blank=True,
        null=True,
        help_text="Optional YouTube or video guidance link."
    )

    description = models.TextField(
        blank=True,
        help_text="Brief description about this dating partner guidance resource."
    )

    is_active = models.BooleanField(default=True)

    created_at = models.DateTimeField(default=timezone.now)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['language']
        verbose_name = "Dating Partner Guidance Resource"
        verbose_name_plural = "Dating Partner Guidance Resources"

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