from rest_framework import viewsets, permissions, status, filters, serializers
from rest_framework.decorators import action
from rest_framework.response import Response
from django.db.models import Q
from shop.utils import get_current_wechat_user
from .models import Competition, CompetitionEnrollment, Project, ProjectFile, Score, Comment, ScoreDimension
from .serializers import (
    CompetitionSerializer, CompetitionEnrollmentSerializer, 
    ProjectSerializer, ProjectFileSerializer, 
    ScoreSerializer, CommentSerializer, ScoreDimensionSerializer
)

from rest_framework.pagination import PageNumberPagination

class StandardResultsSetPagination(PageNumberPagination):
    page_size = 10
    page_size_query_param = 'page_size'
    max_page_size = 100

class CompetitionViewSet(viewsets.ReadOnlyModelViewSet):
    """
    比赛视图集
    """
    queryset = Competition.objects.filter(is_active=True).order_by('-created_at')
    serializer_class = CompetitionSerializer
    permission_classes = [permissions.AllowAny]
    pagination_class = StandardResultsSetPagination
    filter_backends = [filters.SearchFilter]
    search_fields = ['title', 'description']

    def get_queryset(self):
        """
        获取比赛查询集，支持根据查询参数进行动态过滤
        """
        queryset = super().get_queryset()
        
        # 状态过滤
        status_param = self.request.query_params.get('status')
        if status_param and status_param != 'all':
            queryset = queryset.filter(status=status_param)
            
        return queryset

    @action(detail=True, methods=['post'], permission_classes=[permissions.AllowAny])
    def enroll(self, request, pk=None):
        """
        报名参加比赛
        """
        competition = self.get_object()
        user = get_current_wechat_user(request)
        if not user:
            return Response({"detail": "未登录"}, status=status.HTTP_401_UNAUTHORIZED)
            
        role = request.data.get('role', 'contestant')
        
        # 检查是否已报名
        if CompetitionEnrollment.objects.filter(competition=competition, user=user).exists():
            return Response({"detail": "您已报名该比赛"}, status=status.HTTP_400_BAD_REQUEST)
            
        enrollment = CompetitionEnrollment.objects.create(
            competition=competition,
            user=user,
            role=role,
            status='pending'  # 默认待审核
        )
        
        return Response(CompetitionEnrollmentSerializer(enrollment).data, status=status.HTTP_201_CREATED)

    @action(detail=True, methods=['get'])
    def my_enrollment(self, request, pk=None):
        """
        获取我的报名信息
        """
        competition = self.get_object()
        user = get_current_wechat_user(request)
        if not user:
            return Response({"detail": "未登录"}, status=status.HTTP_401_UNAUTHORIZED)
            
        try:
            enrollment = CompetitionEnrollment.objects.get(competition=competition, user=user)
            return Response(CompetitionEnrollmentSerializer(enrollment).data)
        except CompetitionEnrollment.DoesNotExist:
            return Response({"detail": "未报名"}, status=status.HTTP_404_NOT_FOUND)

    @action(detail=False, methods=['get'])
    def my_enrollments(self, request):
        """
        获取我的所有报名信息
        """
        user = get_current_wechat_user(request)
        if not user:
            return Response([])
        enrollments = CompetitionEnrollment.objects.filter(user=user)
        return Response(CompetitionEnrollmentSerializer(enrollments, many=True).data)


