from django.conf import settings
from django.db import models
from django.utils import timezone
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


def validate_image_file(image):
    allowed_extensions = ['.jpg', '.jpeg', '.png', '.webp']
    ext = os.path.splitext(image.name)[1].lower()

    if ext not in allowed_extensions:
        raise ValidationError("Only JPG, JPEG, PNG, and WEBP images are allowed.")

    max_size_mb = 5
    if image.size > max_size_mb * 1024 * 1024:
        raise ValidationError(f"Image file too large. Maximum allowed size is {max_size_mb} MB.")


def rental_owner_profile_image_upload_path(instance, filename):
    ext = os.path.splitext(filename)[1].lower() or '.jpg'
    owner_id = instance.id or 'new'
    return f'rental_owner_profiles/owner_{owner_id}{ext}'


def rental_listing_image_upload_path(instance, filename):
    ext = os.path.splitext(filename)[1].lower() or '.jpg'
    listing_slug = instance.listing.slug if instance.listing_id else 'listing'
    image_id = instance.id or 'new'
    return f'rental_listings/{listing_slug}/image_{image_id}{ext}'


class RentalOwner(models.Model):
    OWNER_TYPE_CHOICES = [
        ('individual', 'Individual'),
        ('agency', 'Agency'),
        ('company', 'Company'),
    ]

    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='rental_owner_profile'
    )
    owner_type = models.CharField(max_length=20, choices=OWNER_TYPE_CHOICES, default='individual')
    full_name = models.CharField(max_length=150)
    email = models.EmailField()
    whatsapp_number = models.CharField(max_length=50, blank=True)
    phone_number = models.CharField(max_length=50, blank=True)
    city = models.CharField(
        max_length=120,
        choices=SRI_LANKA_CITY_CHOICES,
        blank=True
    )
    address = models.TextField(blank=True)
    business_name = models.CharField(max_length=150, blank=True)
    
    profile_image = models.ImageField(
        upload_to=rental_owner_profile_image_upload_path,
        blank=True,
        null=True,
        validators=[validate_image_file]
    )

    is_identity_verified = models.BooleanField(default=False)
    is_approved = models.BooleanField(default=True)
    is_featured = models.BooleanField(default=False)
    can_submit_listings = models.BooleanField(default=True)

    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']
        verbose_name = 'Rental Owner'
        verbose_name_plural = 'Rental Owners'

    def __str__(self):
        return self.full_name

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

        if self.profile_image:
            self.compress_profile_image()

    def compress_profile_image(self):
        try:
            img = Image.open(self.profile_image.path)

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

            max_width = 800
            max_height = 800
            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_image.name))[0] + '.jpg'
            self.profile_image.save(
                file_name,
                ContentFile(buffer.getvalue()),
                save=False
            )

            super().save(update_fields=['profile_image'])
        except Exception:
            pass


class RentalListing(models.Model):
    PROPERTY_TYPE_CHOICES = [
        ('room', 'Room'),
        ('annex', 'Annex'),
        ('apartment', 'Apartment'),
        ('house', 'House'),
        ('villa', 'Villa'),
        ('guesthouse', 'Guesthouse'),
        ('other', 'Other'),
    ]

    LISTING_VISIBILITY_CHOICES = [
        ('public', 'Public'),
        ('private', 'Private for Confirmed Foreigners'),
    ]

    FURNISHING_CHOICES = [
        ('fully_furnished', 'Fully Furnished'),
        ('semi_furnished', 'Semi Furnished'),
        ('unfurnished', 'Unfurnished'),
    ]

    owner = models.ForeignKey(
        RentalOwner,
        on_delete=models.CASCADE,
        related_name='listings'
    )
    title = models.CharField(max_length=200)
    slug = models.SlugField(unique=True)
    property_type = models.CharField(max_length=30, choices=PROPERTY_TYPE_CHOICES)
    visibility = models.CharField(max_length=20, choices=LISTING_VISIBILITY_CHOICES, default='public')

    city = models.CharField(
        max_length=120,
        choices=SRI_LANKA_CITY_CHOICES,
        blank=True
    )
    area = models.CharField(
        max_length=120,
        choices=SRI_LANKA_DISTRICT_CHOICES,
        blank=True
    )
    address = models.TextField(blank=True)

    monthly_rent_usd = models.DecimalField(max_digits=10, decimal_places=2)
    security_deposit_usd = models.DecimalField(max_digits=10, decimal_places=2, default=0.00)

    bedrooms = models.PositiveIntegerField(default=1)
    bathrooms = models.PositiveIntegerField(default=1)
    max_occupants = models.PositiveIntegerField(default=1)
    furnishing = models.CharField(max_length=30, choices=FURNISHING_CHOICES, default='fully_furnished')

    has_wifi = models.BooleanField(default=False)
    has_ac = models.BooleanField(default=False)
    has_kitchen = models.BooleanField(default=False)
    has_parking = models.BooleanField(default=False)
    near_beach = models.BooleanField(default=False)
    suitable_for_remote_work = models.BooleanField(default=False)

    short_description = models.CharField(max_length=255)
    full_description = models.TextField()
    house_rules = models.TextField(blank=True)

    available_from = models.DateField(null=True, blank=True)
    is_available = models.BooleanField(default=True)

    is_approved = models.BooleanField(default=False)
    is_featured = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)

    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-is_featured', '-created_at']
        verbose_name = 'Rental Listing'
        verbose_name_plural = 'Rental Listings'

    def __str__(self):
        return self.title


