import os
from datetime import datetime

from django.db import models
from django.urls import reverse
from imagekit.models import ImageSpecField
from imagekit.processors import ResizeToFit

from gallery.exif import Exif
from gallery.models import Album


def get_upload_path(instance, filename):
    """Määrittää lopullisen tallennuspolun heti kuvan tallennusvaiheessa."""
    return os.path.join('albums', str(instance.album.slug), filename)


class Photo(models.Model):
    album = models.ForeignKey(Album, on_delete=models.CASCADE, related_name='photos', verbose_name="Album")
    slug = models.CharField(max_length=15, editable=False, verbose_name="Photo Slug")
    photo = models.ImageField(upload_to=get_upload_path, height_field='height', width_field='width', verbose_name="Photo")

    # Thumbnail-versiot
    photo_sm = ImageSpecField(source='photo', processors=[ResizeToFit(320, 320)], format='JPEG', options={'quality': 70})
    photo_md = ImageSpecField(source='photo', processors=[ResizeToFit(720, 720)], format='JPEG', options={'quality': 80})
    photo_bg = ImageSpecField(source='photo', processors=[ResizeToFit(1920, 1920)], format='JPEG', options={'quality': 90})

    width = models.PositiveIntegerField(default=0, editable=False, verbose_name="Photo Width")
    height = models.PositiveIntegerField(default=0, editable=False, verbose_name="Photo Height")
    taken_at = models.DateTimeField(blank=True, null=True, editable=False, verbose_name="Taken at")
    exif = models.JSONField(blank=True, null=True, editable=False, verbose_name="Exif Metadata")
    is_favorite = models.BooleanField(default=False, verbose_name="Is Favorite")
    views = models.PositiveIntegerField(default=0, verbose_name="Views")
    likes = models.PositiveIntegerField(default=0, verbose_name="Likes")

    @property
    def orientation(self):
        return "Portrait" if self.height > self.width else "Landscape"

    @staticmethod
    def generate_unique_slug(album, datetime_taken):
        """Luo yksilöllisen slug-arvon tiedostolle albumin sisällä."""
        slug = int(datetime_taken.strftime('%y%m%d%H%M%S'))
        while Photo.objects.filter(album=album, slug=str(slug)).exists():
            slug += 1
        return str(slug)

    def add_like(self):
        self.likes += 1
        self.save()

    def add_view(self):
        self.views += 1
        self.save()

    def get_next(self):
        return self.__class__.objects.filter(taken_at__gt=self.taken_at, album=self.album.id).order_by('taken_at').first()

    def get_prev(self):
        return self.__class__.objects.filter(taken_at__lt=self.taken_at, album=self.album.id).order_by('-taken_at').first()

    def extract_metadata(self):
        """Lukee Exif-metadatan ja asettaa tiedot ennen kuvan tallennusta."""
        if self.photo:
            try:
                exif_data = Exif(self.photo.file)  # Suoraan muistista, ei tiedostosta
                self.taken_at = getattr(exif_data, 'datetimeoriginal', datetime.now)()
                self.exif = getattr(exif_data, 'data', None)
            except Exception as e:
                print(f"Exif-tiedon lukeminen epäonnistui: {e}")
                self.taken_at = datetime.now()

    def save(self, *args, **kwargs):
        """Ennen tallennusta luetaan Exif ja asetetaan slug."""
        if not self.slug:
            self.extract_metadata()
            self.slug = self.generate_unique_slug(self.album, self.taken_at or datetime.now())

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

    def get_absolute_url(self):
        return reverse('gallery:photo_url', kwargs={'album_slug': self.album.slug, 'photo_slug': self.slug})

    class Meta:
        verbose_name_plural = "Photos"
        ordering = ('-taken_at',)

    def __str__(self):
        return f'{self.slug} ({self.orientation}) {self.is_favorite}'