from rest_framework.views import APIView
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework import status
from .models import ProductMaster, PackageMaster
from .serializers import ProductMasterSerializer
from django.db.models import Q
from django.db import connection
from django.db import transaction
from django.http import JsonResponse
from django.core.paginator import Paginator
from rest_framework import exceptions


class ProductListView(APIView):
    """
    A POST API to fetch all products or a specific product based on the given product_id.
    If product_id is provided, fetch that product; otherwise, fetch all products.
    """

    def post(self, request):
        product_id = request.data.get('product_id')
        packaging = request.data.get('packaging')
        try:
            if product_id:
                # Fetch a specific product by product_id
                try:
                    product = ProductMaster.objects.get(Id=product_id)
                    serializer = ProductMasterSerializer(product)
                    response_data = {
                        "status_code": 200,
                        "status": "success",
                        "message": "Product fetched successfully",
                        "data": serializer.data
                    }
                except ProductMaster.DoesNotExist:
                    return Response(
                        {
                            "status_code": 404,
                            "status": "error",
                            "message": f"Product with ID {product_id} not found",
                            "data": None
                        },
                        status=status.HTTP_404_NOT_FOUND
                    )
            else:
                # Fetch all products if product_id is not provided
                products = ProductMaster.objects.filter(IsDeleted=False)
                if packaging:
                    products = products.filter(Packaging=packaging)
                serializer = ProductMasterSerializer(products, many=True)
                response_data = {
                    "status_code": 200,
                    "status": "success",
                    "message": "Products fetched successfully",
                    "data": serializer.data
                }

            return Response(response_data, status=status.HTTP_200_OK)

        except Exception as e:
            return Response(
                {
                    "status_code": 500,
                    "status": "error",
                    "message": f"An internal error occurred: {str(e)}",
                    "data": None
                },
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class ProductSearchView(APIView):
    def post(self, request, *args, **kwargs):
        # Extract search query from request
        search_query = request.data.get('search_query', None)
        if not search_query:
            return Response({
                "status": "error",
                "message": "Search parameter is required"
            }, status=status.HTTP_400_BAD_REQUEST)

        products = ProductMaster.objects.filter(
            Q(IsDeleted=False) & (
                    Q(NickName__icontains=search_query) |
                    Q(FullName__icontains=search_query) |
                    Q(ArticleCode__icontains=search_query)
            )
        )

        serializer = ProductMasterSerializer(products, many=True)
        serialized_data = serializer.data
        return Response({
            "status": "success",
            "status_code": status.HTTP_200_OK,
            "message": "Products fetched successfully",
            "data": serialized_data
        }, status=status.HTTP_200_OK)


class AlternateProductView(APIView):
    def post(self, request, *args, **kwargs):
        # Extract search query from request
        product_id = request.data.get('product_id', None)
        if not product_id:
            return Response({
                "status": "error",
                "message": "product_id is required"
            }, status=status.HTTP_400_BAD_REQUEST)
        alternate_article_code = ProductMaster.objects.filter(Id=product_id).values_list('AlternateArticleCode',
                                                                                         flat=True).first()
        product_details = ProductMaster.objects.filter(ArticleCode=alternate_article_code).values_list('Id',
                                                                                                       'NickName').first()
        if product_id:
            response_data = {
                "product_id": product_details[0],
                "alternate_article_code": alternate_article_code,
                "alternate_product_name": product_details[1]
            }
            return Response({
                "status": "success",
                "status_code": status.HTTP_200_OK,
                "message": "Products fetched successfully",
                "data": response_data
            }, status=status.HTTP_200_OK)
        else:
            return Response(
                {
                    "status_code": 404,
                    "status": "error",
                    "message": f"Product with articlecode {article_code} not found",
                    "data": None
                },
                status=status.HTTP_404_NOT_FOUND
            )

    
class ProductMasterERPView(APIView):

    @transaction.atomic
    def post(self, request):
        """
        API to create or update address details from ERP.
        """
        data = request.data.copy() 
        product_id = data.get('product_id')
        package_detail = data.pop('package_detail', None)
        data['ProductName'] = data['FullName']

        if product_id:
            # Update existing product
            try:
                product = ProductMaster.objects.get(Id=product_id, IsDeleted=False)
                serializer = ProductMasterSerializer(
                    instance=product, data=data, partial=True)
            except ProductMaster.DoesNotExist:
                raise exceptions.NotFound(detail="address with the given ID not found.")
        else:
            # Create a new product
            serializer = ProductMasterSerializer(data=data)

        # Validate serializer
        if not serializer.is_valid():
            return Response({
                "status_code": 400,
                "status": "error",
                "message": f"{serializer.errors}",
                "data": None
            }, status=status.HTTP_400_BAD_REQUEST)

        # Save the product
        product = serializer.save()

        if package_detail:
            PackageMaster.objects.update_or_create(
                product=product,
                defaults={
                    "packaged_product": product.ProductName, 
                    "article_code":product.ArticleCode,
                    "kg_per_packaging": package_detail.get("kg_per_packaging"),
                    "pack_tare_weight": package_detail.get("pack_tare_weight"),
                    "dimension": package_detail.get("dimension"),
                    "nos_per_pallet": package_detail.get("nos_per_pallet"),
                    "pallet_weight": package_detail.get("pallet_weight"),
                }
            )

        return  Response(
                {
                    'status_code': status.HTTP_200_OK,
                    'status': "success",
                    'message': 'Product saved successfully',
                    'data': serializer.data,
                },
                status=status.HTTP_200_OK
            )
    
    def get(self, request):
            """API to get infra by department"""
            product_id = request.GET.get('product_id', None)
            page_size = request.GET.get('page_size', 20)
            page_number = request.GET.get('page_no', 1)

            print(product_id)

            if product_id:
                try:
                    product = ProductMaster.objects.get(Id=product_id, IsDeleted=False)
                except ProductMaster.DoesNotExist:
                    raise exceptions.NotFound(detail="Company with the given ID not found.")

                serializer = ProductMasterSerializer(instance=product)
                result = serializer.data
            else:
                product = ProductMaster.objects.filter(IsDeleted=False)

                # Apply pagination
                paginator = Paginator(product, page_size)
                page_obj = paginator.get_page(page_number)

                serializer = ProductMasterSerializer(page_obj, many=True)

                result = {
                    "total_records": paginator.count,
                    "total_pages": paginator.num_pages,
                    "current_page": page_obj.number,
                    "data": serializer.data
                }

            response_data = {
                "status": "success",
                "status_code": status.HTTP_200_OK,
                "message": "Data fetched successfully",
                'data': result}

            return JsonResponse(response_data, status=status.HTTP_200_OK)

    @transaction.atomic
    def delete(self, request):
        """Function to delete Customer """
        product_id = request.GET.get('product_id')

        try:
            product = ProductMaster.objects.get(Id=product_id, IsDeleted=False)
            product.IsDeleted=True
            product.save()
            response = {
                "status": "success",
                "status_code": status.HTTP_200_OK,
                "message": "Product Deleted Successfully",
                'data': "Product Deleted Successfully"}
        except:
            response = {
                "status": "error",
                "status_code": status.HTTP_301_MOVED_PERMANENTLY,
                "message": "Something went wrong",
                'data': "Something went wrong"}
        return JsonResponse(response, status=status.HTTP_200_OK)

