from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from django.shortcuts import get_object_or_404
from django.db import transaction

from common.pagination.custom_pagination import CustomPageNumberPagination
from jobs_company.models.jobs import Jobs, JobReview
from jobs_company.serializers.jobs_serializer import JobsSerializer
from jobs_company.serializers.job_review_serializer import JobReviewSerializer
from notification.models import Notification


class JobFlagAPIView(APIView):
    permission_classes = [IsAuthenticated]
    
    @swagger_auto_schema(
        operation_description="Flag job and create a flagged review",
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            properties={
                'message': openapi.Schema(
                    type=openapi.TYPE_STRING,
                    description='Reason for flagging the job'
                )
            },
            required=['message']
        )
    )
    def post(self, request, pk):
        job = get_object_or_404(Jobs, pk=pk)
        
        # if request.user.role != 'admin' and job.created_by != request.user:
        #     return Response(
        #         {"error": "You don't have permission to flag this job"}, 
        #         status=status.HTTP_403_FORBIDDEN
        #     )
        
        message = request.data.get('message', '').strip()
        if not message:
            return Response(
                {"error": "Message is required when flagging a job"}, 
                status=status.HTTP_400_BAD_REQUEST
            )
        
        review_star = 1
        
        with transaction.atomic():
            job.is_flag = True
            job.save(update_fields=['is_flag'])
            
            # Create flagged review
            flagged_review = JobReview.objects.create(
                job=job,
                review_star=review_star,
                message=message,
                is_flagged_review=True,
                created_by=request.user
            )

            Notification.objects.create(
                notification_type='job_report',
                job_report_id=job.id,
                title=f'Job Flagged: {job.title if hasattr(job, "title") else "Job"} (ID: {job.id})',
                message=message,
                status='unread'
            )
        
        return Response({
            "success": "Job flagged and review created successfully",
            "job_id": job.id,
            "is_flag": job.is_flag,
            "is_active": job.is_active,
            "review_id": flagged_review.id,
            "message": flagged_review.message
        }, status=status.HTTP_200_OK)


class JobUnflagAPIView(APIView):
    permission_classes = [IsAuthenticated]
    
    @swagger_auto_schema(
        operation_description="Unflag job and set active"
    )
    def post(self, request, pk):
        """Set is_flag to False for a specific job"""
        job = get_object_or_404(Jobs, pk=pk)
        
        if request.user.role != 'admin' and job.created_by != request.user:
            return Response(
                {"error": "You don't have permission to unflag this job"}, 
                status=status.HTTP_403_FORBIDDEN
            )
        
        job.is_flag = False
        job.is_active = True
        job.save(update_fields=['is_flag', 'is_active'])
        
        return Response({
            "success": "Job unflagged successfully",
            "job_id": job.id,
            "is_flag": job.is_flag,
            "is_active": job.is_active
        }, status=status.HTTP_200_OK)


class JobFlaggedListAPIView(APIView):
    permission_classes = [IsAuthenticated]
    
    @swagger_auto_schema(
        operation_description="Get paginated list of flagged jobs with flagged reviews",
        manual_parameters=[
            openapi.Parameter('page', openapi.IN_QUERY, description="Page number", type=openapi.TYPE_INTEGER),
            openapi.Parameter('page_size', openapi.IN_QUERY, description="Number of items per page", type=openapi.TYPE_INTEGER),
            openapi.Parameter('company', openapi.IN_QUERY, description="Filter by company ID", type=openapi.TYPE_INTEGER),
            openapi.Parameter('category', openapi.IN_QUERY, description="Filter by category ID", type=openapi.TYPE_INTEGER),
            openapi.Parameter('type', openapi.IN_QUERY, description="Filter by job type", type=openapi.TYPE_INTEGER),
            openapi.Parameter('location', openapi.IN_QUERY, description="Filter by location", type=openapi.TYPE_STRING),
            openapi.Parameter('include_reviews', openapi.IN_QUERY, description="Include flagged reviews", type=openapi.TYPE_BOOLEAN),
        ]
    )
    def get(self, request):
        """Get paginated list of flagged jobs"""
        jobs = Jobs.objects.filter(is_flag=True).select_related(
            'company', 'category', 'created_by'
        ).order_by('-created_at')
        
        user = request.user
        if user.role != 'admin':
            jobs = jobs.filter(created_by=user)
        
        # Apply filters
        company_id = request.query_params.get('company')
        category_id = request.query_params.get('category')
        job_type = request.query_params.get('type')
        location = request.query_params.get('location')
        include_reviews = request.query_params.get('include_reviews', 'false').lower() == 'true'
        
        if company_id:
            jobs = jobs.filter(company_id=company_id)
        if category_id:
            jobs = jobs.filter(category_id=category_id)
        if job_type:
            jobs = jobs.filter(type=job_type)
        if location:
            jobs = jobs.filter(location__icontains=location)
        
        # Pagination
        paginator = CustomPageNumberPagination()
        result_page = paginator.paginate_queryset(jobs, request)
        serializer = JobsSerializer(result_page, many=True, context={'request': request})
        
        response_data = paginator.get_paginated_response(serializer.data)
        
        # Include flagged reviews if requested
        if include_reviews:
            for job_data in response_data.data['results']:
                job_id = job_data['id']
                flagged_reviews = JobReview.objects.filter(
                    job_id=job_id,
                    is_flagged_review=True,
                    is_active=True
                ).select_related('created_by')
                
                reviews_serializer = JobReviewSerializer(flagged_reviews, many=True, context={'request': request})
                job_data['flagged_reviews'] = reviews_serializer.data
                job_data['flagged_reviews_count'] = flagged_reviews.count()
        
        return response_data