import json
import logging
from datetime import timedelta
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth import login, authenticate, logout
from django.contrib.auth.decorators import login_required
from django.db.models import Q, Sum
from django.utils.timezone import now
from django.views.decorators.csrf import csrf_exempt
from .models import Cart, CartItem, ShippingAddress, Order, OrderItem, ShippingMethod
from settings.models import Shop
from inventory.models import Product, Category
try:
    from customers.models import Customer
except ImportError:
    Customer = None
from .forms import AddToCartForm, GuestCheckoutForm, ShippingAddressForm, SearchForm, ShippingMethodForm, CustomerRegistrationForm, CustomerLoginForm
from django.http import JsonResponse
from django.contrib import messages
from .stk_push import MpesaSTKPush
from django.forms.models import model_to_dict
from django.core.paginator import Paginator
from django.contrib.auth.models import User


# ----------------- PRODUCT VIEWS -----------------
def product_list(request):
    query = Q()

    # Search functionality
    search_query = request.GET.get('q', '')
    if search_query:
        query &= (
            Q(name__icontains=search_query) | 
            Q(description__icontains=search_query) |
            Q(barcode__icontains=search_query) |
            Q(variant__icontains=search_query) |
            Q(category__name__icontains=search_query) |
            Q(seo_title__icontains=search_query) |
            Q(seo_description__icontains=search_query) |
            Q(packaging_type__icontains=search_query)
        )

    # Filter by category
    category_id = request.GET.get('category')
    if category_id:
        query &= Q(category_id=category_id)

    # Filter by special criteria
    special_filter = request.GET.get('filter')
    if special_filter == 'sale':
        query &= Q(discount_price__isnull=False)
    elif special_filter == 'new':
        one_week_ago = now() - timedelta(weeks=1)
        query &= Q(created_at__gte=one_week_ago)
    elif special_filter == 'best_seller':
        query &= Q(is_active=True)

    # Sorting
    sort_option = request.GET.get('sort')
    if sort_option == 'price_asc':
        order_by = 'selling_price'
    elif sort_option == 'price_desc':
        order_by = '-selling_price'
    elif sort_option == 'name':
        order_by = 'name'
    else:
        order_by = '-created_at'

    products = Product.objects.filter(query).order_by(order_by).distinct()
    categories = Category.objects.all()

    return render(request, 'shop/product_list.html', {
        'products': products,
        'categories': categories,
    })


def product_detail(request, product_id):
    product = get_object_or_404(Product, id=product_id)
    recommended_products = Product.objects.filter(category=product.category).exclude(id=product.id)[:3]
    return render(request, 'shop/product_detail.html', {
        'product': product,
        'recommended_products': recommended_products,
    })


# ----------------- CART VIEWS -----------------

def add_to_cart(request):
    """
    Add a product to the cart.
    """
    if request.method == 'POST':
        form = AddToCartForm(request.POST)
        if form.is_valid():
            product = get_object_or_404(Product, id=form.cleaned_data['product_id'])
            quantity = form.cleaned_data['quantity']

            # Handle cart for logged-in user or guest
            if request.user.is_authenticated:
                cart, _ = Cart.objects.get_or_create(user=request.user)
            else:
                session_key = request.session.session_key or request.session.save()
                cart, _ = Cart.objects.get_or_create(session_key=session_key)

            # Add item to the cart
            cart_item, created = CartItem.objects.get_or_create(cart=cart, product=product)
            if not created:
                cart_item.quantity += quantity
            cart_item.save()

            messages.success(request, f"{product.name} added to cart.")
            return redirect('shop:cart_detail')

    return redirect('product_list')


def cart_detail(request):
    """
    Display the cart details for the user or guest.
    Creates a cart if it doesn't already exist.
    """
    # Check if the user is authenticated
    if request.user.is_authenticated:
        # Fetch or create the cart for the authenticated user
        cart, created = Cart.objects.get_or_create(user=request.user)
    else:
        # Ensure the session has a key for unauthenticated users
        if not request.session.session_key:
            request.session.create()
        session_key = request.session.session_key

        # Fetch or create a cart for the session
        cart, created = Cart.objects.get_or_create(session_key=session_key, user=None)

    # Prefetch items for performance optimization
    items = cart.items.select_related('product').all()
    total_price = sum(item.get_total_price() for item in items)

    return render(request, 'shop/cart_detail.html', {
        'items': items,
        'total_price': total_price,
    })


