
# 既存のインポート部分に追加
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from rog.models import NewEvent2, Entry
import logging
from django.db.models import F, Count
from django.utils import timezone

logger = logging.getLogger(__name__)

"""
解説
この実装では以下の処理を行っています：

1.イベントコードとクラス名のパラメータを受け取ります
2.パラメータが不足している場合はエラーを返します
3.指定されたイベントの存在を確認します
4.指定クラスに属する、ゴール済みのチームをスコア降順で取得します
5.各チームについて以下の情報を収集します：
    - 順位（1から始まる）
    - チーム基本情報（名前、ゼッケン番号）
    - スコア
    - レース時間（スタートからゴールまでの時間）
    - スタート時間・ゴール時間
    - チェックポイント通過数
    - オーナー情報（ユーザー名、メールアドレス）
6.ランキングの要約情報も提供します：
    - イベント情報
    - 指定クラスのチーム総数
    - ゴール済みチーム数
    - 未ゴールチーム数（スタート済みだがゴールしていないチーム）

この実装により、イベント管理者やユーザーはリアルタイムのランキング情報を確認できます。
特に結果発表や途中経過の確認に有用です。スコア順にソートされているため、現在の順位が一目でわかります。
"""

@api_view(['GET'])
def get_ranking(request):
    """
    指定クラスのランキングを取得
    
    パラメータ:
    - class: クラス名
    - event: イベントコード
    """
    logger.info("get_ranking called")
    
    # リクエストからパラメータを取得
    class_name = request.query_params.get('class')
    event_code = request.query_params.get('event')
    
    logger.debug(f"Parameters: class={class_name}, event={event_code}")
    
    # パラメータ検証
    if not all([class_name, event_code]):
        logger.warning("Missing required parameters")
        return Response({
            "status": "ERROR", 
            "message": "クラス名とイベントコードが必要です"
        }, status=status.HTTP_400_BAD_REQUEST)
    
    try:
        # イベントの存在確認
        event = NewEvent2.objects.filter(event_name=event_code).first()
        if not event:
            logger.warning(f"Event not found: {event_code}")
            return Response({
                "status": "ERROR", 
                "message": "指定されたイベントが見つかりません"
            }, status=status.HTTP_404_NOT_FOUND)
        
        # 指定クラスのゴール済みチームを取得（スコア降順）
        teams = Entry.objects.filter(
            event=event,
            class_name=class_name,
            goal_info__isnull=False
        ).order_by('-goal_info__score')
        
        ranking_data = []
        
        for i, team in enumerate(teams):
            # チームのスタート情報を取得
            start_time = None
            if hasattr(team, 'start_info') and team.start_info:
                start_time = team.start_info.start_time
            
            # チームのゴール情報を取得
            goal_time = None
            score = 0
            if hasattr(team, 'goal_info') and team.goal_info:
                goal_time = team.goal_info.goal_time
                score = team.goal_info.score or 0
            
            # レース時間を計算
            race_time = None
            if start_time and goal_time:
                race_seconds = (goal_time - start_time).total_seconds()
                
                # 時間:分:秒の形式にフォーマット
                hours, remainder = divmod(int(race_seconds), 3600)
                minutes, seconds = divmod(remainder, 60)
                race_time = f"{hours:02}:{minutes:02}:{seconds:02}"
            
            # チェックポイント数を取得
            cp_count = 0
            try:
                from rog.models import GpsLog
                cp_count = GpsLog.objects.filter(entry=team).count()
            except:
                pass
            
            # ランキングデータに追加
            team_data = {
                "rank": i + 1,  # 1-basedのランキング
                "team_name": team.team_name,
                "zekken_number": team.zekken_number,
                "score": score,
                "race_time": race_time,
                "start_time": start_time.strftime("%Y-%m-%d %H:%M:%S") if start_time else None,
                "goal_time": goal_time.strftime("%Y-%m-%d %H:%M:%S") if goal_time else None,
                "checkpoint_count": cp_count
            }
            
            # オーナー情報があれば追加
            if hasattr(team, 'owner') and team.owner:
                team_data["owner_name"] = team.owner.username
                team_data["owner_email"] = team.owner.email
            
            ranking_data.append(team_data)
        
        # 未ゴールチームの数を取得
        not_finished_count = Entry.objects.filter(
            event=event,
            class_name=class_name,
            start_info__isnull=False,
            goal_info__isnull=True
        ).count()
        
        # 登録チーム総数を取得
        total_teams = Entry.objects.filter(
            event=event,
            class_name=class_name
        ).count()
        
        # イベント情報を取得
        event_info = {
            "event_name": event.event_name,
            "event_description": getattr(event, 'description', None),
            "event_date": getattr(event, 'event_date', None)
        }
        
        if hasattr(event, 'event_date') and event.event_date:
            event_info["event_date"] = event.event_date.strftime("%Y-%m-%d")
        
        # 現在の日時
        current_time = timezone.now().strftime("%Y-%m-%d %H:%M:%S")
        
        return Response({
            "status": "OK",
            "event": event_info,
            "class_name": class_name,
            "total_teams": total_teams,
            "finished_teams": len(ranking_data),
            "not_finished_teams": not_finished_count,
            "rankings": ranking_data,
            "timestamp": current_time
        })
    
    except Exception as e:
        logger.error(f"Error in get_ranking: {str(e)}")
        return Response({
            "status": "ERROR", 
            "message": "サーバーエラーが発生しました"
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
# 既存のインポート部分に追加
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from rog.models import NewEvent2, Entry
import logging
from django.db.models import F, Count, Q
from django.utils import timezone

logger = logging.getLogger(__name__)

"""
解説
この実装では以下の処理を行っています：

1.イベントコードのパラメータを受け取ります
2.パラメータが不足している場合はエラーを返します
3.指定されたイベントの存在を確認します
4.イベント内の全クラスを取得します
5.各クラスごとに以下の処理を行います：
    - ゴール済みチームをスコア降順で取得し、上位3件に絞り込みます
    - 各チームの基本情報（ランク、名前、ゼッケン番号、スコア、レース時間、チェックポイント数）を収集します
    - クラスの統計情報（総チーム数、ゴール済みチーム数）を計算します
    - クラスデータとチームデータを階層化して格納します
6.イベント全体の統計情報も提供します：
    - 全クラス数
    - 全チーム数
    - ゴール済みチーム数
    - 未ゴールチーム数（スタート済みだがゴールしていないチーム）
この実装により、リアルタイムで全クラスのトップ3ランキングを確認できます。
大会のスコアボードやリザルト公開ページなどに利用できます。
1つのリクエストで全クラスの情報が取得できるため、複数のクラスを表示するページで効率的に情報を取得できます。
"""

@api_view(['GET'])
def all_ranking_top3(request):
    """
    指定イベントの全クラスにおけるトップ3選手のランキングを取得
    
    パラメータ:
    - event: イベントコード
    """
    logger.info("all_ranking_top3 called")
    
    # リクエストからパラメータを取得
    event_code = request.query_params.get('event')
    
    logger.debug(f"Parameters: event={event_code}")
    
    # パラメータ検証
    if not event_code:
        logger.warning("Missing required event parameter")
        return Response({
            "status": "ERROR", 
            "message": "イベントコードが必要です"
        }, status=status.HTTP_400_BAD_REQUEST)
    
    try:
        # イベントの存在確認
        event = NewEvent2.objects.filter(event_name=event_code).first()
        if not event:
            logger.warning(f"Event not found: {event_code}")
            return Response({
                "status": "ERROR", 
                "message": "指定されたイベントが見つかりません"
            }, status=status.HTTP_404_NOT_FOUND)
        
        # イベント内の全クラスを取得
        all_classes = Entry.objects.filter(
            event=event
        ).values_list('class_name', flat=True).distinct()
        
        class_rankings = []
        
        for class_name in all_classes:
            # 指定クラスのゴール済みチームを取得（スコア降順、上位3件）
            teams = Entry.objects.filter(
                event=event,
                class_name=class_name,
                goal_info__isnull=False
            ).order_by('-goal_info__score')[:3]  # 上位3件
            
            team_rankings = []
            
            for i, team in enumerate(teams):
                # チームのスタート情報を取得
                start_time = None
                if hasattr(team, 'start_info') and team.start_info:
                    start_time = team.start_info.start_time
                
                # チームのゴール情報を取得
                goal_time = None
                score = 0
                if hasattr(team, 'goal_info') and team.goal_info:
                    goal_time = team.goal_info.goal_time
                    score = team.goal_info.score or 0
                
                # レース時間を計算
                race_time = None
                if start_time and goal_time:
                    race_seconds = (goal_time - start_time).total_seconds()
                    
                    # 時間:分:秒の形式にフォーマット
                    hours, remainder = divmod(int(race_seconds), 3600)
                    minutes, seconds = divmod(remainder, 60)
                    race_time = f"{hours:02}:{minutes:02}:{seconds:02}"
                
                # チェックポイント数を取得
                cp_count = 0
                try:
                    from rog.models import GpsLog
                    cp_count = GpsLog.objects.filter(entry=team).count()
                except:
                    pass
                
                # チームデータ
                team_data = {
                    "rank": i + 1,  # 1-basedのランキング
                    "team_name": team.team_name,
                    "zekken_number": team.zekken_number,
                    "score": score,
                    "race_time": race_time,
                    "checkpoint_count": cp_count
                }
                
                team_rankings.append(team_data)
            
            # クラスの総チーム数
            total_teams_in_class = Entry.objects.filter(
                event=event,
                class_name=class_name
            ).count()
            
            # ゴール済みチーム数
            finished_teams_in_class = Entry.objects.filter(
                event=event,
                class_name=class_name,
                goal_info__isnull=False
            ).count()
            
            class_data = {
                "class_name": class_name,
                "total_teams": total_teams_in_class,
                "finished_teams": finished_teams_in_class,
                "top_teams": team_rankings
            }
            
            class_rankings.append(class_data)
        
        # イベント情報を取得
        event_info = {
            "event_name": event.event_name,
            "event_description": getattr(event, 'description', None),
            "event_date": getattr(event, 'event_date', None)
        }
        
        if hasattr(event, 'event_date') and event.event_date:
            event_info["event_date"] = event.event_date.strftime("%Y-%m-%d")
        
        # 未ゴールチームの数をイベント全体で取得
        not_finished_count = Entry.objects.filter(
            event=event,
            start_info__isnull=False,
            goal_info__isnull=True
        ).count()
        
        # ゴール済みチームの数をイベント全体で取得
        finished_count = Entry.objects.filter(
            event=event,
            goal_info__isnull=False
        ).count()
        
        # 登録チーム総数をイベント全体で取得
        total_teams = Entry.objects.filter(
            event=event
        ).count()
        
        # 現在の日時
        current_time = timezone.now().strftime("%Y-%m-%d %H:%M:%S")
        
        return Response({
            "status": "OK",
            "event": event_info,
            "total_classes": len(class_rankings),
            "total_teams": total_teams,
            "finished_teams": finished_count,
            "not_finished_teams": not_finished_count,
            "rankings_by_class": class_rankings,
            "timestamp": current_time
        })
    
    except Exception as e:
        logger.error(f"Error in all_ranking_top3: {str(e)}")
        return Response({
            "status": "ERROR", 
            "message": "サーバーエラーが発生しました"
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
