from rest_framework import viewsets, status, filters
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import AllowAny, IsAdminUser
from rest_framework.parsers import MultiPartParser, FormParser, JSONParser
from django_filters.rest_framework import DjangoFilterBackend
from django.shortcuts import get_object_or_404
import logging

from .models import JobPosition, JobApplication
from .serializers import (
    JobPositionListSerializer,
    JobPositionDetailSerializer,
    JobApplicationSerializer,
    JobApplicationListSerializer
)
from .email_service import CareerEmailService

logger = logging.getLogger(__name__)


class JobPositionViewSet(viewsets.ReadOnlyModelViewSet):
    """
    ViewSet for job positions
    GET /api/career/jobs/ - List all active job positions
    GET /api/career/jobs/{slug}/ - Get job position by slug
    """
    
    queryset = JobPosition.objects.filter(status='active')
    permission_classes = [AllowAny]
    lookup_field = 'slug'
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ['department', 'employment_type', 'location_type', 'featured']
    search_fields = ['title', 'department', 'location', 'short_description']
    ordering_fields = ['posted_date', 'priority', 'title']
    ordering = ['-priority', '-posted_date']
    
    def get_serializer_class(self):
        if self.action == 'retrieve':
            return JobPositionDetailSerializer
        return JobPositionListSerializer
    
    @action(detail=False, methods=['get'])
    def featured(self, request):
        """Get featured job positions"""
        featured_jobs = self.queryset.filter(featured=True)
        serializer = self.get_serializer(featured_jobs, many=True)
        return Response(serializer.data)
    
    @action(detail=True, methods=['get'])
    def applications_count(self, request, slug=None):
        """Get number of applications for a job"""
        job = self.get_object()
        count = job.applications.count()
        return Response({'count': count})


class JobApplicationViewSet(viewsets.ModelViewSet):
    """
    ViewSet for job applications
    POST /api/career/applications/ - Submit a job application
    GET /api/career/applications/ - List applications (admin only)
    """
    
    queryset = JobApplication.objects.all()
    serializer_class = JobApplicationSerializer
    parser_classes = [MultiPartParser, FormParser, JSONParser]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ['job', 'status']
    search_fields = ['first_name', 'last_name', 'email', 'job__title']
    ordering_fields = ['applied_date', 'status']
    ordering = ['-applied_date']
    
    def get_permissions(self):
        """
        Allow anyone to create (submit) applications
        Only admins can list/view/update/delete applications
        """
        if self.action == 'create':
            return [AllowAny()]
        return [IsAdminUser()]
    
    def get_serializer_class(self):
        if self.action == 'list':
            return JobApplicationListSerializer
        return JobApplicationSerializer
    
    def create(self, request, *args, **kwargs):
        """Submit a job application"""
        try:
            # Build data dict - Django QueryDict returns lists, so we need to get first item
            data = {}
            
            # Get POST data (text fields)
            for key in request.POST.keys():
                value = request.POST.get(key)
                data[key] = value
            
            # Get FILES data
            for key in request.FILES.keys():
                file_obj = request.FILES.get(key)
                data[key] = file_obj
                
        except Exception as e:
            logger.error(f"Error parsing request: {str(e)}")
            return Response(
                {'error': 'Error parsing request data'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        serializer = self.get_serializer(data=data)
        
        if not serializer.is_valid():
            logger.error(f"Validation errors: {serializer.errors}")
            return Response(
                {'error': 'Validation failed', 'details': serializer.errors},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        try:
            # Save the application
            application = serializer.save()
            logger.info(f"New job application received: {application.full_name} for {application.job.title}")
            
            # Try to send email notifications (non-blocking - don't fail if emails fail)
            try:
                email_service = CareerEmailService()
                email_service.send_application_confirmation(application)
                email_service.send_application_notification_to_admin(application)
                logger.info(f"Email notifications sent successfully for application {application.id}")
            except Exception as email_error:
                # Log email error but don't fail the application submission
                logger.warning(f"Failed to send email notifications for application {application.id}: {str(email_error)}")
            
            return Response(
                {
                    'message': 'Application submitted successfully',
                    'data': serializer.data
                },
                status=status.HTTP_201_CREATED
            )
            
        except Exception as e:
            logger.error(f"Error submitting job application: {str(e)}", exc_info=True)
            return Response(
                {'error': 'Failed to submit application. Please try again.'},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=True, methods=['post'])
    def update_status(self, request, pk=None):
        """Update application status"""
        application = self.get_object()
        new_status = request.data.get('status')
        
        if new_status not in dict(JobApplication.STATUS_CHOICES):
            return Response(
                {'error': 'Invalid status'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        application.status = new_status
        application.save()
        
        serializer = self.get_serializer(application)
        return Response(serializer.data)