def remove_from_cart(request, cart_item_id):
    """
    Remove an item from the cart.
    """
    cart_item = get_object_or_404(CartItem, id=cart_item_id)

    # Ensure the item belongs to the current user's or guest's cart
    if request.user.is_authenticated:
        if cart_item.cart.user != request.user:
            return redirect('cart_detail')
    else:
        session_key = request.session.session_key
        if cart_item.cart.session_key != session_key:
            return redirect('shop:cart_detail')

    cart_item.delete()
    messages.success(request, "Item removed from cart.")
    return redirect('shop:cart_detail')

def update_cart(request):
    if request.method == "POST":
        item_id = request.POST.get('item_id')
        action = request.POST.get('action')
        cart_item = get_object_or_404(CartItem, id=item_id)

        if action == "increment":
            cart_item.quantity += 1
        elif action == "decrement" and cart_item.quantity > 1:
            cart_item.quantity -= 1
        cart_item.save()

    return redirect('shop:cart_detail')


# ----------------- CHECKOUT VIEWS -----------------

def checkout(request):
    """
    Handle checkout process for both logged-in and guest users.
    """
    if request.user.is_authenticated:
        cart = Cart.objects.filter(user=request.user).first()
    else:
        session_key = request.session.session_key or request.session.save()
        cart = Cart.objects.filter(session_key=session_key).first()

    if not cart or not cart.items.exists():
        messages.error(request, "Your cart is empty.")
        return redirect('shop:cart_detail')

    shipping_form = ShippingAddressForm(request.POST or None)
    shipping_methods = ShippingMethod.objects.filter(is_active=True)
    selected_shipping_method = None
    total_price = cart.get_total_price()

    # Get saved addresses for logged-in users
    saved_addresses = []
    payment_on_delivery_eligible = False
    
    if request.user.is_authenticated:
        saved_addresses = ShippingAddress.objects.filter(user=request.user)
        # Check eligibility for payment on delivery (5+ successful orders)
        successful_orders = Order.objects.filter(
            user=request.user, 
            status__in=['Delivered', 'Processing', 'Shipped']
        ).count()
        payment_on_delivery_eligible = successful_orders >= 5

    if request.method == "POST":
        payment_method = request.POST.get('payment_method', 'mpesa')
        shipping_method_id = request.POST.get('shipping_method')
        
        if shipping_method_id:
            selected_shipping_method = get_object_or_404(ShippingMethod, id=shipping_method_id)
            total_price += selected_shipping_method.cost

        # Handle saved address selection
        saved_address_id = request.POST.get('saved_address')
        if saved_address_id and request.user.is_authenticated:
            try:
                shipping_address = ShippingAddress.objects.get(id=saved_address_id, user=request.user)
            except ShippingAddress.DoesNotExist:
                messages.error(request, "Selected address not found.")
                return redirect('shop:checkout')
        elif shipping_form.is_valid():
            if request.user.is_authenticated:
                shipping_address = shipping_form.save(commit=False)
                shipping_address.user = request.user
                shipping_address.save()
            else:
                shipping_address = shipping_form.save(commit=False)
                shipping_address.guest_email = request.POST.get('email')
                shipping_address.save()
        else:
            messages.error(request, "Please provide valid shipping information.")
            return render(request, 'shop/checkout.html', {
                'cart': cart,
                'shipping_methods': shipping_methods,
                'shipping_form': shipping_form,
                'saved_addresses': saved_addresses,
                'total_price': total_price,
                'payment_on_delivery_eligible': payment_on_delivery_eligible,
            })

        if shipping_address and selected_shipping_method:
            # Create order
            order = Order.objects.create(
                user=request.user if request.user.is_authenticated else None,
                guest_email=shipping_address.guest_email if not request.user.is_authenticated else None,
                shipping_address=shipping_address,
                shipping_method=selected_shipping_method,
                total_price=total_price,
                payment_method=payment_method
            )
            
            for item in cart.items.all():
                OrderItem.objects.create(
                    order=order,
                    product=item.product,
                    quantity=item.quantity,
                    price=item.get_unit_price()
                )

            # Handle different payment methods
            if payment_method == 'payment_on_delivery':
                if not payment_on_delivery_eligible:
                    messages.error(request, "You are not eligible for Payment on Delivery.")
                    order.delete()
                    return redirect('shop:checkout')
                
                order.status = 'Processing'
                order.mpesa_payment_status = 'Payment on Delivery'
                order.save()
                cart.items.all().delete()
                messages.success(request, "Order placed successfully! Payment will be collected on delivery.")
                return redirect('shop:order_confirmation', order_id=order.id)
                
            elif payment_method == 'card':
                # Store order ID in session for card payment callback
                request.session['pending_order_id'] = order.id
                return redirect('shop:card_payment', order_id=order.id)
                
            else:  # mpesa
                phone_number = request.POST.get('phone_number')
                shop = Shop.objects.first()
                if not shop:
                    messages.error(request, "Payment configuration is missing.")
                    logging.error("Checkout attempted without a Shop configuration.")
                    order.delete()
                    return redirect('shop:checkout')

                mpesa = MpesaSTKPush(shop)
                try:
                    response = mpesa.initiate_stk_push(phone_number, total_price, f"Order #{order.id}")
                    if response.get("ResponseCode") == "0":
                        order.mpesa_payment_status = 'Pending'
                        order.save()
                        cart.items.all().delete()
                        request.session['pending_order_id'] = order.id
                        messages.success(request, "STK Push sent. Please complete the payment on your phone.")
                        return redirect('shop:payment_status', order_id=order.id)
                    else:
                        error_msg = response.get('errorMessage', 'Payment initiation failed')
                        messages.error(request, f"Payment failed: {error_msg}")
                        # Don't delete order, allow retry
                        return redirect('shop:payment_retry', order_id=order.id)
                except Exception as e:
                    logging.error(f"STK Push failed for Order #{order.id}: {e}")
                    messages.error(request, "Payment processing error. Please try again.")
                    return redirect('shop:payment_retry', order_id=order.id)

    return render(request, 'shop/checkout.html', {
        'cart': cart,
        'shipping_methods': shipping_methods,
        'shipping_form': shipping_form,
        'saved_addresses': saved_addresses,
        'total_price': total_price,
        'payment_on_delivery_eligible': payment_on_delivery_eligible,
    })


