"""
Multi Image Upload API Views
複数画像一括アップロード機能
"""

import os
import base64
import uuid
import time
import logging
from datetime import datetime
from django.conf import settings
from django.core.files.base import ContentFile
from django.core.files.storage import default_storage
from rest_framework import status
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.response import Response
from django.db import transaction
from PIL import Image
import io

from .models import UploadedImage, NewEvent2, Entry
from .serializers import (
    MultiImageUploadSerializer, 
    MultiImageUploadResponseSerializer,
    UploadedImageSerializer
)

logger = logging.getLogger(__name__)


@api_view(['POST'])
@permission_classes([AllowAny])
def multi_image_upload(request):
    """
    複数画像一括アップロードAPI
    
    POST /api/images/multi-upload
    
    Request:
    {
        "event_code": "岐阜ロゲイニング2025",
        "team_name": "チーム名",
        "cp_number": 1,
        "images": [
            {
                "file_data": "base64_encoded_image_data",
                "filename": "checkpoint1_photo1.jpg",
                "mime_type": "image/jpeg",
                "file_size": 2048576,
                "capture_timestamp": "2025-09-15T11:30:00Z"
            }
        ],
        "upload_source": "sharing_intent",
        "device_platform": "ios"
    }
    """
    start_time = time.time()
    
    try:
        # リクエストデータ検証
        serializer = MultiImageUploadSerializer(data=request.data)
        if not serializer.is_valid():
            return Response({
                'status': 'error',
                'message': 'Invalid request data',
                'errors': serializer.errors
            }, status=status.HTTP_400_BAD_REQUEST)
        
        validated_data = serializer.validated_data
        event_code = validated_data['event_code']
        team_name = validated_data['team_name']
        cp_number = validated_data['cp_number']
        images_data = validated_data['images']
        upload_source = validated_data.get('upload_source', 'direct')
        device_platform = validated_data.get('device_platform')
        
        # イベントの存在確認
        try:
            event = NewEvent2.objects.get(event_name=event_code)
        except NewEvent2.DoesNotExist:
            return Response({
                'status': 'error',
                'message': f'イベント "{event_code}" が見つかりません'
            }, status=status.HTTP_404_NOT_FOUND)
        
        # エントリーの存在確認
        try:
            entry = Entry.objects.filter(
                event=event,
                team__team_name=team_name
            ).first()
        except Entry.DoesNotExist:
            entry = None
        
        uploaded_files = []
        failed_files = []
        total_upload_size = 0
        
        # トランザクション開始
        with transaction.atomic():
            for i, image_data in enumerate(images_data):
                try:
                    uploaded_image = _process_single_image(
                        image_data,
                        event_code,
                        team_name,
                        cp_number,
                        upload_source,
                        device_platform,
                        entry,
                        i
                    )
                    
                    uploaded_files.append({
                        'original_filename': uploaded_image.original_filename,
                        'server_filename': uploaded_image.server_filename,
                        'file_url': uploaded_image.file_url,
                        'file_size': uploaded_image.file_size
                    })
                    
                    total_upload_size += uploaded_image.file_size
                    
                except Exception as e:
                    logger.error(f"Failed to process image {i}: {e}")
                    failed_files.append({
                        'filename': image_data.get('filename', f'image_{i}'),
                        'error': str(e)
                    })
        
        # 処理時間計算
        processing_time_ms = int((time.time() - start_time) * 1000)
        
        # レスポンス作成
        response_data = {
            'status': 'success' if not failed_files else 'partial_success',
            'uploaded_count': len(uploaded_files),
            'failed_count': len(failed_files),
            'uploaded_files': uploaded_files,
            'failed_files': failed_files,
            'total_upload_size': total_upload_size,
            'processing_time_ms': processing_time_ms
        }
        
        if failed_files:
            response_data['message'] = f"{len(uploaded_files)}個のファイルがアップロードされ、{len(failed_files)}個が失敗しました"
        else:
            response_data['message'] = f"{len(uploaded_files)}個のファイルが正常にアップロードされました"
        
        return Response(response_data, status=status.HTTP_200_OK)
        
    except Exception as e:
        logger.error(f"Multi image upload error: {e}")
        return Response({
            'status': 'error',
            'message': 'サーバーエラーが発生しました',
            'error_details': str(e)
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def image_list(request):
    """
    アップロード済み画像一覧取得
    
    GET /api/images/list/
    
    Parameters:
    - entry_id: エントリーID（オプション）
    - event_code: イベントコード（オプション）
    - limit: 取得数上限（デフォルト50）
    - offset: オフセット（デフォルト0）
    """
    
    try:
        entry_id = request.GET.get('entry_id')
        event_code = request.GET.get('event_code')
        limit = int(request.GET.get('limit', 50))
        offset = int(request.GET.get('offset', 0))
        
        # 基本クエリ
        queryset = UploadedImage.objects.all()
        
        # フィルタリング
        if entry_id:
            queryset = queryset.filter(entry_id=entry_id)
        if event_code:
            queryset = queryset.filter(entry__event_name=event_code)
        
        # 並び順と取得数制限
        queryset = queryset.order_by('-uploaded_at')[offset:offset+limit]
        
        # シリアライズ
        serializer = UploadedImageSerializer(queryset, many=True)
        
        return Response({
            'images': serializer.data,
            'count': len(serializer.data),
            'limit': limit,
            'offset': offset
        })
        
    except Exception as e:
        logger.error(f"Image list error: {e}")
        return Response({
            'error': 'Failed to get image list',
            'message': str(e)
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET', 'DELETE'])
@permission_classes([IsAuthenticated])
def image_detail(request, image_id):
    """
    画像詳細取得・削除
    
    GET /api/images/{image_id}/  - 画像詳細取得
    DELETE /api/images/{image_id}/  - 画像削除
    """
    
    try:
        image = UploadedImage.objects.get(id=image_id)
        
        if request.method == 'GET':
            serializer = UploadedImageSerializer(image)
            return Response(serializer.data)
        
        elif request.method == 'DELETE':
            # ファイル削除
            if image.image_file and os.path.exists(image.image_file.path):
                os.remove(image.image_file.path)
            if image.thumbnail and os.path.exists(image.thumbnail.path):
                os.remove(image.thumbnail.path)
            
            # データベースレコード削除
            image.delete()
            
            return Response({
                'message': 'Image deleted successfully'
            })
        
    except UploadedImage.DoesNotExist:
        return Response({
            'error': 'Image not found'
        }, status=status.HTTP_404_NOT_FOUND)
        
    except Exception as e:
        logger.error(f"Image detail error: {e}")
        return Response({
            'error': 'Internal server error',
            'message': str(e)
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


def _process_single_image(image_data, event_code, team_name, cp_number, 
                         upload_source, device_platform, entry, index):
    """単一画像の処理"""
    
    # Base64デコード
    try:
        if ',' in image_data['file_data']:
            # data:image/jpeg;base64,... 形式の場合
            file_data = image_data['file_data'].split(',')[1]
        else:
            file_data = image_data['file_data']
        
        image_binary = base64.b64decode(file_data)
    except Exception as e:
        raise ValueError(f"Base64デコードに失敗しました: {e}")
    
    # ファイル名生成
    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
    file_extension = _get_file_extension(image_data['mime_type'])
    server_filename = f"{event_code}_{team_name}_cp{cp_number}_{timestamp}_{index:03d}{file_extension}"
    
    # ディレクトリ作成
    upload_dir = f"uploads/{datetime.now().strftime('%Y/%m/%d')}"
    full_upload_dir = os.path.join(settings.MEDIA_ROOT, upload_dir)
    os.makedirs(full_upload_dir, exist_ok=True)
    
    # ファイル保存
    file_path = os.path.join(upload_dir, server_filename)
    full_file_path = os.path.join(settings.MEDIA_ROOT, file_path)
    
    with open(full_file_path, 'wb') as f:
        f.write(image_binary)
    
    # ファイルURL生成
    file_url = f"{settings.MEDIA_URL}{file_path}"
    
    # HEICからJPEGへの変換（iOS対応）
    if image_data['mime_type'] == 'image/heic' and device_platform == 'ios':
        try:
            file_url, server_filename = _convert_heic_to_jpeg(full_file_path, file_path)
        except Exception as e:
            logger.warning(f"HEIC conversion failed: {e}")
    
    # サムネイル生成
    thumbnail_url = _generate_thumbnail(full_file_path, file_path)
    
    # データベース保存
    uploaded_image = UploadedImage.objects.create(
        original_filename=image_data['filename'],
        server_filename=server_filename,
        file_url=file_url,
        file_size=image_data['file_size'],
        mime_type=image_data['mime_type'],
        event_code=event_code,
        team_name=team_name,
        cp_number=cp_number,
        upload_source=upload_source,
        device_platform=device_platform,
        capture_timestamp=image_data.get('capture_timestamp'),
        device_info=image_data.get('device_info'),
        processing_status='processed',
        thumbnail_url=thumbnail_url,
        entry=entry
    )
    
    return uploaded_image


def _get_file_extension(mime_type):
    """MIMEタイプからファイル拡張子を取得"""
    mime_to_ext = {
        'image/jpeg': '.jpg',
        'image/png': '.png',
        'image/heic': '.heic',
        'image/webp': '.webp'
    }
    return mime_to_ext.get(mime_type, '.jpg')


def _convert_heic_to_jpeg(heic_path, original_path):
    """HEICファイルをJPEGに変換"""
    try:
        # PIL-HEICライブラリが必要（要インストール）
        from PIL import Image
        
        # HEICファイルを開いてJPEGで保存
        with Image.open(heic_path) as img:
            jpeg_path = heic_path.replace('.heic', '.jpg')
            rgb_img = img.convert('RGB')
            rgb_img.save(jpeg_path, 'JPEG', quality=85)
        
        # 元のHEICファイルを削除
        os.remove(heic_path)
        
        # 新しいファイル情報を返す
        new_file_path = original_path.replace('.heic', '.jpg')
        new_file_url = f"{settings.MEDIA_URL}{new_file_path}"
        new_filename = os.path.basename(new_file_path)
        
        return new_file_url, new_filename
        
    except ImportError:
        logger.warning("PIL-HEIC not available, keeping original HEIC file")
        return f"{settings.MEDIA_URL}{original_path}", os.path.basename(original_path)


def _generate_thumbnail(image_path, original_path):
    """サムネイル画像生成"""
    try:
        with Image.open(image_path) as img:
            # サムネイルサイズ（300x300）
            img.thumbnail((300, 300), Image.Resampling.LANCZOS)
            
            # サムネイルファイル名
            path_parts = original_path.split('.')
            thumbnail_path = f"{'.'.join(path_parts[:-1])}_thumb.{path_parts[-1]}"
            thumbnail_full_path = os.path.join(settings.MEDIA_ROOT, thumbnail_path)
            
            # サムネイル保存
            img.save(thumbnail_full_path, quality=75)
            
            return f"{settings.MEDIA_URL}{thumbnail_path}"
            
    except Exception as e:
        logger.warning(f"Thumbnail generation failed: {e}")
        return None


@api_view(['GET'])
@permission_classes([AllowAny])
def uploaded_images_list(request):
    """アップロード済み画像一覧取得"""
    
    event_code = request.GET.get('event_code')
    team_name = request.GET.get('team_name')
    cp_number = request.GET.get('cp_number')
    
    queryset = UploadedImage.objects.all().order_by('-upload_timestamp')
    
    # フィルタリング
    if event_code:
        queryset = queryset.filter(event_code=event_code)
    if team_name:
        queryset = queryset.filter(team_name=team_name)
    if cp_number:
        queryset = queryset.filter(cp_number=cp_number)
    
    # ページネーション（50件ずつ）
    page = int(request.GET.get('page', 1))
    page_size = 50
    start_index = (page - 1) * page_size
    end_index = start_index + page_size
    
    total_count = queryset.count()
    images = queryset[start_index:end_index]
    
    serializer = UploadedImageSerializer(images, many=True)
    
    return Response({
        'images': serializer.data,
        'pagination': {
            'total_count': total_count,
            'page': page,
            'page_size': page_size,
            'has_next': end_index < total_count,
            'has_previous': page > 1
        }
    })
