from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from master.models import Master, Banner
from master.serializers import MasterSerializer, BannerSerializer, BannerStatusSerializer, BannerImageTypeUpdateSerializer, AdminRejectUserSerializer
from master.authentication import IsActiveAdmin
from user.models import User

import boto3
import mimetypes
from django.conf import settings
from rest_framework.parsers import MultiPartParser, FormParser
from uuid import uuid4
import uuid

from rest_framework.permissions import IsAuthenticated
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from django.db.models import Q



# Helper function to apply search
def apply_search(queryset, search_term, fields):
    q = Q()
    for field in fields:
        q |= Q(**{f"{field}__icontains": search_term})
    return queryset.filter(q)

class MasterDetailView(APIView):
    permission_classes = [IsAuthenticated, IsActiveAdmin]
    
    def get(self, request, type_id):
        master_entries = Master.objects.filter(type=type_id)

        search = request.query_params.get("search")
        if search:
            master_entries = apply_search(master_entries, search, ['name'])

        serializer = MasterSerializer(master_entries, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

class MastertoUserView(APIView):
    def get(self, request, type_id):
        master_entries = Master.objects.filter(type=type_id, status=True)

        search = request.query_params.get("search")
        if search:
            master_entries = apply_search(master_entries, search, ['name'])

        serializer = MasterSerializer(master_entries, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)
    

class BannerView(APIView):
    permission_classes = [IsAuthenticated]
    parser_classes = [MultiPartParser]

    @swagger_auto_schema(
        operation_description="Get all banners",
        responses={200: BannerSerializer(many=True)}
    )
    def get(self, request):
        banners = Banner.objects.all().order_by('-created_at')
        serializer = BannerSerializer(banners, many=True)
        return Response({
            "status": "success",
            "data": serializer.data
        }, status=status.HTTP_200_OK)

    def post(self, request):
        image_file = request.FILES.get('image')

        if not image_file:
            return Response({"error": "Image file is required."}, status=status.HTTP_400_BAD_REQUEST)

        # S3 Upload
        try:
            s3 = boto3.client(
                's3',
                region_name='sgp1',
                endpoint_url='https://sgp1.digitaloceanspaces.com',
                aws_access_key_id='NMQAUQUGQAQ4ZE4QNKFN',
                aws_secret_access_key='IbTaeOcuA8Xb9WFclN1vow53a3D6yjyxbwn1Yzvw5nc'
            )

            filename = f"chatapp/banners/{uuid.uuid4()}.{image_file.name.split('.')[-1]}"
            s3.upload_fileobj(
                image_file,
                'foodieninos',
                filename,
                ExtraArgs={'ACL': 'public-read'}
            )

            image_url = f"https://foodieninos.sgp1.cdn.digitaloceanspaces.com/{filename}"

        except Exception as e:
            return Response({"error": f"Image upload failed: {str(e)}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        banner_data = {
            "type": request.data.get("type"),
            "status": request.data.get("status", True),
            "image": image_url
        }

        serializer = BannerSerializer(data=banner_data)
        if serializer.is_valid():
            serializer.save()
            return Response({
                "status": "success",
                "message": "Banner added successfully",
                "data": serializer.data
            }, status=status.HTTP_201_CREATED)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class BannerDetailView(APIView):
    permission_classes = [IsAuthenticated, IsActiveAdmin]
    parser_classes = [MultiPartParser]

    def post(self, request, pk):
        try:
            banner = Banner.objects.get(pk=pk)
        except Banner.DoesNotExist:
            return Response({"error": "Banner not found"}, status=status.HTTP_404_NOT_FOUND)

        update_data = request.data.dict()

        image_file = request.FILES.get('image')
        if image_file:
            try:
                s3 = boto3.client(
                    's3',
                    region_name='sgp1',
                    endpoint_url='https://sgp1.digitaloceanspaces.com',
                    aws_access_key_id='NMQAUQUGQAQ4ZE4QNKFN',
                    aws_secret_access_key='IbTaeOcuA8Xb9WFclN1vow53a3D6yjyxbwn1Yzvw5nc'
                )

                filename = f"chatapp/banners/{uuid.uuid4()}.{image_file.name.split('.')[-1]}"
                s3.upload_fileobj(
                    image_file,
                    'foodieninos',
                    filename,
                    ExtraArgs={'ACL': 'public-read'}
                )

                image_url = f"https://foodieninos.sgp1.cdn.digitaloceanspaces.com/{filename}"
                update_data['image'] = image_url

            except Exception as e:
                return Response({"error": f"Image upload failed: {str(e)}"}, status=500)

        serializer = BannerSerializer(banner, data=update_data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response({
                "status": "success",
                "message": "Banner updated successfully",
                "data": serializer.data
            }, status=status.HTTP_200_OK)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    
class BannerImageTypeUpdateView(APIView):
    permission_classes = [IsAuthenticated, IsActiveAdmin]
    parser_classes = [MultiPartParser]

    def post(self, request, pk):
        try:
            banner = Banner.objects.get(pk=pk)
        except Banner.DoesNotExist:
            return Response({"error": "Banner not found"}, status=status.HTTP_404_NOT_FOUND)

        update_data = {}

        image_file = request.FILES.get('image')
        if image_file:
            try:
                s3 = boto3.client(
                    's3',
                    region_name='sgp1',
                    endpoint_url='https://sgp1.digitaloceanspaces.com',
                    aws_access_key_id='NMQAUQUGQAQ4ZE4QNKFN',
                    aws_secret_access_key='IbTaeOcuA8Xb9WFclN1vow53a3D6yjyxbwn1Yzvw5nc'
                )

                filename = f"chatapp/banners/{uuid.uuid4()}.{image_file.name.split('.')[-1]}"
                s3.upload_fileobj(image_file, 'foodieninos', filename, ExtraArgs={'ACL': 'public-read'})
                image_url = f"https://foodieninos.sgp1.cdn.digitaloceanspaces.com/{filename}"
                update_data['image'] = image_url
            except Exception as e:
                return Response({"error": f"Failed to upload image: {str(e)}"}, status=500)

        banner_type = request.data.get("type")
        if banner_type is not None:
            update_data["type"] = banner_type

        serializer = BannerImageTypeUpdateSerializer(banner, data=update_data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response({
                "status": "success",
                "message": "Banner image updated successfully",
                "data": serializer.data
            }, status=status.HTTP_200_OK)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class AdminRejectUserAPIView(APIView):
    permission_classes = [IsAuthenticated]

    @swagger_auto_schema(request_body=AdminRejectUserSerializer)
    def post(self, request):
        serializer = AdminRejectUserSerializer(data=request.data)
        if not serializer.is_valid():
            return Response({"status": "error", "errors": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)

        user_id = serializer.validated_data["user_id"]
        reject_reason = serializer.validated_data["reject_reason"]

        try:
            user = User.objects.get(id=user_id)
        except User.DoesNotExist:
            return Response({"status": "error", "message": "User not found"}, status=status.HTTP_404_NOT_FOUND)

        user.admin_status = 2
        user.save(update_fields=["admin_status"])

        Master.objects.get_or_create(
            type=6,
            name =user_id,
            defaults={"value1": reject_reason}
        )

        return Response({"status": "success", "message": "User rejected"}, status=status.HTTP_200_OK)