def order_confirmation(request, order_id):
    """
    Display order confirmation details.
    """
    order = get_object_or_404(Order, id=order_id)
    return render(request, 'shop/order_confirmation.html', {'order': order})


# ----------------- ORDER MANAGEMENT VIEWS -----------------

@login_required
def order_list(request):
    """
    Display the logged-in user's order history.
    """
    orders = Order.objects.filter(user=request.user).order_by('-created_at')
    return render(request, 'shop/order_list.html', {'orders': orders})


@login_required
def order_detail(request, order_id):
    """
    Display details of a specific order.
    """
    order = get_object_or_404(Order, id=order_id, user=request.user)
    return render(request, 'shop/order_detail.html', {'order': order})


# ----------------- SEARCH VIEW -----------------

def search(request):
    """
    Search for products by name, description, barcode, category, and other fields.
    """
    query = request.GET.get('q', '')
    is_ajax = request.GET.get('ajax') == '1'
    products = Product.objects.none()

    if query:
        products = Product.objects.filter(
            Q(name__icontains=query) | 
            Q(description__icontains=query) |
            Q(barcode__icontains=query) |
            Q(variant__icontains=query) |
            Q(category__name__icontains=query) |
            Q(seo_title__icontains=query) |
            Q(seo_description__icontains=query) |
            Q(packaging_type__icontains=query),
            is_active=True
        ).distinct()

    # Handle AJAX requests for live suggestions
    if is_ajax:
        suggestions = []
        for product in products[:5]:  # Limit to 5 suggestions
            suggestions.append({
                'name': product.name,
                'price': str(product.discount_price if product.discount_price else product.selling_price),
                'url': f"/shop/product/{product.id}/"
            })
        return JsonResponse({'suggestions': suggestions})

    return render(request, 'shop/search_results.html', {'products': products, 'query': query})

