from django.db import models
from carts.models import Cart
from ecommerce.utils import unique_order_id_generator
from django.db.models.signals import pre_save,post_save
import math
from billing.models import BillingProfile
from addresss.models import Address

ORDER_STATUS_CHOICES = [ ( 'created' , 'Created' ),
                        ( 'paid' , 'Paid' ),
                        ( 'shipped' , 'Shipped' ),
                        ( 'refunded' , 'Refunded' )
                       ]

# Create your models here.

class OrderManager(models.Manager):
    def new_or_get(self,billing_profile,cart_obj):
        print("cart_objcart_obj",cart_obj)
        created= False
        qs = self.get_queryset().filter(
                  active=True,billing_profile=billing_profile,cart=cart_obj 
                ).exclude(status='paid')
        if qs.count() == 1:
            obj = qs.first()
        else:
            obj = self.model.objects.create(billing_profile=billing_profile,cart=cart_obj)
            created = True
        return obj ,created


class Order(models.Model):
    billing_profile = models.ForeignKey(BillingProfile,null=True,blank=True, on_delete=models.CASCADE)
    order_id = models.CharField(max_length=120,blank=True)
    cart = models.ForeignKey(Cart , on_delete=models.CASCADE)
    shipping_address = models.ForeignKey(Address,null=True, blank=True,on_delete=models.CASCADE)
    billing_address = models.ForeignKey(Address, related_name="billing_address",null=True, blank=True , on_delete=models.CASCADE)
    status = models.CharField(max_length=120,choices=ORDER_STATUS_CHOICES)
    shipping_total = models.DecimalField(default=5.99 , max_digits=100,decimal_places=2)
    total = models.DecimalField(default=0.00 , max_digits=100 , decimal_places=2)
    active = models.BooleanField(default=True)
    
    
    objects = OrderManager()
    
    def __str__(self):
        return self.order_id
    
    def update_total(self):
        cart_total = self.cart.total
        shipping_total = self.shipping_total
        new_total = math.fsum([cart_total,shipping_total])
        formatted_total = format(new_total,'.2f')
        self.total = formatted_total
        self.save()
        return new_total
    
    def check_done(self):
        billing_profile = self.billing_profile
        shipping_address = self.shipping_address
        billing_address = self.billing_address
        total = self.total
        if billing_profile and shipping_address and billing_address and total > 0:
            return True
        return False
    
    def mark_done(self):
        if self.check_done():
            self.status = "paid"
            self.save()
        return self.status

def pre_save_create_order_id(sender,instance,*args,**kwargs):
    if not instance.order_id:
        instance.order_id = unique_order_id_generator(instance)

pre_save.connect(pre_save_create_order_id,sender=Order)

    
def post_save_cart_total(sender,instance,created,*args,**kwargs):
    if not created:
        cart_obj = instance
        cart_total = instance.total
        cart_id = instance.id
        qs = Order.objects.filter(cart__id=cart_id)
        if qs.count() ==1:
            order_obj = qs.first()
            order_obj.update_total()
            
            
post_save.connect(post_save_cart_total,sender=Cart)

def pre_save_create_order_id(sender,instance,*args,**kwargs):
    if not instance.order_id:
        instance.order_id = unique_order_id_generator(instance)
    qs = Order.objects.filter(cart=instance.cart).exclude(billing_profile=instance.billing_profile)
    if qs.exists():
        qs.update(active=False)
pre_save.connect(pre_save_create_order_id,sender=Order)


def post_save_order(sender,instance,created,*args,**kwargs):
    print("running")
    if created:
        print("Updating first")
        instance.update_total()
        
post_save.connect(post_save_order,sender=Order)