"""
Shopping Cart Views
"""
from django.shortcuts import render, redirect, get_object_or_404
from django.http import JsonResponse
from decimal import Decimal, ROUND_HALF_UP
from django.contrib import messages
from django.views.decorators.http import require_http_methods
from django.contrib.auth.decorators import login_required
from .models import Cart, CartItem
from products.models import Product
import json


def get_or_create_cart(request):
    """Get or create cart for user or session"""
    if request.user.is_authenticated:
        cart, created = Cart.objects.get_or_create(user=request.user)
    else:
        # For anonymous users, use session
        if not request.session.session_key:
            request.session.create()
        session_key = request.session.session_key
        cart, created = Cart.objects.get_or_create(session_key=session_key)
    return cart


def cart_view(request):
    """Display cart page"""
    cart = get_or_create_cart(request)
    cart_items = cart.items.select_related('product', 'variation').all()
    
    context = {
        'cart': cart,
        'cart_items': cart_items,
    }
    return render(request, 'pages/cart.html', context)


@require_http_methods(["POST"])
def add_to_cart(request, product_id):
    """Add product to cart"""
    product = get_object_or_404(Product, id=product_id, is_active=True)
    cart = get_or_create_cart(request)
    
    # Get quantity from request
    try:
        data = json.loads(request.body)
        quantity_raw = data.get('quantity', 1)
        variation_id = data.get('variation_id')
    except:
        quantity_raw = request.POST.get('quantity', 1)
        variation_id = request.POST.get('variation_id')
    
    try:
        quantity = int(str(quantity_raw))
    except Exception:
        quantity = 1
    
    variation = None
    if variation_id:
        try:
            from products.models import ProductVariation
            variation = ProductVariation.objects.get(id=int(variation_id), product=product)
        except Exception:
            variation = None
    
    if variation:
        if variation.stock <= 0 or quantity <= 0:
            msg = 'Selected variation is out of stock'
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({'success': False, 'message': msg}, status=400)
            messages.error(request, msg)
            return redirect('frontend:cart')
        if quantity > int(variation.stock):
            msg = 'Requested quantity exceeds available stock for this variation'
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({'success': False, 'message': msg}, status=400)
            messages.error(request, msg)
            return redirect('frontend:cart')
    
    # Check if item already in cart
    cart_item, created = CartItem.objects.get_or_create(
        cart=cart,
        product=product,
        variation=variation,
        defaults={'quantity': quantity}
    )
    
    if not created:
        new_qty = int(cart_item.quantity) + int(quantity)
        if variation and new_qty > int(variation.stock):
            msg = 'Requested quantity exceeds available stock for this variation'
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({'success': False, 'message': msg}, status=400)
            messages.error(request, msg)
            return redirect('frontend:cart')
        cart_item.quantity = new_qty
        cart_item.save()
    else:
        if variation and quantity > int(variation.stock):
            cart_item.delete()
            msg = 'Requested quantity exceeds available stock for this variation'
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({'success': False, 'message': msg}, status=400)
            messages.error(request, msg)
            return redirect('frontend:cart')
    
    # Return JSON response for AJAX requests
    if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
        return JsonResponse({
            'success': True,
            'message': f'{product.name} added to cart!',
            'cart_total_items': cart.total_items,
            'cart_total': float(cart.total.quantize(Decimal('1'), rounding=ROUND_HALF_UP)),
        })
    
    # Regular form submission
    messages.success(request, f'{product.name} added to cart!')
    return redirect('frontend:cart')


