from django.contrib.gis.db import models
from django.contrib.auth.models import User
import uuid


class Farm(models.Model):
    """model representing a farm entity"""
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=255)
    description = models.TextField(blank=True,null=True)
    boundary = models.MultiPolygonField(geography=True)
    area_hectares = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
    address = models.TextField(blank=True, null=True)
    owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='farms')
    elevation = models.FloatField(blank=True,null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    def __str__(self):
        return self.name
    
    def save(self, *args, **kwargs):
        #calculate area in square meters and convert to hectares
        if self.boundary:
            self.area_hectares = self.boundary.area / 10000
        super().save(*args, **kwargs)
        

class ZoneType(models.Model):
    """model representing different types of zones"""
    name = models.CharField(max_length=100)
    description = models.TextField(blank=True, null=True)
    
    def __str__(self):
        return self.name
    

class Zone(models.Model):
    """model representing a specific zone within a farm"""
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=255)
    farm = models.ForeignKey(Farm, on_delete=models.CASCADE, related_name='zones')
    zone_type = models.ForeignKey(ZoneType, on_delete=models.CASCADE, related_name='zones')
    boundary = models.PolygonField(geography=True)
    area_hectares = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
    description = models.TextField(blank=True,null=True)
    active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    def __str__(self):
        return f"{self.name} - {self.farm.name}"
    
    def save(self, *args, **kwargs):
        #calculate area in square meters and convert to hectares
        if self.boundary:
            self.area_hectares = self.boundary.area / 10000
        super().save(*args, **kwargs)
        

class SoilType(models.Model):
    """model representing soil type information"""
    name = models.CharField(max_length=100)
    description = models.TextField(blank=True, null=True)
    texture = models.CharField(max_length=100, blank=True, null=True)
    ph_min = models.FloatField(blank=True, null=True)
    ph_max = models.FloatField(blank=True, null=True)
    organic_matter_percentage = models.FloatField(blank=True, null=True)
    drainage_rate = models.CharField(max_length=50,blank=True, null=True)
    water_holding_capacity = models.FloatField(blank=True,null=True)
    
    def __str__(self):
        return self.name
    

class SoilData(models.Model):
    """model representing soil data for a specific zone"""
    zone = models.ForeignKey(Zone,on_delete=models.CASCADE, related_name='soil_data')
    soil_type = models.ForeignKey(SoilType,on_delete=models.CASCADE)
    ph_value = models.FloatField(blank=True, null=True)
    organic_matter = models.FloatField(blank=True, null=True)
    nitrogen = models.FloatField(blank=True, null=True)
    phosphorus = models.FloatField(blank=True, null=True)
    potassium = models.FloatField(blank=True, null=True)
    sand_percentage = models.FloatField(blank=True, null=True)
    silt_percentage = models.FloatField(blank=True, null=True)
    clay_percentage = models.FloatField(blank=True, null=True)
    cec = models.FloatField(blank=True, null=True)
    ec = models.FloatField(blank=True, null=True)
    data_source = models.CharField(max_length=255, blank=True, null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    def __str__(self):
        return f"soil data for {self.zone.name}"
    

class WeatherData(models.Model):
    """model for storing weather data for a farm"""
    farm = models.ForeignKey(Farm, on_delete=models.CASCADE,related_name='weather_data')
    date = models.DateField()
    temperature_min = models.FloatField(blank=True, null=True)
    temperature_max = models.FloatField(blank=True, null=True)
    temperature_avg = models.FloatField(blank=True, null=True)
    humidity = models.FloatField(blank=True, null=True)
    precipitation = models.FloatField(blank=True, null=True)
    wind_speed = models.FloatField(blank=True, null=True)
    wind_direction = models.CharField(max_length=50, blank=True, null=True)
    cloud_cover = models.FloatField(blank=True, null=True)
    solar_radiation = models.FloatField(blank=True, null=True)
    evapotranspiration = models.FloatField(blank=True, null=True)
    data_source = models.CharField(max_length=255, blank=True, null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    class Meta:
        unique_together = ('farm', 'date') 
    
    def __str__(self):
        return f"weather data for {self.farm.name} on {self.date}"
    

class SatelliteImage(models.Model):
    """model for storing satellite imagery data"""
    farm = models.ForeignKey(Farm, on_delete=models.CASCADE, related_name='satellite_images')
    image_url = models.URLField()
    image_date = models.URLField()
    satellite_name = models.CharField(max_length=100)
    cloud_cover_percentage = models.FloatField(blank=True, null=True)
    resolution = models.CharField(max_length=50, blank=True, null=True)
    bands = models.CharField(max_length=255, blank=True, null=True)
    ndvi_avg = models.FloatField(blank=True, null=True) 
    evi_avg = models.FloatField(blank=True,null=True)
    data_source = models.CharField(max_length=255, blank=True, null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    def __str__(self):
        return f"satellite image for {self.farm.name} on {self.image_date}"
    
    
class ThirdPartyAPIKey(models.Model):
    """model for storing API keys for third-party services."""
    service_name = models.CharField(max_length=100)
    api_key = models.CharField(max_length=255)
    api_url = models.URLField(blank=True, null=True)
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at =models.DateTimeField(auto_now=True)
    
    def __str__(self):
        return f"{self.service_name} API key"