from django.db import models
from django.contrib.auth import get_user_model
from django.utils import timezone
from django.urls import reverse
from django.db.models import Q

class Currency(models.Model):
    slug = models.SlugField(null=True, unique=True)
    name = models.CharField(max_length=128, unique=True)
    short_name = models.CharField(max_length=3, unique=True)

    def __str__(self):
        return f"{self.name} ({self.short_name})"


class TimeFrame(models.Model):
    slug = models.SlugField(null=True, unique=True)
    name = models.CharField(max_length=128, unique=True)
    seconds = models.IntegerField(null=True, blank=True)

    @staticmethod
    def secs_to_name(secs):
        name = ""
        days = 0
        hours = 0

        if secs >= 24*3600:
            days = secs // (24*3600)
            secs -= (days*24*3600)

        if secs >= 3600:
            hours = secs // 3600
            secs -= hours*3600

        return f"{days} days {hours} hours {secs} seconds"

    def __str__(self):
        #return "{} ({})".format(self.name, self.secs_to_name(self.seconds))
        return f"{self.name}"

class PricePerTime(models.Model):
    timeframe = models.ForeignKey(TimeFrame, on_delete=models.CASCADE)
    price = models.FloatField()
    currency = models.ForeignKey(Currency, on_delete=models.CASCADE)

    def __str__(self):
        return f"{self.price} {self.currency.short_name}/{self.timeframe}"

class Resource(models.Model):
    slug = models.SlugField(null=True, unique=True)                 # primary identifier
    name = models.CharField(max_length=128, unique=False)           # CPU, RAM
    unit = models.CharField(max_length=128)                         # Count, GB
    minimum_units = models.FloatField(null=True, blank=True)        # might have min
    maximum_units = models.FloatField(null=True, blank=True)        # might have max
    step_size = models.FloatField(default=1) # might/must step size

    price_per_time = models.ManyToManyField(PricePerTime, blank=True)

    def __str__(self):
        if self.minimum_units:
            minimum = self.minimum_units
        else:
            minimum = "No minimum"
        if self.maximum_units:
            maximum = self.maximum_units
        else:
            maximum = "No maximum"

        pricing = []
        for price in self.price_per_time.all():
            pricing.append(f"{price.price}{price.currency.short_name}/{price.timeframe}")

        pricing = ", ".join(pricing)

        return f"{self.slug}: {minimum}-{maximum} (+/-){self.step_size} {self.unit} ({pricing})"

class ResourceOrder(models.Model):
    """
    Resources that have been ordered
    """
    timeframe = models.ForeignKey(TimeFrame, on_delete=models.CASCADE)
    value = models.FloatField()
    resource = models.ForeignKey(Resource, on_delete=models.CASCADE)


class Product(models.Model):
    """
    Describes a product a user can buy
    """

    slug = models.SlugField(null=True, unique=True)
    name = models.CharField(max_length=128, unique=True)

    resources = models.ManyToManyField(Resource, blank=True) # List of REQUIRED resources
    timeframes = models.ManyToManyField(TimeFrame, blank=True) # List of POSSIBLE timeframes

    def valid_timeframes(self):
        """
        Return all timeframes that have all resources configured
        """

        valid_tf = []

        num_res = self.resources.all().count()

        for tf in self.timeframes.all():
            # Get all distinct source for this timeframe
            res = self.resources.filter(price_per_time__timeframe=tf).distinct().count()

            if res == num_res:
                valid_tf.append(tf)

        return valid_tf

    def get_absolute_url(self):
        return reverse('product-detail', kwargs={'slug' : self.slug})

    def __str__(self):
        return self.name

class ProductOrder(models.Model):
    """
    Describes a product a user bought
    """
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    resources = models.ManyToManyField(ResourceOrder)


class Order(models.Model):
    owner = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, editable=False)

    creation_date = models.DateTimeField(auto_now_add=True)
    starting_date = models.DateTimeField(default=timezone.now)
    ending_date = models.DateTimeField(blank=True, null=True)

    product = models.ManyToManyField(ProductOrder, blank=True)

    #textconfigs = models.ManyToManyField(ResourceConfig)