# ----------------- MY ACCOUNT -----------------
@login_required
def my_account(request):
    """
    Display user account information.
    """
    user = request.user
    return render(request, 'shop/my_account.html', {'user': user})


# ----------------- MY ORDERS -----------------
@login_required
def my_orders(request):
    """
    Display the logged-in user's order history.
    """
    orders = Order.objects.filter(user=request.user).order_by('-created_at')
    return render(request, 'shop/my_orders.html', {'orders': orders})


@login_required
def order_detail(request, order_id):
    """
    Display details of a specific order.
    """
    order = get_object_or_404(Order, id=order_id, user=request.user)
    return render(request, 'shop/order_detail.html', {'order': order})


# ----------------- SAVED ITEMS -----------------
@login_required
def saved_items(request):
    """
    Display the logged-in user's saved items.
    """
    from .models import SavedItem
    saved_items = SavedItem.objects.filter(user=request.user).select_related('product')
    return render(request, 'shop/saved_items.html', {'saved_items': saved_items})


@login_required
def add_to_saved_items(request, product_id):
    """
    Add a product to the user's saved items.
    """
    if request.method == 'POST':
        from .models import SavedItem
        product = get_object_or_404(Product, id=product_id)
        saved_item, created = SavedItem.objects.get_or_create(
            user=request.user,
            product=product
        )
        if created:
            messages.success(request, f"{product.name} added to saved items.")
        else:
            messages.info(request, f"{product.name} is already in your saved items.")

        return JsonResponse({'success': True, 'created': created})
    return JsonResponse({'success': False})


@login_required
def remove_from_saved_items(request, saved_item_id):
    """
    Remove a product from the user's saved items.
    """
    if request.method == 'POST':
        from .models import SavedItem
        saved_item = get_object_or_404(SavedItem, id=saved_item_id, user=request.user)
        product_name = saved_item.product.name
        saved_item.delete()
        messages.success(request, f"{product_name} removed from saved items.")
        return JsonResponse({'success': True})
    return JsonResponse({'success': False})


@login_required
def remove_saved_item_by_product(request, product_id):
    """
    Remove a product from the user's saved items by product ID.
    """
    if request.method == 'POST':
        from .models import SavedItem
        try:
            saved_item = SavedItem.objects.get(user=request.user, product_id=product_id)
            product_name = saved_item.product.name
            saved_item.delete()
            messages.success(request, f"{product_name} removed from saved items.")
            return JsonResponse({'success': True})
        except SavedItem.DoesNotExist:
            return JsonResponse({'success': False, 'error': 'Item not found in saved items'})
    return JsonResponse({'success': False})

def about_us(request):
    """
    About Us page.
    """
    return render(request, 'shop/about_us.html')


def help_center(request):
    """
    Help Center page.
    """
    return render(request, 'shop/help_center.html')


def terms_and_conditions(request):
    """
    Terms & Conditions page.
    """
    return render(request, 'shop/terms_and_conditions.html')


def privacy_policy(request):
    """
    Privacy Policy page.
    """
    return render(request, 'shop/privacy_policy.html')

def return_policy(request):
    return render(request, 'shop/return_policy.html')

def cookie_policy(request):
    return render(request, 'shop/cookie_policy.html')

def search(request):
    """
    Search for products by name, description, barcode, category, and other fields.
    """
    query = request.GET.get('q', '')
    is_ajax = request.GET.get('ajax') == '1'
    products = Product.objects.none()

    if query:
        products = Product.objects.filter(
            Q(name__icontains=query) | 
            Q(description__icontains=query) |
            Q(barcode__icontains=query) |
            Q(variant__icontains=query) |
            Q(category__name__icontains=query) |
            Q(seo_title__icontains=query) |
            Q(seo_description__icontains=query) |
            Q(packaging_type__icontains=query),
            is_active=True
        ).distinct()

    # Handle AJAX requests for live suggestions
    if is_ajax:
        suggestions = []
        for product in products[:5]:  # Limit to 5 suggestions
            suggestions.append({
                'name': product.name,
                'price': str(product.discount_price if product.discount_price else product.selling_price),
                'url': f"/shop/product/{product.id}/"
            })
        return JsonResponse({'suggestions': suggestions})

    return render(request, 'shop/search_results.html', {'products': products, 'query': query})


