from django.shortcuts import render, get_object_or_404
from rest_framework import generics, permissions
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework import status
from .models import *
from product.models import *
from .serializers import *
from django.db import transaction
from suscription.custom_pagination import CustomPagination
from Help_Support.decorators import cache_response
from rest_framework.exceptions import ValidationError
from setting.views import *
from decimal import Decimal
from rest_framework.views import APIView
from rest_framework import viewsets
from rest_framework.generics import UpdateAPIView
from rest_framework.decorators import action
import json
import hashlib
import hmac
from rest_framework.permissions import AllowAny


class CartListCreateView(generics.ListCreateAPIView):
    serializer_class = CartSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        return Cart.objects.filter(buyer=self.request.user).order_by('-id')
    
    @cache_response()
    def list(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)

        cart_items = serializer.data if isinstance(serializer.data, list) else []

        subtotal = sum(float(item.get('product_price', 0)) * int(item.get('quantity', 1)) for item in cart_items)
        tax_percentage = float(get_setting_value('tax', 10))  
        platform_fee = float(get_setting_value('platform_fee', 10))  
        shipping_fee_percentage = float(get_setting_value('shipping_fee', 10))  
        free_shipping_amount = float(get_setting_value('free_shipping_amount', 500))  

        # Calculate tax
        total_tax = round((subtotal * tax_percentage) / 100, 2)

        # Calculate shipping fee (if subtotal exceeds free shipping amount)
        shipping_fee = round((subtotal * shipping_fee_percentage) / 100, 2) if subtotal > free_shipping_amount else 0

        # Calculate total price
        total_price = subtotal + total_tax
        total_amount = total_price + platform_fee + shipping_fee

        total_products = len(cart_items)

        total_amount = round(total_amount, 2) if total_products else 0.00

        return Response({
            "status": True,
            "message": "Cart items fetch successfully.",
            "data": {
                "products": cart_items,
                "total_products": total_products,  
                "summary": {
                    "item_subtotal": round(subtotal, 2),
                    "tax_percentage": tax_percentage,
                    "tax": total_tax,
                    "platform_fee": platform_fee,
                    "free_shipping_amount": free_shipping_amount,
                    "shipping_fee_percentage": shipping_fee_percentage,
                    "shipping_fee": shipping_fee,
                    "total_amount": round(total_amount, 2)
                }
            }
        }, status=status.HTTP_200_OK)
    
    def perform_create(self, serializer):
        buyer = self.request.user
        product = serializer.validated_data.get('product')
        quantity = serializer.validated_data.get('quantity')

        product_instance = Product.objects.filter(id=product.id).first()

        if not product_instance:
            raise ValidationError({"status": False, "message": "Product not found."})

        # if product_instance.quantity < quantity:
        #     raise ValidationError({"status": False, "message": "Insufficient quantity available."})

        existing_cart_item = Cart.objects.filter(buyer=buyer, product=product).first()

        if existing_cart_item:
            raise ValidationError({"status": False, "message": "This product has already been added."})

            # new_quantity = existing_cart_item.quantity + quantity
           
            # if product_instance.quantity < new_quantity:
            #     raise ValidationError({"status": False, "message": "Insufficient quantity available."})

            # existing_cart_item.quantity = new_quantity
            # existing_cart_item.total = existing_cart_item.product_price * new_quantity
            # existing_cart_item.save()
            # serializer.instance = existing_cart_item  
            # self.cart_updated = True
        else:
            cart_item =serializer.save(buyer=buyer)
            self.cart_updated = False
            

    def create(self, request, *args, **kwargs):
        self.cart_updated = False  # Initialize before calling `perform_create`
        response = super().create(request, *args, **kwargs)

        message = (
            "Product updated in cart successfully." if self.cart_updated
            else "Product added to cart successfully."
        )

        return Response(
            {"status": True, "message": message, "data": response.data},
            status=response.status_code
        )


