""" Code to handle the website shopping cart """
from datetime import datetime, timedelta
import logging

from django.shortcuts import get_object_or_404
from .models import Cart, CartItem, CartItemGiftDetail

LOGGER = logging.getLogger("cart")


def get_cart_from_key(cart_key):
    """ Given a cart_id, get the cart """
    return Cart.objects.for_session(cart_key)


def get_cart(request):
    """ get the cart for the given request """
    return Cart.objects.for_request(request)


def get_cart_items(request):
    """ return all items from the current user's cart """
    cart = get_cart(request)
    return cart.cart_items


def empty_cart(request):
    """ empties the shopping cart of the current customer """
    user_cart = get_cart_items(request)
    user_cart.delete()


def remove_subscriptions(request):
    """ removes any subscriptions from the cart """
    user_cart = get_cart_items(request)
    for item in user_cart:
        if item.product.is_subscription:
            item.delete()


def get_single_item(request, cart_token):
    """ get the one item from the cart """
    return get_object_or_404(CartItem, cart_token=cart_token, cart=get_cart(request))


def remove_from_cart(request, cart_token):
    """ function that removes a single product instance from the
    current customer's shopping cart
    """
    cart_item = get_single_item(request, cart_token)
    if cart_item:
        gift_detail = cart_item.gift_detail
        if gift_detail:
            gift_detail.delete()
        cart_item.delete()


def cart_subtotal(request):
    """ cart subtotal """
    cart = get_cart(request)
    return cart.cart_subtotal


def cart_distinct_item_count(request):
    """ returns the total number of items in the user's cart """
    cart = get_cart(request)
    return cart.item_count


def is_empty(request):
    """ Check if the cart is empty """
    return cart_distinct_item_count(request) == 0


def update_cart(request, cart_item, quantity):
    """ function takes the quantity for single product instance in the
    current customer's shopping cart, and updates it.
    """
    if cart_item:
        if int(quantity) > 0:
            cart_item.quantity = int(quantity)
            cart_item.save()
        else:
            remove_from_cart(request, cart_item.cart_token)


def add_to_cart(request, item, account_number=None, gift_detail=None, quantity=1):
    """ function that takes an item instance to the current
    customer's shopping cart

    :param detail: dictionary of additional cart information
    """
    # get cart
    cart = get_cart(request)

    if not cart:
        LOGGER.info("Cart is None, just returning. See this with search bots")
        return

    # get products in cart
    cart_products = cart.cart_items

    product_in_cart = False
    # check to see if item is already in cart
    for cart_item in cart_products:
        if cart_item.product.pk == item.pk:
            # update the quantity if found
            # only works if we can have one item and no options
            cart_item.quantity = cart_item.quantity + quantity
            product_in_cart = True
            cart_item.save()

    if not product_in_cart:
        # create and save a new cart item
        cart_item = CartItem()
        cart_item.cart = cart
        cart_item.product = item
        cart_item.quantity = quantity
        cart_item.account_number = account_number
        cart_item.save()

    if gift_detail:
        cart_item_gift_detail = CartItemGiftDetail(**gift_detail)
        cart_item_gift_detail.save()
        cart_item.gift_detail = cart_item_gift_detail
        cart_item.save()


def remove_old_cart_items():
    """ 1. calculate date of 30 days ago,
    2. find how many carts are older then date
    3. delete those Cart instances
    """
    LOGGER.debug("Removing old carts")
    remove_before = datetime.now() + timedelta(days=-30)
    # TODO, keep carts related to checkout?
    old_items = Cart.objects.filter(last_update__lt=remove_before)
    old_item_count = old_items.count()
    if old_item_count > 0:
        old_items.delete()
    LOGGER.debug("{0} carts were removed".format(old_item_count))