@login_required
def reorder_items(request, order_id):
    """Add all items from a previous order to cart"""
    if request.method == 'POST':
        try:
            order = Order.objects.get(id=order_id, user=request.user)
            cart = request.session.get('cart', {})

            for item in order.items.all():
                product_id = str(item.product.id)
                if product_id in cart:
                    cart[product_id] += item.quantity
                else:
                    cart[product_id] = item.quantity

            request.session['cart'] = cart
            return JsonResponse({'success': True, 'message': 'Items added to cart'})
        except Order.DoesNotExist:
            return JsonResponse({'success': False, 'message': 'Order not found'})
        except Exception as e:
            return JsonResponse({'success': False, 'message': str(e)})

    return JsonResponse({'success': False, 'message': 'Invalid request'})

@csrf_exempt
def mpesa_callback(request):
    """
    Handle M-Pesa STK Push payment callback.
    """
    if request.method == "POST":
        try:
            data = json.loads(request.body)
            result_code = data.get("Body", {}).get("stkCallback", {}).get("ResultCode")
            merchant_request_id = data.get("Body", {}).get("stkCallback", {}).get("MerchantRequestID")

            if result_code == 0:
                # Payment successful
                order = Order.objects.filter(account_reference=merchant_request_id).first()
                if order:
                    order.payment_status = "Paid"
                    order.mpesa_payment_status = "Paid"
                    order.save()
                    logging.info(f"Payment successful for Order #{order.id}")
                return JsonResponse({"status": "success", "message": "Payment successful."})

            # Log failure reason
            logging.warning(f"Payment failed for MerchantRequestID {merchant_request_id}: ResultCode {result_code}")
            return JsonResponse({"status": "failure", "message": "Payment failed or cancelled."})
        except Exception as e:
            logging.error(f"Error processing M-Pesa callback: {e}")
            return JsonResponse({"status": "error", "message": "Callback processing failed."})

    return JsonResponse({"status": "error", "message": "Invalid request method."})



@login_required
def shipping_method_list(request):
    """
    List all shipping methods and display the form for creating a new method.
    """
    shipping_methods = ShippingMethod.objects.all()
    form = ShippingMethodForm()  # Empty form for creating a new shipping method
    return render(request, 'shop/shipping_method_list.html', {
        'shipping_methods': shipping_methods,
        'form': form,
    })


@login_required
def shipping_method_create(request):
    """
    Create a new shipping method and redirect to the list view.
    """
    if request.method == 'POST':
        form = ShippingMethodForm(request.POST)
        if form.is_valid():
            form.save()
            messages.success(request, "Shipping method created successfully.")
        else:
            messages.error(request, "There were errors in the form. Please correct them.")
    return redirect('shop:shipping_method_list')


@login_required
def shipping_method_edit(request, pk):
    """
    Edit an existing shipping method.
    """
    shipping_method = get_object_or_404(ShippingMethod, pk=pk)
    if request.method == 'POST':
        form = ShippingMethodForm(request.POST, instance=shipping_method)
        if form.is_valid():
            form.save()
            messages.success(request, "Shipping method updated successfully.")
        else:
            messages.error(request, "There were errors in the form. Please correct them.")
        return redirect('shop:shipping_method_list')
    else:
        messages.error(request, "Invalid request method.")
        return redirect('shop:shipping_method_list')


@login_required
def shipping_method_delete(request, pk):
    """
    Delete an existing shipping method and redirect to the list view.
    """
    shipping_method = get_object_or_404(ShippingMethod, pk=pk)
    if request.method == 'POST':
        shipping_method.delete()
        messages.success(request, "Shipping method deleted successfully.")
    else:
        messages.error(request, "Invalid request method.")
    return redirect('shop:shipping_method_list')