class CartDetailView(generics.RetrieveUpdateDestroyAPIView):
    serializer_class = CartSerializer
    permission_classes = [IsAuthenticated]

    def get_object(self):
        return get_object_or_404(Cart, id=self.kwargs['pk'], buyer=self.request.user)
    
    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return Response(
            {
                "status": True,
                "message": "Cart item retrieved successfully.",
                "data": serializer.data
            },
            status=status.HTTP_200_OK
        )


    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()

        if instance.deleted_at:
            return Response(
                {"status": False, "message": "Cart item not found."},
                status=status.HTTP_404_NOT_FOUND
            )

        instance.soft_delete()  
        return Response(
            {"status": True, "message": "Product removed from cart."},
            status=status.HTTP_200_OK
        )


class CreateOrderAPIView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request):
        data = request.data
        transaction_id = data.get('transaction_id',None)

        serializer = OrderSerializer(data=request.data, context={"request": request})

        
        if not serializer.is_valid():
            return Response({"status": False, "errors": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)

        validated_data = serializer.validated_data
        buyer_id = request.user.id

         # Validate cart existence
        if not Cart.objects.filter(buyer=buyer_id).exists():
            return Response(
                {"status": False, "message": "No items found in the cart."},
                status=status.HTTP_400_BAD_REQUEST
            )

        try:
            
            order = serializer.save()

            transaction_id = data.get('transaction_id',None)
          
            transaction_data = {
                "buyer":buyer_id,
                "transaction_id": transaction_id,
                "order_purchase": order.id,
                "payment_status": data.get("payment_status", OrderTransaction.PaymentStatus.PENDING),
                # "payment_method": data.get("payment_method",OrderTransaction.PaymentMethod.CREDIT_CARD),
                "amount": order.grand_total,
            }

            transaction_serializer = OrderTransactionSerializer(data=transaction_data)
            if transaction_serializer.is_valid():
                transaction_serializer.save()
            else:
                return Response(
                    {"status": False, "errors": transaction_serializer.errors},
                    status=status.HTTP_400_BAD_REQUEST
                )

            return Response(
                {"status": True, "message": "Order created successfully.", "order_id": order.id},
                status=status.HTTP_201_CREATED
            )
            

        except Exception as e:
            return Response(
                {"status": False, "message": f"Order creation failed: {str(e)}"},
                status=status.HTTP_400_BAD_REQUEST
            )


class BuyerOrderListAPIView(generics.ListAPIView):
    permission_classes = [IsAuthenticated]
    serializer_class = OrderItemSerializer
    pagination_class = CustomPagination

    def get_queryset(self):
        # queryset = OrderItem.objects.filter(buyer=self.request.user).order_by("-created_at")
        queryset = OrderItem.objects.filter(
            buyer=self.request.user,
            # order_purchase__transactions__payment_status=OrderTransaction.PaymentStatus.SUCCESS
           order_purchase__payment_status=OrderPurchase.PaymentStatus.SUCCESS
        ).prefetch_related("order_purchase__transactions").order_by("-created_at")

        order_id = self.request.query_params.get('order_id')
        if order_id is not None:
            queryset = queryset.filter(id=order_id)

        return queryset

    def get_serializer_class(self):
        if self.request.query_params.get('order_id') is not None:
            return OrderDetailsSerializer
        return self.serializer_class

    def list(self, request, *args, **kwargs):
        queryset = self.get_queryset()

        page = self.paginate_queryset(queryset)  
        if page is not None:
            serializer = self.get_serializer(page, many=True, context={'request': request})
            paginated_response = self.get_paginated_response(serializer.data)  
            
            return Response({
                "status": True,
                "message": "Order listing retrieved successfully",
                "data": paginated_response.data 
            })

        serializer = self.get_serializer(queryset, many=True, context={'request': request})
        return Response({
            "status": True,
            "message": "Order listing retrieved successfully",
            "data": serializer.data
        })
      
class OrderStatusUpdateView(UpdateAPIView):
    queryset = OrderItem.objects.all()
    serializer_class = OrderItemFlagUpdateSerializer
    permission_classes = [IsAuthenticated]

    def partial_update(self, request, *args, **kwargs):
        try:
            order_id = kwargs.get("pk")
            
            order_item = OrderItem.objects.get(id=order_id)
            is_arrival = request.data.get("is_arrival")
            is_delivered = request.data.get("is_delivered")
            is_received = request.data.get("is_received")

            if is_arrival is None and is_delivered is None and is_received is None:
                return Response({"status":False,"message": "At least one flag must be provided"}, status=status.HTTP_400_BAD_REQUEST)

            # if is_received and not (is_delivered or order_item.is_delivered):
            #     return Response({"status":False,"message": "Order cannot be received before it is delivered"}, status=status.HTTP_400_BAD_REQUEST)
            if request.user.is_vendor : 
                if is_arrival is not None:
                    order_item.is_arrival = is_arrival
                    order_item.delivery_status = OrderItem.DeliveryStatus.SHIPPED
                if is_delivered is not None:
                    order_item.is_delivered = is_delivered
            else :
                if is_received is not None  :
                    order_item.is_received = is_received
                    order_item.is_delivered = True
                    order_item.delivery_date = now().date()
            
            if order_item.is_delivered and order_item.is_received:
                order_item.delivery_status = OrderItem.DeliveryStatus.DELIVERED
                # order_item.delivery_date = now().date()

            order_item.save()
            

            return Response({
                "status":True,
                "message": "Flags updated successfully",
                "data": OrderItemFlagUpdateSerializer(order_item).data
            }, status=status.HTTP_200_OK)

        except OrderItem.DoesNotExist:
            return Response({"status":False,"message": "Order item not found"}, status=status.HTTP_404_NOT_FOUND)

        except Exception as e:
            return Response({"status":False,"message": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        
class OrderTransactionsAPIView(generics.ListAPIView):
    permission_classes = [IsAuthenticated]
    serializer_class = TransactionDetailsSerializer
    pagination_class = CustomPagination

    def get_queryset(self):
        queryset = OrderTransaction.objects.filter(buyer=self.request.user).order_by("-created_at")
        return queryset

    def list(self, request, *args, **kwargs):
        queryset = self.get_queryset()

        page = self.paginate_queryset(queryset)  
        if page is not None:
            serializer = self.get_serializer(page, many=True, context={'request': request})
            paginated_response = self.get_paginated_response(serializer.data)  
            
            return Response({
                "status": True,
                "message": "Order transactions fetch successfully",
                "data": paginated_response.data 
            })

        serializer = self.get_serializer(queryset, many=True, context={'request': request})
        return Response({
            "status": True,
            "message": "Order transactions fetch successfully",
            "data": serializer.data
        })
    
class FlutterwaveWebhookViewSet(viewsets.ViewSet):
    permission_classes = [AllowAny]  

    @action(detail=False, methods=['post'], url_path='flutterwave')
    def handle_webhook(self, request):
        try:
            payload = json.loads(request.body)
            print('Received Flutterwave webhook payload:', payload)

            transaction_id = payload.get("id") 
            # transaction_id = payload.get("txRef") 

            if not transaction_id:
                return Response({"status": False, "error": "Missing transaction ID"}, status=400)

            order_transaction = OrderTransaction.objects.filter(transaction_id=transaction_id).first()
            if not order_transaction:
                return Response({"status": False, "error": "Transaction not found"}, status=404)

            payment_method = payload.get('event.type')

            # Map payment method based on event type
            payment_method = "mobile_money" if payment_method == "MOBILEMONEYTZ_TRANSACTION" else "credit_card"

            if payload.get("status", "pending") == order_transaction.payment_status:
                return Response({"status": False, "error": "Transaction status is already updated."}, status=400)

            order_transaction.payment_status = payload.get("status", "pending")
            order_transaction.payment_method = payment_method  
            order_transaction.save()

            order = OrderPurchase.objects.filter(id=order_transaction.order_purchase.id).first()
            if order:
                order.payment_status = payload.get("status", "pending")
                order.save()

            print('Updated transaction:', order_transaction.transaction_id, 'Status:', order_transaction.payment_status)

            return Response({"status": True, "message": "Transaction status updated"}, status=200)

        except json.JSONDecodeError:
            return Response({"status": False, "error": "Invalid JSON payload"}, status=400)
        except Exception as e:
            print('Error processing webhook:', str(e))
            return Response({"status": False, "error": str(e)}, status=500)