from django.db import models
from django.db import IntegrityError
from django.core.exceptions import ValidationError
from django.urls import reverse

class PriceLevel(models.Model):
    Name = models.CharField(max_length=50)
    Desc = models.CharField(max_length=180, verbose_name="Description", blank=True, null=True)
    TimeCreated = models.DateTimeField(auto_now_add=True)
    TimeModified = models.DateTimeField(auto_now=True)

    def __str__(self):
        return f"{self.pk}; {self.Name}"
    
    def get_field_name(obj):
        # return [(f.name, f.value_to_string(obj)) for f in obj._meta.fields]   #get value convert it to string
        return [(f.verbose_name, f.name, f.value_from_object(obj)) for f in obj._meta.fields]
    
    def get_absolute_url(self):
        return reverse('Item:edit_pricelevel', args=[str(self.id)])

class PriceLevelItem(models.Model):
    PL = models.ForeignKey("PriceLevel", related_name="pricelevel", on_delete=models.CASCADE)
    IPL = models.ForeignKey("Item", related_name="itempricelevel", on_delete=models.CASCADE)
    Price = models.DecimalField(max_digits=12, decimal_places=2, null=True)
    TimeCreated = models.DateTimeField(auto_now_add=True)
    TimeModified = models.DateTimeField(auto_now=True)

    #class meta pl ipl unique together
    def __str__(self):
        return f"{self.PL.Name}; {self.IPL.FullName}; {self.Price}"
    
class UOM(models.Model):
    Name = models.CharField(max_length=80, blank=True, null=True)
    Abbreviation = models.CharField(max_length=12)
    Number_of = models.DecimalField(max_digits=12, decimal_places=3, blank=True, null=True)
    Parent = models.ForeignKey("UOM", related_name="parent", on_delete=models.DO_NOTHING, blank=True, null=True)
    Purchases = models.ForeignKey("UOM", related_name="purchases", on_delete=models.DO_NOTHING, blank=True, null=True)
    Sales = models.ForeignKey("UOM", related_name="sales", on_delete=models.DO_NOTHING, blank=True, null=True)

    def __str__(self):
        return self.Abbreviation
    
class Item(models.Model):
    ITEMINVENTORY = "1"
    NONINVENTORY = "2"
    SERVICE = "3"
    OTHERCHARGES = "4"
    SUBTOTAL = "5"
    GROUP = "6"
    DISCOUNT = "7"
    PAYMENT = "8"
    ITEM_TYPE_CHOICES = [
        (SERVICE, "SERVICE"),
        (ITEMINVENTORY, "INVENTORY PART"),
        (NONINVENTORY, "NON INVENTORY"),
        (OTHERCHARGES, "OTHER CHARGES"),
        (SUBTOTAL, "SUB TOTAL"),
        (GROUP, "GROUP"),
        (DISCOUNT, "DISCOUNT"),
        (PAYMENT, "PAYMENT"),
    ]
    ItemType = models.CharField(max_length=1, choices=ITEM_TYPE_CHOICES)
    Name = models.CharField(max_length=80)
    Parent = models.ForeignKey("Item", on_delete=models.DO_NOTHING, blank=True, null=True)
    FullName = models.CharField(max_length=80, blank=True, null=True, unique=True)
    # BarCodeValue = models.CharField(max_length=80)
    SalesDesc = models.CharField(max_length=80, blank=True, null=True)
    SalesPrice = models.DecimalField(max_digits=10, decimal_places=2, default=0)
    PurchaseDesc = models.CharField(max_length=80, blank=True, null=True)
    Sublevel = models.PositiveSmallIntegerField(default = 0)
    ManufacturerPartNumber = models.CharField(max_length=80, blank=True, null=True)
    PurchaseCost = models.DecimalField(max_digits=10, decimal_places=2, default=0)
    ReorderPoint = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
    QuantityOnHand = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
    AverageCost = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
    QuantityOnOrder = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
    QuantityOnSalesOrder = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
    UnitOfMeasureSetRefFullName = models.ForeignKey(UOM, verbose_name="UOM", on_delete=models.DO_NOTHING, blank=True, null=True)
    ParentRefFullName = models.CharField(max_length=80, blank=True, null=True)
    # SalesTaxCodeRefFullName
    IncomeAccountRefFullName= models.CharField(max_length=80, default="Sales")
    COGSAccountRefFullName = models.CharField(max_length=80, default="COGS")
    PrefVendorRefFullName = models.CharField(max_length=80, default="TACO")
    AssetAccountRefFullName = models.CharField(max_length=80, default="Inventory Asset")
    IsActive = models.BooleanField(default=True)
    NameFromTaco = models.CharField(max_length=60, blank=True, null=True)
    CATEGORY = models.CharField(max_length=60, blank=True, null=True)
    Type = models.CharField(max_length=60, blank=True, null=True)
    AlwaysNull = models.CharField(max_length=1, blank=True, null=True, editable=False)
    TimeCreated = models.DateTimeField(auto_now_add=True)
    TimeModified = models.DateTimeField(auto_now=True)
    
    # class Meta:
    #     ordering = ["FullName"]

    def get_field_name(obj):
        # return [(f.name, f.value_to_string(obj)) for f in obj._meta.fields]   #get value convert it to string
        return [(f.verbose_name, f.name, f.value_from_object(obj)) for f in obj._meta.fields]
    
    def save(self, *args, **kwargs):
        try:
            self.FullName = self.Name
            print(f"self.FullName={self.FullName}; self.parentreffullname={self.ParentRefFullName}; self.pk={self.pk}")
            if self.ParentRefFullName:
                print("masuk")
                parent = Item.objects.filter(FullName__iexact=self.ParentRefFullName)[0]
                print(f"parent.fullname:{parent.FullName}")

                if parent:
                    print(parent.FullName)
                    self.Parent=parent
            print(f"self.Parent={self.Parent}")
            if self.Parent:
                print(f"self.Parent={self.Parent}")
                if self.Parent.FullName:
                    self.FullName = f"{self.Parent.FullName}:{self.Name}"   #no need to do upper()
                else:
                    self.FullName = f"{self.Parent.Name}:{self.Name}"
                print(self.Parent.Name, self.Parent.FullName, self.FullName)
                item = Item.objects.filter(FullName__iexact=self.FullName)
                if item and not self.pk:    #check for unique constrain
                    raise ValidationError("Item FullName should be Unique") #TODO again later
                    # return
                    print("raise validationerror itemfullname should unique")
            print(f"{self.IsActive}; {self.PurchaseCost}; {self.ReorderPoint}")
            super(Item, self).save(*args, **kwargs)
        except IntegrityError:
            print("integrity error")
        except ValidationError:
            print("valid error")

    def __str__(self) -> str:
        if self.FullName:
            return f"{self.FullName}"
        else:
            return self.Name
        
    def get_absolute_url(self):  #     // ---> new function
        return reverse('Item:edit_item', args=[str(self.id)])