def customer_register(request):
    if request.method == 'POST':
        form = CustomerRegistrationForm(request.POST)
        if form.is_valid():
            user = form.save(commit=False)
            user.set_password(form.cleaned_data['password'])
            user.save()

            # Assign user to Customer group
            from django.contrib.auth.models import Group
            customer_group, created = Group.objects.get_or_create(name='Customer')
            user.groups.add(customer_group)

            # Create customer profile
            if Customer:
                try:
                    Customer.objects.create(
                        user=user,
                        name=f"{user.first_name} {user.last_name}",
                        email=user.email,
                        phone=form.cleaned_data.get('phone', ''),
                        address=form.cleaned_data.get('address', '')
                    )
                except:
                    # Customer model might not exist, continue without it
                    pass

            # Log the user in
            login(request, user)
            messages.success(request, 'Account created successfully! Welcome to our store.')
            return redirect('shop:product_list')
        else:
            messages.error(request, 'Please correct the errors below.')
    else:
        form = CustomerRegistrationForm()

    return render(request, 'shop/customer_register.html', {'form': form})

def customer_login(request):
    if request.method == 'POST':
        form = CustomerLoginForm(request, data=request.POST)
        if form.is_valid():
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            user = authenticate(username=username, password=password)
            if user is not None:
                login(request, user)
                messages.success(request, f'Welcome back, {user.first_name}!')
                next_url = request.GET.get('next', 'shop:product_list')
                return redirect(next_url)
        else:
            messages.error(request, 'Invalid username or password.')
    else:
        form = CustomerLoginForm()

    return render(request, 'shop/customer_login.html', {'form': form})

def customer_logout(request):
    logout(request)
    messages.success(request, 'You have been logged out successfully.')
    return redirect('shop:product_list')

@login_required
def customer_profile(request):
    customer = None
    if Customer:
        try:
            # Try to find customer by email since there's no user field
            customer = Customer.objects.filter(email=request.user.email).first()
            if not customer:
                # Create customer profile if it doesn't exist
                customer = Customer.objects.create(
                    first_name=request.user.first_name,
                    last_name=request.user.last_name,
                    email=request.user.email,
                    phone='',
                    address=''
                )
        except Exception:
            # Handle any other exceptions
            customer = None

    if request.method == 'POST':
        from .forms import CustomerProfileForm
        form = CustomerProfileForm(request.POST, instance=request.user)
        if form.is_valid():
            form.save()

            # Update customer information if Customer model exists
            if customer:
                customer.first_name = request.user.first_name
                customer.last_name = request.user.last_name
                customer.email = request.user.email
                customer.phone = form.cleaned_data.get('phone', '')
                customer.address = form.cleaned_data.get('address', '')
                customer.save()

            messages.success(request, 'Profile updated successfully!')
            return redirect('shop:customer_profile')
        else:
            messages.error(request, 'Please correct the errors below.')
    else:
        from .forms import CustomerProfileForm
        initial_data = {}
        if customer:
            initial_data['phone'] = customer.phone
            initial_data['address'] = customer.address
        form = CustomerProfileForm(instance=request.user, initial=initial_data)

    return render(request, 'shop/customer_profile.html', {
        'customer': customer,
        'form': form
    })


@login_required
def customer_addresses(request):
    """
    List all addresses for the customer.
    """
    addresses = ShippingAddress.objects.filter(user=request.user)
    return render(request, 'shop/customer_addresses.html', {'addresses': addresses})


@login_required
def customer_address_add(request):
    """
    Add a new address for the customer.
    """
    if request.method == 'POST':
        from .forms import CustomerAddressForm
        form = CustomerAddressForm(request.POST)
        if form.is_valid():
            address = form.save(commit=False)
            address.user = request.user
            address.save()
            messages.success(request, 'Address added successfully!')
            return redirect('shop:customer_addresses')
        else:
            messages.error(request, 'Please correct the errors below.')
    else:
        from .forms import CustomerAddressForm
        form = CustomerAddressForm()

    return render(request, 'shop/customer_address_form.html', {
        'form': form,
        'title': 'Add New Address'
    })


@login_required
def customer_address_edit(request, address_id):
    """
    Edit an existing address.
    """
    address = get_object_or_404(ShippingAddress, id=address_id, user=request.user)

    if request.method == 'POST':
        from .forms import CustomerAddressForm
        form = CustomerAddressForm(request.POST, instance=address)
        if form.is_valid():
            form.save()
            messages.success(request, 'Address updated successfully!')
            return redirect('shop:customer_addresses')
        else:
            messages.error(request, 'Please correct the errors below.')
    else:
        from .forms import CustomerAddressForm
        form = CustomerAddressForm(instance=address)

    return render(request, 'shop/customer_address_form.html', {
        'form': form,
        'address': address,
        'title': 'Edit Address'
    })


