"""
写真一括アップロード・通過履歴校正API
スマホアルバムから複数の写真をアップロードし、EXIF情報から自動的に通過履歴を生成・校正する
"""

import logging
import uuid
import os
from datetime import datetime
from django.http import JsonResponse
from django.utils import timezone
from django.db import transaction
from django.core.files.storage import default_storage
from django.conf import settings
from rest_framework.decorators import api_view, permission_classes, parser_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework import status
from rest_framework.parsers import MultiPartParser, FormParser
from knox.auth import TokenAuthentication

from ..models import NewEvent2, Entry, GpsLog, Location2025

# ログ設定
logger = logging.getLogger(__name__)

@api_view(['POST'])
@permission_classes([IsAuthenticated])
@parser_classes([MultiPartParser, FormParser])
def bulk_upload_checkin_photos(request):
    """
    スマホアルバムから複数の写真を一括アップロードし、EXIF情報から通過履歴を校正する
    
    パラメータ:
    - event_code: イベントコード (必須)
    - zekken_number: ゼッケン番号 (必須)
    - photos: アップロードする写真ファイルのリスト (必須)
    - auto_process: 自動処理を行うかどうか (デフォルト: true)
    """
    
    # リクエストID生成（デバッグ用）
    request_id = str(uuid.uuid4())[:8]
    client_ip = request.META.get('HTTP_X_FORWARDED_FOR', request.META.get('REMOTE_ADDR', 'Unknown'))
    
    logger.info(f"[BULK_UPLOAD] 🎯 API call started - ID: {request_id}, User: {request.user.email if request.user.is_authenticated else 'Anonymous'}, Client IP: {client_ip}")
    
    try:
        # リクエストデータの取得
        event_code = request.POST.get('event_code')
        zekken_number = request.POST.get('zekken_number')
        auto_process = request.POST.get('auto_process', 'true').lower() == 'true'
        
        # アップロードされた写真ファイルの取得
        uploaded_files = request.FILES.getlist('photos')
        
        logger.info(f"[BULK_UPLOAD] 📝 Request data - ID: {request_id}, event_code: '{event_code}', zekken_number: '{zekken_number}', files_count: {len(uploaded_files)}, auto_process: {auto_process}")
        
        # 必須パラメータの検証
        if not all([event_code, zekken_number]):
            logger.warning(f"[BULK_UPLOAD] ❌ Missing required parameters - ID: {request_id}")
            return Response({
                "status": "ERROR",
                "message": "イベントコードとゼッケン番号が必要です"
            }, status=status.HTTP_400_BAD_REQUEST)
        
        if not uploaded_files:
            logger.warning(f"[BULK_UPLOAD] ❌ No files uploaded - ID: {request_id}")
            return Response({
                "status": "ERROR", 
                "message": "アップロードする写真が必要です"
            }, status=status.HTTP_400_BAD_REQUEST)
        
        # ファイル数制限の確認
        max_files = getattr(settings, 'BULK_UPLOAD_MAX_FILES', 50)
        if len(uploaded_files) > max_files:
            logger.warning(f"[BULK_UPLOAD] ❌ Too many files - ID: {request_id}, count: {len(uploaded_files)}, max: {max_files}")
            return Response({
                "status": "ERROR",
                "message": f"一度にアップロードできる写真は最大{max_files}枚です"
            }, status=status.HTTP_400_BAD_REQUEST)
        
        # イベントの存在確認
        event = NewEvent2.objects.filter(event_name=event_code).first()
        if not event:
            logger.warning(f"[BULK_UPLOAD] ❌ Event not found - ID: {request_id}, event_code: '{event_code}'")
            return Response({
                "status": "ERROR", 
                "message": "指定されたイベントが見つかりません"
            }, status=status.HTTP_404_NOT_FOUND)
        
        logger.info(f"[BULK_UPLOAD] ✅ Event found - ID: {request_id}, event: '{event_code}', event_id: {event.id}")
        
        # チームの存在確認とオーナー権限の検証
        entry = Entry.objects.filter(
            event=event, 
            team__zekken_number=zekken_number
        ).first()
        
        if not entry:
            logger.warning(f"[BULK_UPLOAD] ❌ Team not found - ID: {request_id}, zekken_number: '{zekken_number}', event_code: '{event_code}'")
            return Response({
                "status": "ERROR", 
                "message": "指定されたゼッケン番号のチームが見つかりません"
            }, status=status.HTTP_404_NOT_FOUND)
        
        logger.info(f"[BULK_UPLOAD] ✅ Team found - ID: {request_id}, team_name: '{entry.team.team_name}', zekken: {zekken_number}, entry_id: {entry.id}")
        
        # オーナー権限の確認
        if entry.owner != request.user:
            logger.warning(f"[BULK_UPLOAD] ❌ Permission denied - ID: {request_id}, user: {request.user.email}, team_owner: {entry.owner.email}")
            return Response({
                "status": "ERROR",
                "message": "このチームの写真をアップロードする権限がありません"
            }, status=status.HTTP_403_FORBIDDEN)
        
        # 写真処理の準備
        processed_files = []
        successful_uploads = 0
        failed_uploads = 0
        
        # アップロードディレクトリの準備
        upload_dir = f"bulk_checkin_photos/{event_code}/{zekken_number}/"
        os.makedirs(os.path.join(settings.MEDIA_ROOT, upload_dir), exist_ok=True)
        
        with transaction.atomic():
            for index, uploaded_file in enumerate(uploaded_files):
                file_result = {
                    "filename": uploaded_file.name,
                    "file_index": index + 1,
                    "file_size": uploaded_file.size,
                    "upload_time": timezone.now().strftime("%Y-%m-%d %H:%M:%S")
                }
                
                try:
                    # ファイル形式の確認
                    allowed_extensions = ['.jpg', '.jpeg', '.png', '.heic']
                    file_extension = os.path.splitext(uploaded_file.name)[1].lower()
                    
                    if file_extension not in allowed_extensions:
                        file_result.update({
                            "status": "failed",
                            "error": f"サポートされていないファイル形式: {file_extension}"
                        })
                        failed_uploads += 1
                        processed_files.append(file_result)
                        continue
                    
                    # ファイルサイズの確認
                    max_size = getattr(settings, 'BULK_UPLOAD_MAX_FILE_SIZE', 10 * 1024 * 1024)  # 10MB
                    if uploaded_file.size > max_size:
                        file_result.update({
                            "status": "failed",
                            "error": f"ファイルサイズが大きすぎます: {uploaded_file.size / (1024*1024):.1f}MB"
                        })
                        failed_uploads += 1
                        processed_files.append(file_result)
                        continue
                    
                    # ファイルの保存
                    timestamp = timezone.now().strftime("%Y%m%d_%H%M%S")
                    safe_filename = f"{timestamp}_{index+1:03d}_{uploaded_file.name}"
                    file_path = os.path.join(upload_dir, safe_filename)
                    
                    # ファイル保存
                    saved_path = default_storage.save(file_path, uploaded_file)
                    full_path = os.path.join(settings.MEDIA_ROOT, saved_path)
                    
                    file_result.update({
                        "status": "uploaded",
                        "saved_path": saved_path,
                        "file_url": f"{settings.MEDIA_URL}{saved_path}"
                    })
                    
                    # EXIF情報の抽出（今後実装予定）
                    if auto_process:
                        # TODO: EXIF情報の抽出とGPS座標取得
                        # TODO: 撮影時刻の取得
                        # TODO: 近接チェックポイントの検索
                        # TODO: 自動チェックイン処理
                        
                        file_result.update({
                            "auto_process_status": "pending",
                            "auto_process_message": "EXIF解析機能は今後実装予定です"
                        })
                    
                    successful_uploads += 1
                    logger.info(f"[BULK_UPLOAD] ✅ File uploaded - ID: {request_id}, filename: {uploaded_file.name}, size: {uploaded_file.size}")
                    
                except Exception as file_error:
                    file_result.update({
                        "status": "failed",
                        "error": f"ファイル処理エラー: {str(file_error)}"
                    })
                    failed_uploads += 1
                    logger.error(f"[BULK_UPLOAD] ❌ File processing error - ID: {request_id}, filename: {uploaded_file.name}, error: {str(file_error)}")
                
                processed_files.append(file_result)
        
        # 処理結果のサマリー
        logger.info(f"[BULK_UPLOAD] ✅ Upload completed - ID: {request_id}, successful: {successful_uploads}, failed: {failed_uploads}")
        
        # 成功レスポンス
        return Response({
            "status": "OK",
            "message": "写真の一括アップロードが完了しました",
            "upload_summary": {
                "total_files": len(uploaded_files),
                "successful_uploads": successful_uploads,
                "failed_uploads": failed_uploads,
                "upload_time": timezone.now().strftime("%Y-%m-%d %H:%M:%S")
            },
            "team_info": {
                "team_name": entry.team.team_name,
                "zekken_number": zekken_number,
                "event_code": event_code
            },
            "processed_files": processed_files,
            "auto_process_enabled": auto_process,
            "next_steps": [
                "アップロードされた写真のEXIF情報解析",
                "GPS座標からチェックポイント自動判定",
                "通過履歴の自動生成と校正",
                "ユーザーによる確認と承認"
            ]
        })
        
    except Exception as e:
        logger.error(f"[BULK_UPLOAD] 💥 Unexpected error - ID: {request_id}, error: {str(e)}", exc_info=True)
        return Response({
            "status": "ERROR",
            "message": "サーバーエラーが発生しました"
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_bulk_upload_status(request):
    """
    一括アップロードの処理状況を取得する
    
    パラメータ:
    - event_code: イベントコード (必須)
    - zekken_number: ゼッケン番号 (必須)
    """
    
    request_id = str(uuid.uuid4())[:8]
    logger.info(f"[BULK_STATUS] 🎯 API call started - ID: {request_id}, User: {request.user.email}")
    
    try:
        event_code = request.GET.get('event_code')
        zekken_number = request.GET.get('zekken_number')
        
        if not all([event_code, zekken_number]):
            return Response({
                "status": "ERROR",
                "message": "イベントコードとゼッケン番号が必要です"
            }, status=status.HTTP_400_BAD_REQUEST)
        
        # チーム権限の確認
        event = NewEvent2.objects.filter(event_name=event_code).first()
        if not event:
            return Response({
                "status": "ERROR",
                "message": "指定されたイベントが見つかりません"
            }, status=status.HTTP_404_NOT_FOUND)
        
        entry = Entry.objects.filter(event=event, team__zekken_number=zekken_number).first()
        if not entry or entry.owner != request.user:
            return Response({
                "status": "ERROR",
                "message": "このチームの情報にアクセスする権限がありません"
            }, status=status.HTTP_403_FORBIDDEN)
        
        # TODO: 実際の処理状況を取得
        # TODO: アップロードされたファイル一覧
        # TODO: EXIF解析状況
        # TODO: 自動チェックイン生成状況
        
        return Response({
            "status": "OK",
            "team_info": {
                "team_name": entry.team.team_name,
                "zekken_number": zekken_number,
                "event_code": event_code
            },
            "upload_status": {
                "total_uploaded_files": 0,
                "processed_files": 0,
                "pending_files": 0,
                "auto_checkins_generated": 0,
                "manual_review_required": 0
            },
            "implementation_status": "基本機能実装完了、詳細処理は今後実装予定"
        })
        
    except Exception as e:
        logger.error(f"[BULK_STATUS] 💥 Unexpected error - ID: {request_id}, error: {str(e)}", exc_info=True)
        return Response({
            "status": "ERROR",
            "message": "サーバーエラーが発生しました"
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