class RentalListingImage(models.Model):
    listing = models.ForeignKey(
        RentalListing,
        on_delete=models.CASCADE,
        related_name='images'
    )
    image = models.ImageField(
        upload_to=rental_listing_image_upload_path,
        validators=[validate_image_file]
    )
    caption = models.CharField(max_length=150, blank=True)
    order = models.PositiveIntegerField(default=0)

    class Meta:
        ordering = ['order', 'id']

    def __str__(self):
        return f"{self.listing.title} Image"

    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')

            max_width = 1600
            max_height = 1600
            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.image.name))[0] + '.jpg'
            self.image.save(
                file_name,
                ContentFile(buffer.getvalue()),
                save=False
            )

            super().save(update_fields=['image'])
        except Exception:
            pass


class RentalInquiry(models.Model):
    listing = models.ForeignKey(
        RentalListing,
        on_delete=models.CASCADE,
        related_name='inquiries'
    )
    foreigner_profile = models.ForeignKey(
        'expat_life.ForeignerProfile',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='rental_inquiries'
    )
    full_name = models.CharField(max_length=150)
    email = models.EmailField()
    whatsapp_number = models.CharField(max_length=50, blank=True)
    message = models.TextField(blank=True)

    is_reviewed = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']
        verbose_name = 'Rental Inquiry'
        verbose_name_plural = 'Rental Inquiries'

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

class RentalInterest(models.Model):
    STATUS_CHOICES = [
        ('interested', 'Interested'),
        ('reviewing', 'Reviewing'),
        ('contacted', 'Contacted'),
        ('negotiating', 'Negotiating'),
        ('selected', 'Selected as Final Property'),
        ('closed', 'Closed'),
    ]

    foreigner = models.ForeignKey(
        'expat_life.ForeignerProfile',
        on_delete=models.CASCADE,
        related_name='rental_interests'
    )
    listing = models.ForeignKey(
        'rental_app.RentalListing',
        on_delete=models.CASCADE,
        related_name='rental_interests'
    )
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='interested')
    notes = models.TextField(blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']
        unique_together = ('foreigner', 'listing')
        verbose_name = 'Rental Interest'
        verbose_name_plural = 'Rental Interests'

    def __str__(self):
        return f"{self.foreigner.user.username} -> {self.listing.title}"
    
class RentalOwnerBankingDetails(models.Model):
    owner = models.OneToOneField(
        RentalOwner,
        on_delete=models.CASCADE,
        related_name='banking_details'
    )

    account_holder_name = models.CharField(max_length=200)
    bank_name = models.CharField(max_length=200)
    branch_name = models.CharField(max_length=200, blank=True)

    account_number = models.CharField(max_length=100)
    iban = models.CharField(max_length=100, blank=True)
    swift_code = models.CharField(max_length=50, blank=True)

    bank_country = models.CharField(max_length=120, blank=True)
    bank_address = models.TextField(blank=True)

    payment_notes = models.TextField(
        blank=True,
        help_text="Optional notes for transfers, preferred payout instructions, or additional details."
    )

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

    class Meta:
        verbose_name = 'Rental Owner Banking Details'
        verbose_name_plural = 'Rental Owner Banking Details'

    def __str__(self):
        return f"{self.owner.full_name} - {self.bank_name}"
    
class RentalPartnerGuidanceResource(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 Rental Property Partner Guidance Playbook"
    )

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

    summary_overview_pdf = models.FileField(
        upload_to='rental_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='rental_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 rental property 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 = "Rental Property Partner Guidance Resource"
        verbose_name_plural = "Rental Property Partner Guidance Resources"

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