@login_required
def customer_address_delete(request, address_id):
    """
    Delete an address.
    """
    address = get_object_or_404(ShippingAddress, id=address_id, user=request.user)

    if request.method == 'POST':
        address.delete()
        messages.success(request, 'Address deleted successfully!')
        return redirect('shop:customer_addresses')

    return render(request, 'shop/customer_address_confirm_delete.html', {'address': address})


@login_required
def customer_change_password(request):
    """
    Change customer password.
    """
    if request.method == 'POST':
        from .forms import CustomerPasswordChangeForm
        form = CustomerPasswordChangeForm(request.user, request.POST)
        if form.is_valid():
            form.save()
            messages.success(request, 'Password changed successfully!')
            return redirect('shop:customer_profile')
        else:
            messages.error(request, 'Please correct the errors below.')
    else:
        from .forms import CustomerPasswordChangeForm
        form = CustomerPasswordChangeForm(request.user)

    return render(request, 'shop/customer_change_password.html', {'form': form})

@login_required
def customer_orders(request):
    if Customer:
        try:
            # Try to find customer by email since there's no user field
            customer = Customer.objects.filter(email=request.user.email).first()
            if customer:
                # Customer model exists but Order model is linked to User, not Customer
                orders = Order.objects.filter(user=request.user).order_by('-created_at')
            else:
                orders = Order.objects.filter(user=request.user).order_by('-created_at')

            paginator = Paginator(orders, 10)
            page_number = request.GET.get('page')
            page_obj = paginator.get_page(page_number)

            return render(request, 'shop/customer_orders.html', {
                'orders': page_obj,
                'customer': customer
            })
        except Exception:
            # Handle any other exceptions
            orders = Order.objects.filter(user=request.user).order_by('-created_at')
            paginator = Paginator(orders, 10)
            page_number = request.GET.get('page')
            page_obj = paginator.get_page(page_number)

            return render(request, 'shop/customer_orders.html', {
                'orders': page_obj,
                'customer': None
            })
    else:
        # Use user orders directly if Customer model doesn't exist
        orders = Order.objects.filter(user=request.user).order_by('-created_at')
        paginator = Paginator(orders, 10)
        page_number = request.GET.get('page')
        page_obj = paginator.get_page(page_number)

        return render(request, 'shop/customer_orders.html', {
            'orders': page_obj,
            'customer': None
        })

@csrf_exempt
def check_email(request):
    """
    Check if an email exists in the system for modern authentication flow.
    """
    if request.method == 'POST':
        try:
            data = json.loads(request.body)
            email = data.get('email', '').strip().lower()

            if not email:
                return JsonResponse({'exists': False, 'error': 'Email is required'})

            # Check if user exists with this email
            user_exists = User.objects.filter(email__iexact=email).exists()

            return JsonResponse({'exists': user_exists})

        except json.JSONDecodeError:
            return JsonResponse({'exists': False, 'error': 'Invalid JSON'})
        except Exception as e:
            return JsonResponse({'exists': False, 'error': str(e)})

    return JsonResponse({'exists': False, 'error': 'Invalid request method'})


def payment_retry(request, order_id):
    """
    Handle payment retry for failed payments.
    """
    order = get_object_or_404(Order, id=order_id)
    
    # Ensure user can retry this payment
    if request.user.is_authenticated and order.user != request.user:
        messages.error(request, "Unauthorized access.")
        return redirect('shop:product_list')
    elif not request.user.is_authenticated and not order.guest_email:
        messages.error(request, "Unauthorized access.")
        return redirect('shop:product_list')

    if request.method == "POST":
        payment_method = request.POST.get('payment_method', 'mpesa')
        
        if payment_method == 'mpesa':
            phone_number = request.POST.get('phone_number')
            shop = Shop.objects.first()
            
            if not shop:
                messages.error(request, "Payment configuration is missing.")
                return redirect('shop:payment_retry', order_id=order.id)

            mpesa = MpesaSTKPush(shop)
            try:
                response = mpesa.initiate_stk_push(phone_number, order.total_price, f"Order #{order.id}")
                if response.get("ResponseCode") == "0":
                    order.mpesa_payment_status = 'Pending'
                    order.save()
                    messages.success(request, "STK Push sent. Please complete the payment on your phone.")
                    return redirect('shop:payment_status', order_id=order.id)
                else:
                    error_msg = response.get('errorMessage', 'Payment initiation failed')
                    messages.error(request, f"Payment failed: {error_msg}")
            except Exception as e:
                logging.error(f"STK Push retry failed for Order #{order.id}: {e}")
                messages.error(request, "Payment processing error. Please try again.")
        
        elif payment_method == 'card':
            return redirect('shop:card_payment', order_id=order.id)

    return render(request, 'shop/payment_retry.html', {
        'order': order,
    })


