import os
from PIL import Image
import io
from django.db import models, transaction
from django.conf import settings
from django.utils import timezone
from django.core.files.base import ContentFile
from django.core.exceptions import ValidationError

# --- FUNKCIJE ZA DINAMIČKE PUTANJE ---

def putanja_slike_naloga(instance, filename):
    # Kreira putanju: radni-nalozi/broj_naloga/originalni_naziv.ekstenzija
    return f'radni-nalozi/{instance.broj_naloga}/{filename}'

def putanja_galerije_naloga(instance, filename):
    # instance je objekt RadniNalogSlika koji ima ForeignKey na radni_nalog
    # Sprema u isti folder gdje je i glavna slika kvara
    return f'radni-nalozi/{instance.radni_nalog.broj_naloga}/galerija/{filename}'


class PutniNalog(models.Model):
    class StatusChoices(models.TextChoices):
        OTVOREN = 'OTVOREN', 'Otvoren'
        ZAVRSEN = 'ZAVRSEN', 'Završen'

    broj_naloga = models.CharField(max_length=50, unique=True)
    datum_izdavanja = models.DateField(default=timezone.now)
    
    vozilo = models.ForeignKey(
        'fleet.Vozilo', 
        on_delete=models.PROTECT,
        related_name='putni_nalozi',
        verbose_name="Službeno vozilo"
    )
    
    korisnik = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT)
    relacija = models.CharField(max_length=255)
    mjesto_odredista = models.CharField(max_length=255)

    pocetna_km = models.PositiveIntegerField(
        editable=False, 
        help_text="Automatski preuzeto iz modela Vozilo"
    )
    zavrsna_km = models.PositiveIntegerField(null=True, blank=True)
    
    vrijeme_polaska = models.DateTimeField(default=timezone.now)
    vrijeme_povratka = models.DateTimeField(null=True, blank=True)
    
    status = models.CharField(
        max_length=15, 
        choices=StatusChoices.choices, 
        default=StatusChoices.OTVOREN
    )

    class Meta:
        verbose_name = "Putni nalog"
        verbose_name_plural = "Putni nalozi"

    def clean(self):
        super().clean()
        if self.status == self.StatusChoices.ZAVRSEN:
            if self.zavrsna_km is None:
                raise ValidationError({'zavrsna_km': "Morate unijeti završne kilometre prije zatvaranja naloga."})
            
            otvoreni_radni_nalozi = self.radni_nalozi.exclude(status='ZAVRSENO').exists()
            if otvoreni_radni_nalozi:
                raise ValidationError({
                    'status': "Putni nalog ne može biti završen jer postoje povezani radni nalozi koji još nisu zatvoreni."
                })

    def save(self, *args, **kwargs):
        if not self.pk:
            self.pocetna_km = self.vozilo.trenutni_kilometri
        
        self.full_clean()
        
        if self.status == self.StatusChoices.ZAVRSEN and self.zavrsna_km:
            with transaction.atomic():
                super().save(*args, **kwargs)
                v = self.vozilo
                v.trenutni_kilometri = self.zavrsna_km
                v.pocetni_kilometri = self.zavrsna_km
                v.save()
        else:
            super().save(*args, **kwargs)

    def __str__(self):
        return f"{self.broj_naloga} - {self.vozilo.registracija}"


