from django.db import models
from django.utils.translation import gettext_lazy as _
from django.utils.text import slugify
from django.core.validators import MinValueValidator, MaxValueValidator


class Governorate(models.Model):
    """Governorate Model"""
    name = models.CharField(max_length=100, verbose_name=_('Name'))
    name_ar = models.CharField(max_length=100, verbose_name=_('Name (Arabic)'))
    name_ku = models.CharField(max_length=100, verbose_name=_('Name (Kurdish)'))
    name_en = models.CharField(max_length=100, verbose_name=_('Name (English)'))
    code = models.CharField(max_length=10, unique=True, verbose_name=_('Code'))

    class Meta:
        verbose_name = _('Governorate')
        verbose_name_plural = _('Governorates')
        ordering = ['name_ar']

    def __str__(self):
        return self.name_ar


class Category(models.Model):
    """Category Model"""
    name = models.CharField(max_length=100, verbose_name=_('Name'))
    name_ar = models.CharField(max_length=100, verbose_name=_('Name (Arabic)'))
    name_ku = models.CharField(max_length=100, verbose_name=_('Name (Kurdish)'))
    name_en = models.CharField(max_length=100, verbose_name=_('Name (English)'))
    slug = models.SlugField(unique=True, verbose_name=_('Slug'))
    icon = models.CharField(max_length=50, blank=True, null=True, verbose_name=_('Icon'))
    image = models.ImageField(upload_to='categories/', blank=True, null=True, verbose_name=_('Image'))
    is_active = models.BooleanField(default=True, verbose_name=_('Is Active'))

    class Meta:
        verbose_name = _('Category')
        verbose_name_plural = _('Categories')
        ordering = ['name_ar']

    def __str__(self):
        return self.name_ar

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name_ar)
        super().save(*args, **kwargs)


class Amenity(models.Model):
    """Amenity Model"""
    name = models.CharField(max_length=100, unique=True, verbose_name=_('Name'))
    name_ar = models.CharField(max_length=100, verbose_name=_('Name (Arabic)'))
    name_ku = models.CharField(max_length=100, blank=True, null=True, verbose_name=_('Name (Kurdish)'))
    name_en = models.CharField(max_length=100, blank=True, null=True, verbose_name=_('Name (English)'))
    icon = models.CharField(max_length=50, blank=True, null=True, verbose_name=_('Icon'))

    class Meta:
        verbose_name = _('Amenity')
        verbose_name_plural = _('Amenities')
        ordering = ['name_ar']

    def __str__(self):
        return self.name_ar


class Place(models.Model):
    """Place Model"""
    name = models.CharField(max_length=200, verbose_name=_('Name'))
    slug = models.SlugField(unique=True, verbose_name=_('Slug'))
    category = models.ForeignKey(
        Category,
        on_delete=models.PROTECT,
        related_name='places',
        verbose_name=_('Category')
    )
    governorate = models.ForeignKey(
        Governorate,
        on_delete=models.PROTECT,
        related_name='places',
        verbose_name=_('Governorate')
    )
    owner = models.ForeignKey(
        'accounts.User',
        on_delete=models.PROTECT,
        related_name='owned_places',
        verbose_name=_('Owner')
    )
    description = models.TextField(blank=True, null=True, verbose_name=_('Description'))
    address = models.CharField(max_length=500, verbose_name=_('Address'))
    latitude = models.DecimalField(
        max_digits=9,
        decimal_places=6,
        verbose_name=_('Latitude')
    )
    longitude = models.DecimalField(
        max_digits=9,
        decimal_places=6,
        verbose_name=_('Longitude')
    )
    phone = models.CharField(max_length=20, blank=True, null=True, verbose_name=_('Phone'))
    website = models.URLField(blank=True, null=True, verbose_name=_('Website'))
    email = models.EmailField(blank=True, null=True, verbose_name=_('Email'))
    image = models.ImageField(upload_to='places/', verbose_name=_('Image'))
    gallery = models.JSONField(default=list, blank=True, verbose_name=_('Gallery'))
    working_hours = models.JSONField(default=dict, blank=True, verbose_name=_('Working Hours'))
    amenities = models.ManyToManyField(Amenity, blank=True, verbose_name=_('Amenities'))
    price_range = models.CharField(
        max_length=10,
        blank=True,
        null=True,
        choices=[('$', '$'), ('$$', '$$'), ('$$$', '$$$'), ('$$$$', '$$$$')],
        verbose_name=_('Price Range')
    )
    is_open = models.BooleanField(default=True, verbose_name=_('Is Open'))
    has_booking = models.BooleanField(default=False, verbose_name=_('Has Booking'))
    rating = models.DecimalField(
        max_digits=3,
        decimal_places=2,
        default=0.0,
        validators=[MinValueValidator(0.0), MaxValueValidator(5.0)],
        verbose_name=_('Rating')
    )
    reviews_count = models.IntegerField(default=0, verbose_name=_('Reviews Count'))
    is_verified = models.BooleanField(default=False, verbose_name=_('Is Verified'))
    is_active = models.BooleanField(default=True, verbose_name=_('Is Active'))
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = _('Place')
        verbose_name_plural = _('Places')
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['latitude', 'longitude']),
            models.Index(fields=['category']),
            models.Index(fields=['governorate']),
            models.Index(fields=['is_active', 'is_verified']),
        ]

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        super().save(*args, **kwargs)

    def update_rating(self):
        """Update rating and reviews count from reviews"""
        from reviews.models import Review
        reviews = Review.objects.filter(place=self, is_active=True)
        if reviews.exists():
            self.rating = reviews.aggregate(
                avg_rating=models.Avg('rating')
            )['avg_rating'] or 0.0
            self.reviews_count = reviews.count()
        else:
            self.rating = 0.0
            self.reviews_count = 0
        self.save(update_fields=['rating', 'reviews_count'])