class ProjectViewSet(viewsets.ModelViewSet):
    """
    参赛项目视图集
    """
    serializer_class = ProjectSerializer
    permission_classes = [permissions.AllowAny]
    pagination_class = StandardResultsSetPagination
    
    def get_queryset(self):
        queryset = Project.objects.all()
        competition_id = self.request.query_params.get('competition')
        if competition_id:
            queryset = queryset.filter(competition_id=competition_id)
            
        contestant_id = self.request.query_params.get('contestant')
        if contestant_id:
            queryset = queryset.filter(contestant_id=contestant_id)
            
        user = get_current_wechat_user(self.request)
        
        # 1. 基础条件：公开可见且已提交的项目
        q = Q(competition__project_visibility='public', status='submitted')
        
        if user:
            # 2. 用户自己的项目（始终可见，包括草稿）
            q |= Q(contestant__user=user)
            
            # 3. 基于角色的可见性
            # 获取用户已通过审核的报名信息
            enrollments = CompetitionEnrollment.objects.filter(user=user, status='approved')
            
            # 获取各角色的比赛ID集合
            judge_comp_ids = set(enrollments.filter(role='judge').values_list('competition_id', flat=True))
            guest_comp_ids = set(enrollments.filter(role='guest').values_list('competition_id', flat=True))
            contestant_comp_ids = set(enrollments.filter(role='contestant').values_list('competition_id', flat=True))
            
            # 'judge' 可见性：仅评委可见
            if judge_comp_ids:
                q |= Q(competition__project_visibility='judge', competition__in=judge_comp_ids, status='submitted')
            
            # 'guest' 可见性：嘉宾及评委可见
            guest_access_ids = judge_comp_ids | guest_comp_ids
            if guest_access_ids:
                q |= Q(competition__project_visibility='guest', competition__in=guest_access_ids, status='submitted')
                
            # 'contestant' 可见性：选手及以上可见（包括评委、嘉宾）
            contestant_access_ids = judge_comp_ids | guest_comp_ids | contestant_comp_ids
            if contestant_access_ids:
                q |= Q(competition__project_visibility='contestant', competition__in=contestant_access_ids, status='submitted')
        
        queryset = queryset.filter(q)
            
        return queryset.order_by('-final_score', '-created_at')

    def perform_create(self, serializer):
        user = get_current_wechat_user(self.request)
        if not user:
            raise serializers.ValidationError("请先登录")
            
        competition = serializer.validated_data['competition']
        
        # 检查是否有参赛资格
        try:
            enrollment = CompetitionEnrollment.objects.get(
                competition=competition, 
                user=user, 
                role='contestant',
                status='approved'
            )
        except CompetitionEnrollment.DoesNotExist:
            raise serializers.ValidationError("您没有参赛资格或审核未通过")
            
        # 检查是否已提交过项目
        if Project.objects.filter(competition=competition, contestant=enrollment).exists():
            raise serializers.ValidationError("您已提交过该比赛的项目，请勿重复提交")

        serializer.save(contestant=enrollment)

    @action(detail=True, methods=['post'])
    def submit(self, request, pk=None):
        """
        提交项目（从草稿转为已提交）
        """
        project = self.get_object()
        user = get_current_wechat_user(request)
        
        if project.contestant.user != user:
            return Response({"detail": "无权操作"}, status=status.HTTP_403_FORBIDDEN)
            
        project.status = 'submitted'
        project.save()
        return Response({"status": "submitted"})


class ProjectFileViewSet(viewsets.ModelViewSet):
    """
    项目附件管理
    """
    serializer_class = ProjectFileSerializer
    permission_classes = [permissions.AllowAny]
    
    def get_queryset(self):
        return ProjectFile.objects.all()
        
    def perform_create(self, serializer):
        # 简单权限控制：只有项目拥有者可以上传
        project = serializer.validated_data['project']
        user = get_current_wechat_user(self.request)
        
        if not user or project.contestant.user != user:
            raise serializers.ValidationError("无权上传文件")
            
        serializer.save()


class ScoreViewSet(viewsets.ModelViewSet):
    """
    评分管理
    """
    serializer_class = ScoreSerializer
    permission_classes = [permissions.AllowAny]
    
    def get_queryset(self):
        project_id = self.request.query_params.get('project')
        if project_id:
            return Score.objects.filter(project_id=project_id)
        return Score.objects.all()

    def perform_create(self, serializer):
        user = get_current_wechat_user(self.request)
        if not user:
            raise serializers.ValidationError("请先登录")
            
        project = serializer.validated_data['project']
        
        # 检查是否是评委
        try:
            enrollment = CompetitionEnrollment.objects.get(
                competition=project.competition,
                user=user,
                role='judge',
                status='approved'
            )
        except CompetitionEnrollment.DoesNotExist:
            raise serializers.ValidationError("您不是该比赛的评委")
            
        # 检查是否重复打分
        dimension = serializer.validated_data['dimension']
        if Score.objects.filter(project=project, judge=enrollment, dimension=dimension).exists():
            raise serializers.ValidationError("您已对该维度打分")
            
        serializer.save(judge=enrollment)


class CommentViewSet(viewsets.ModelViewSet):
    """
    评语管理
    """
    serializer_class = CommentSerializer
    permission_classes = [permissions.AllowAny]
    
    def get_queryset(self):
        project_id = self.request.query_params.get('project')
        if project_id:
            return Comment.objects.filter(project_id=project_id)
        return Comment.objects.all()

    def perform_create(self, serializer):
        user = get_current_wechat_user(self.request)
        if not user:
            raise serializers.ValidationError("请先登录")
            
        project = serializer.validated_data['project']
        
        # 检查是否是评委
        try:
            enrollment = CompetitionEnrollment.objects.get(
                competition=project.competition,
                user=user,
                role='judge',
                status='approved'
            )
        except CompetitionEnrollment.DoesNotExist:
            raise serializers.ValidationError("您不是该比赛的评委")
            
        serializer.save(judge=enrollment)