@require_http_methods(["POST"])
def update_cart_item(request, item_id):
    """Update cart item quantity"""
    cart_item = get_object_or_404(CartItem, id=item_id)
    cart = get_or_create_cart(request)
    
    # Verify this item belongs to current cart
    if cart_item.cart != cart:
        return JsonResponse({'success': False, 'message': 'Invalid cart item'}, status=403)
    
    try:
        data = json.loads(request.body)
        quantity_raw = data.get('quantity', 1)
    except:
        quantity_raw = request.POST.get('quantity', 1)
    
    try:
        quantity = int(str(quantity_raw))
    except Exception:
        quantity = 1
    
    if quantity <= 0:
        cart_item.delete()
        message = 'Item removed from cart'
    else:
        if cart_item.variation:
            if quantity > int(cart_item.variation.stock):
                return JsonResponse({'success': False, 'message': 'Requested quantity exceeds available stock'}, status=400)
        cart_item.quantity = quantity
        cart_item.save()
        message = 'Cart updated'
    
    if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
        return JsonResponse({
            'success': True,
            'message': message,
            'cart_total_items': cart.total_items,
            'cart_subtotal': float(cart.subtotal.quantize(Decimal('1'), rounding=ROUND_HALF_UP)),
            'cart_total': float(cart.total.quantize(Decimal('1'), rounding=ROUND_HALF_UP)),
            'item_total': float(cart_item.total_price.quantize(Decimal('1'), rounding=ROUND_HALF_UP)) if quantity > 0 else 0,
        })
    
    messages.success(request, message)
    return redirect('frontend:cart')


@require_http_methods(["POST", "DELETE"])
def remove_from_cart(request, item_id):
    """Remove item from cart"""
    cart = get_or_create_cart(request)
    cart_item = CartItem.objects.filter(id=item_id).first()

    if not cart_item:
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return JsonResponse({
                'success': True,
                'message': 'Item removed from cart',
                'cart_total_items': cart.total_items,
                'cart_subtotal': float(cart.subtotal.quantize(Decimal('1'), rounding=ROUND_HALF_UP)),
                'cart_total': float(cart.total.quantize(Decimal('1'), rounding=ROUND_HALF_UP)),
            })
        messages.info(request, 'Cart was refreshed.')
        return redirect('frontend:cart')
    
    # Verify this item belongs to current cart
    if cart_item.cart != cart:
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return JsonResponse({
                'success': True,
                'message': 'Item removed from cart',
                'cart_total_items': cart.total_items,
                'cart_subtotal': float(cart.subtotal.quantize(Decimal('1'), rounding=ROUND_HALF_UP)),
                'cart_total': float(cart.total.quantize(Decimal('1'), rounding=ROUND_HALF_UP)),
            })
        messages.info(request, 'Cart was refreshed.')
        return redirect('frontend:cart')
    
    product_name = cart_item.product.name
    cart_item.delete()
    
    if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
        return JsonResponse({
            'success': True,
            'message': f'{product_name} removed from cart',
            'cart_total_items': cart.total_items,
            'cart_subtotal': float(cart.subtotal.quantize(Decimal('1'), rounding=ROUND_HALF_UP)),
            'cart_total': float(cart.total.quantize(Decimal('1'), rounding=ROUND_HALF_UP)),
        })
    
    messages.success(request, f'{product_name} removed from cart')
    return redirect('frontend:cart')


def clear_cart(request):
    """Clear all items from cart"""
    cart = get_or_create_cart(request)
    cart.items.all().delete()
    
    if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
        return JsonResponse({
            'success': True,
            'message': 'Cart cleared'
        })
    
    messages.success(request, 'Cart cleared')
    return redirect('frontend:cart')


def get_cart_count(request):
    """Get cart item count (for AJAX)"""
    cart = get_or_create_cart(request)
    return JsonResponse({
        'count': cart.total_items,
        'total': float(cart.total.quantize(Decimal('1'), rounding=ROUND_HALF_UP)),
    })


def get_cart_data(request):
    """Get all cart items data (product_id: quantity)"""
    cart = get_or_create_cart(request)
    # Return dictionary of product_id: quantity
    # If multiple items with same product (different variations), sum them up
    items_data = {}
    for item in cart.items.all():
        pid = item.product.id
        if pid in items_data:
            items_data[pid] += item.quantity
        else:
            items_data[pid] = item.quantity
            
    return JsonResponse({
        'success': True,
        'items': items_data,
        'count': cart.total_items,
        'total': float(cart.total.quantize(Decimal('1'), rounding=ROUND_HALF_UP)),
    })