def payment_status(request, order_id):
    """
    Display payment status and allow retry if needed.
    """
    order = get_object_or_404(Order, id=order_id)
    
    # Check if user can view this order
    if request.user.is_authenticated and order.user != request.user:
        messages.error(request, "Unauthorized access.")
        return redirect('shop:product_list')
    elif not request.user.is_authenticated and not order.guest_email:
        messages.error(request, "Unauthorized access.")
        return redirect('shop:product_list')

    return render(request, 'shop/payment_status.html', {
        'order': order,
    })


def card_payment(request, order_id):
    """
    Handle card payment with YellowCard API.
    """
    if not request.user.is_authenticated:
        messages.error(request, "Please log in to use card payment.")
        return redirect('shop:customer_login')
        
    order = get_object_or_404(Order, id=order_id, user=request.user)
    
    if request.method == "POST":
        try:
            # YellowCard API integration
            import requests
            
            yellowcard_api_url = "https://api.yellowcard.io/v1/payments"
            api_key = "your_yellowcard_api_key"  # Store in settings
            
            payload = {
                "amount": float(order.total_price),
                "currency": "KES",
                "reference": f"order_{order.id}",
                "customer": {
                    "email": request.user.email,
                    "name": f"{request.user.first_name} {request.user.last_name}",
                },
                "card": {
                    "number": request.POST.get('card_number'),
                    "expiry_month": request.POST.get('expiry_month'),
                    "expiry_year": request.POST.get('expiry_year'),
                    "cvv": request.POST.get('cvv'),
                },
                "callback_url": request.build_absolute_uri(f'/shop/card-payment-callback/{order.id}/'),
            }
            
            headers = {
                "Authorization": f"Bearer {api_key}",
                "Content-Type": "application/json",
            }
            
            response = requests.post(yellowcard_api_url, json=payload, headers=headers)
            
            if response.status_code == 200:
                result = response.json()
                if result.get('status') == 'success':
                    order.mpesa_payment_status = 'Paid'
                    order.status = 'Processing'
                    order.save()
                    messages.success(request, "Card payment successful!")
                    return redirect('shop:order_confirmation', order_id=order.id)
                else:
                    messages.error(request, f"Card payment failed: {result.get('message', 'Unknown error')}")
            else:
                messages.error(request, "Card payment processing failed. Please try again.")
                
        except Exception as e:
            logging.error(f"Card payment failed for Order #{order.id}: {e}")
            messages.error(request, "An error occurred while processing your card payment.")
            
        return redirect('shop:payment_retry', order_id=order.id)

    return render(request, 'shop/card_payment.html', {
        'order': order,
    })


@csrf_exempt
def card_payment_callback(request, order_id):
    """
    Handle YellowCard payment callback.
    """
    if request.method == "POST":
        try:
            data = json.loads(request.body)
            order = Order.objects.get(id=order_id)
            
            if data.get('status') == 'successful':
                order.mpesa_payment_status = 'Paid'
                order.status = 'Processing'
                order.save()
                logging.info(f"Card payment successful for Order #{order.id}")
                return JsonResponse({"status": "success"})
            else:
                order.mpesa_payment_status = 'Failed'
                order.save()
                logging.warning(f"Card payment failed for Order #{order.id}")
                return JsonResponse({"status": "failed"})
                
        except Exception as e:
            logging.error(f"Error processing card payment callback: {e}")
            return JsonResponse({"status": "error"})
    
    return JsonResponse({"status": "error", "message": "Invalid request method"})
