"""
通過審査管理画面用API
参加者全体の得点とクラス別ランキング表示機能
"""

import logging
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework import status
from django.db.models import Sum, Q, Count
from django.db import models

from rog.models import NewEvent2, Entry, GpsCheckin, NewCategory

logger = logging.getLogger(__name__)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_event_participants_ranking(request):
    """
    イベント参加者全体のクラス別得点ランキング取得
    
    GET /api/event-participants-ranking/?event_code=FC岐阜
    """
    try:
        event_code = request.GET.get('event_code')
        
        if not event_code:
            return Response({
                'error': 'event_code parameter is required'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        # イベントの検索（完全一致を優先）
        event = None
        if event_code:
            # まず完全一致でイベント名検索
            event = NewEvent2.objects.filter(event_name=event_code).first()
            if not event:
                # 次にイベントコードで検索
                event = NewEvent2.objects.filter(event_code=event_code).first()
        
        if not event:
            return Response({
                'error': 'Event not found'
            }, status=status.HTTP_404_NOT_FOUND)
        
        # イベント参加者の取得と得点計算
        entries = Entry.objects.filter(
            event=event,
            is_active=True
        ).select_related('category', 'team').prefetch_related('team__members')
        
        ranking_data = []
        
        for entry in entries:
            # このエントリーのチェックイン記録を取得
            checkins = GpsCheckin.objects.filter(
                zekken=str(entry.zekken_number),
                event_code=event_code
            )
            
            # 得点計算
            total_points = 0
            cp_points = 0
            buy_points = 0
            confirmed_points = 0  # 確定済み得点
            unconfirmed_points = 0  # 未確定得点
            late_penalty = 0
            
            for checkin in checkins:
                if checkin.points:
                    if checkin.validate_location:  # 確定済み
                        confirmed_points += checkin.points
                        if checkin.buy_flag:
                            buy_points += checkin.points
                        else:
                            cp_points += checkin.points
                    else:  # 未確定
                        unconfirmed_points += checkin.points
                
                if checkin.late_point:
                    late_penalty += checkin.late_point
            
            total_points = confirmed_points - late_penalty
            
            # チェックイン確定状況
            total_checkins = checkins.count()
            confirmed_checkins = checkins.filter(validate_location=True).count()
            confirmation_rate = (confirmed_checkins / total_checkins * 100) if total_checkins > 0 else 0
            
            # チームメンバー情報
            team_members = []
            if entry.team and entry.team.members.exists():
                team_members = [
                    {
                        'name': f"{member.user.firstname} {member.user.lastname}" if member.user else member.name,
                        'age': member.age if hasattr(member, 'age') else None
                    }
                    for member in entry.team.members.all()
                ]
            
            ranking_data.append({
                'rank': 0,  # 後で設定
                'zekken_number': entry.zekken_number,
                'zekken_label': entry.zekken_label or f"{entry.zekken_number}",
                'team_name': entry.team.team_name if entry.team else "チーム名不明",
                'category': {
                    'name': entry.category.category_name,
                    'class_name': entry.category.category_name  # class_nameプロパティがない場合はcategory_nameを使用
                },
                'members': team_members,
                'points': {
                    'total': total_points,
                    'cp_points': cp_points,
                    'buy_points': buy_points,
                    'confirmed_points': confirmed_points,
                    'unconfirmed_points': unconfirmed_points,
                    'late_penalty': late_penalty
                },
                'checkin_status': {
                    'total_checkins': total_checkins,
                    'confirmed_checkins': confirmed_checkins,
                    'unconfirmed_checkins': total_checkins - confirmed_checkins,
                    'confirmation_rate': round(confirmation_rate, 1)
                },
                'entry_status': {
                    'has_participated': entry.hasParticipated,
                    'has_goaled': entry.hasGoaled
                }
            })
        
        # クラス別にソートしてランキング設定
        ranking_data.sort(key=lambda x: (x['category']['class_name'], -x['points']['total']))
        
        # クラス別ランキングの設定
        current_class = None
        current_rank = 0
        for i, item in enumerate(ranking_data):
            if item['category']['class_name'] != current_class:
                current_class = item['category']['class_name']
                current_rank = 1
            else:
                current_rank += 1
            item['rank'] = current_rank
            item['class_rank'] = current_rank
        
        # クラス別にグループ化
        classes_ranking = {}
        for item in ranking_data:
            class_name = item['category']['class_name']
            if class_name not in classes_ranking:
                classes_ranking[class_name] = []
            classes_ranking[class_name].append(item)
        
        return Response({
            'status': 'success',
            'event': {
                'event_code': event_code,
                'event_name': event.event_name,
                'total_participants': len(ranking_data)
            },
            'classes_ranking': classes_ranking,
            'all_participants': ranking_data,
            'participants': ranking_data  # JavaScript互換性のため
        }, status=status.HTTP_200_OK)
        
    except Exception as e:
        logger.error(f"Error in get_event_participants_ranking: {str(e)}")
        return Response({
            'error': str(e)
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_participant_validation_details(request):
    """
    参加者の通過情報詳細と確定状況の取得
    
    GET /api/participant-validation-details/?event_code=FC岐阜&zekken_number=123
    """
    try:
        event_code = request.GET.get('event_code')
        zekken_number = request.GET.get('zekken_number')
        
        if not all([event_code, zekken_number]):
            return Response({
                'error': 'event_code and zekken_number parameters are required'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        # イベントの確認
        try:
            event = NewEvent2.objects.get(event_code=event_code)
        except NewEvent2.DoesNotExist:
            return Response({
                'error': 'Event not found'
            }, status=status.HTTP_404_NOT_FOUND)
        
        # エントリーの確認
        try:
            entry = Entry.objects.get(
                event=event, 
                zekken_number=zekken_number
            )
        except Entry.DoesNotExist:
            return Response({
                'error': 'Participant not found'
            }, status=status.HTTP_404_NOT_FOUND)
        
        # チェックイン記録の取得
        checkins = GpsCheckin.objects.filter(
            zekken=str(zekken_number),
            event_code=event_code
        ).order_by('serial_number')
        
        checkin_details = []
        for checkin in checkins:
            checkin_details.append({
                'id': checkin.id,
                'path_order': checkin.serial_number,
                'cp_number': checkin.cp_number,
                'checkin_time': checkin.create_at.isoformat() if checkin.create_at else None,
                'image_url': checkin.image_address,
                'gps_location': {
                    'latitude': checkin.lattitude,
                    'longitude': checkin.longitude
                } if checkin.lattitude and checkin.longitude else None,
                'validation': {
                    'is_confirmed': checkin.validate_location,
                    'buy_flag': checkin.buy_flag,
                    'points': checkin.points or 0
                },
                'metadata': {
                    'create_user': checkin.create_user,
                    'update_user': checkin.update_user,
                    'update_time': checkin.update_at.isoformat() if checkin.update_at else None
                }
            })
        
        # 統計情報
        stats = {
            'total_checkins': len(checkin_details),
            'confirmed_checkins': sum(1 for c in checkin_details if c['validation']['is_confirmed']),
            'unconfirmed_checkins': sum(1 for c in checkin_details if not c['validation']['is_confirmed']),
            'total_points': sum(c['validation']['points'] for c in checkin_details if c['validation']['is_confirmed']),
            'potential_points': sum(c['validation']['points'] for c in checkin_details)
        }
        
        return Response({
            'status': 'success',
            'participant': {
                'zekken_number': entry.zekken_number,
                'team_name': entry.team_name,
                'category': entry.category.name,
                'class_name': entry.class_name
            },
            'statistics': stats,
            'checkins': checkin_details
        }, status=status.HTTP_200_OK)
        
    except Exception as e:
        logger.error(f"Error in get_participant_validation_details: {str(e)}")
        return Response({
            'error': str(e)
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def get_event_zekken_list(request):
    """
    イベントのゼッケン番号リスト取得（ALLオプション付き）
    
    POST /api/event-zekken-list/
    {
        "event_code": "FC岐阜"
    }
    """
    try:
        import json
        data = json.loads(request.body)
        event_code = data.get('event_code')
        
        if event_code is None:
            return Response({
                'error': 'event_code parameter is required'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        # イベントの確認 - event_code=Noneの場合の処理を追加
        try:
            if event_code == '' or event_code is None:
                # event_code=Noneまたは空文字列の場合
                event = NewEvent2.objects.filter(event_code=None).first()
            else:
                # まずevent_nameで正確な検索を試す
                try:
                    event = NewEvent2.objects.get(event_name=event_code)
                except NewEvent2.DoesNotExist:
                    # event_nameで見つからない場合はevent_codeで検索
                    event = NewEvent2.objects.get(event_code=event_code)
                
            if not event:
                return Response({
                    'error': 'Event not found'
                }, status=status.HTTP_404_NOT_FOUND)
                
        except NewEvent2.DoesNotExist:
            return Response({
                'error': 'Event not found'
            }, status=status.HTTP_404_NOT_FOUND)
        
        # 参加エントリーの取得
        entries = Entry.objects.filter(
            event=event,
            is_active=True
        ).order_by('zekken_number')
        
        zekken_list = []
        
        # ALLオプションを最初に追加
        zekken_list.append({
            'value': 'ALL',
            'label': 'ALL（全参加者）',
            'team_name': '全参加者表示',
            'category': '全クラス'
        })
        
        # 各参加者のゼッケン番号を追加
        for entry in entries:
            team_name = entry.team.team_name if entry.team else 'チーム名未設定'
            category_name = entry.category.category_name if entry.category else 'クラス未設定'
            
            # zekken_labelが存在する場合はそれを使用、そうでなければzekken_numberを使用
            zekken_value = entry.zekken_label if entry.zekken_label else str(entry.zekken_number)
            # 表示ラベルをzekken_labelベースに変更
            zekken_label = f"{zekken_value} - {team_name}"
            
            zekken_list.append({
                'value': zekken_value,
                'label': zekken_label,
                'team_name': team_name,
                'category': category_name
            })
        
        return Response({
            'status': 'success',
            'event_code': event_code,
            'zekken_options': zekken_list
        }, status=status.HTTP_200_OK)
        
    except Exception as e:
        logger.error(f"Error in get_event_zekken_list: {str(e)}")
        return Response({
            'error': str(e)
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