class RadniNalog(models.Model):
    class StatusRadaChoices(models.TextChoices):
        PLANIRANO = 'PLANIRANO', 'Planirano'
        U_RADU = 'U_RADU', 'U radu'
        ZAVRSENO = 'ZAVRSENO', 'Završeno'

    broj_naloga = models.CharField(max_length=20, unique=True, blank=True)
    
    stroj = models.ForeignKey(
        'fleet.Stroj', 
        on_delete=models.CASCADE, 
        related_name='radni_nalozi',
        verbose_name="Stroj na popravku"
    )

    putni_nalog = models.ForeignKey(
        'PutniNalog', 
        on_delete=models.SET_NULL, 
        null=True, blank=True, 
        related_name='radni_nalozi'
    )
    
    klijent = models.ForeignKey(
        'kupci.Kupac', 
        on_delete=models.PROTECT, 
        related_name='radni_nalozi'
    )

    opis_kvara = models.TextField()
    izvrsitelj = models.ForeignKey(
        settings.AUTH_USER_MODEL, 
        on_delete=models.SET_NULL, 
        null=True, blank=True,
        related_name='dodijeljeni_nalozi'
    )
    
    status = models.CharField(
        max_length=20, 
        choices=StatusRadaChoices.choices, 
        default=StatusRadaChoices.PLANIRANO
    )
    
    datum_kreiranja = models.DateTimeField(auto_now_add=True, verbose_name="Datum kreiranja")
    datum_azuriranja = models.DateTimeField(auto_now=True, verbose_name="Zadnja izmjena")
    slika_kvara = models.ImageField(upload_to=putanja_slike_naloga, null=True, blank=True)
    potpis_klijenta = models.ImageField(upload_to='potpisi/%Y/%m/', null=True, blank=True)

    def save(self, *args, **kwargs):
        # 1. AUTOMATSKO GENERIRANJE BROJA NALOGA
        if not self.broj_naloga:
            godina = timezone.now().year
            prefix = f"RN-{godina}-"

            # Koristimo atomsku transakciju i select_for_update da spriječimo 
            # da dva korisnika dobiju isti broj u istoj milisekundi
            with transaction.atomic():
                zadnji_nalog = RadniNalog.objects.select_for_update().filter(
                    broj_naloga__startswith=prefix
                ).order_by('-broj_naloga').first()

                if zadnji_nalog:
                    try:
                        # RN-2026-0001 -> uzimamo "0001"
                        zadnji_broj_str = zadnji_nalog.broj_naloga.split('-')[-1]
                        novi_broj = int(zadnji_broj_str) + 1
                    except (ValueError, IndexError):
                        novi_broj = 1
                else:
                    novi_broj = 1

                self.broj_naloga = f"{prefix}{novi_broj:04d}"

        # 2. OBRADA SLIKE
        if self.slika_kvara:
            try:
                self.slika_kvara = self.rescale_image(self.slika_kvara)
            except Exception as e:
                print(f"Greška pri obradi slike: {e}")
        
        # 3. PRIMARNO SPREMANJE
        super().save(*args, **kwargs)

        # 4. LOGIKA ZA PUTNI NALOG
        if self.putni_nalog and self.status == self.StatusRadaChoices.ZAVRSENO:
            pn = self.putni_nalog
            # Provjeravamo ima li nalog još uvijek otvorenih radnih naloga
            ostali_otvoreni = pn.radni_nalozi.exclude(
                id=self.id, # Isključujemo trenutni nalog jer je on upravo završen
                status=self.StatusRadaChoices.ZAVRSENO
            ).exists()
            
            if not ostali_otvoreni and pn.zavrsna_km:
                pn.status = 'ZAVRSEN' 
                pn.save()

    def rescale_image(self, image_field):
        img = Image.open(image_field)
        if img.height > 1200 or img.width > 1200:
            output_size = (1200, 1200)
            img.thumbnail(output_size)
            img_io = io.BytesIO()
            img_format = img.format if img.format else 'JPEG'
            img.save(img_io, format=img_format, quality=90)
            return ContentFile(img_io.getvalue(), name=image_field.name)
        return image_field

    class Meta:
        verbose_name = "Radni nalog"
        verbose_name_plural = "Radni nalozi"

    def __str__(self):
        return f"RN-{self.broj_naloga} | {self.stroj.naziv}"

class RadniNalogSlika(models.Model):
    radni_nalog = models.ForeignKey(
        RadniNalog, 
        related_name='slike', 
        on_delete=models.CASCADE
    )
    # POPRAVLJENO: uklonjeni navodnici oko funkcije
    slika = models.ImageField(upload_to=putanja_galerije_naloga, verbose_name="Slika")
    opis = models.CharField(max_length=100, blank=True, verbose_name="Kratki opis slike")

    class Meta:
        verbose_name = "Dodatna slika naloga"
        verbose_name_plural = "Dodatne slike naloga"

    def __str__(self):
        return f"Slika za nalog {self.radni_nalog.broj_naloga}"