"""
S3画像アップロードユーティリティ
チェックイン時の画像をS3にアップロードし、URLを生成します
"""

import boto3
import logging
import uuid
from datetime import datetime
from django.conf import settings
from botocore.exceptions import ClientError, NoCredentialsError
import base64
import io
import requests

logger = logging.getLogger(__name__)

class S3ImageUploader:
    def __init__(self):
        """S3クライアントを初期化"""
        try:
            self.s3_client = boto3.client(
                's3',
                aws_access_key_id=getattr(settings, 'AWS_ACCESS_KEY', None),
                aws_secret_access_key=getattr(settings, 'AWS_SECRET_ACCESS_KEY', None),
                region_name=getattr(settings, 'AWS_REGION', 'us-west-2')
            )
            self.bucket_name = getattr(settings, 'S3_BUCKET_NAME', 'sumasenrogaining')
            logger.info(f"S3 client initialized for bucket: {self.bucket_name}")
        except Exception as e:
            logger.error(f"Failed to initialize S3 client: {e}")
            self.s3_client = None
            self.bucket_name = None

    def upload_checkin_image(self, image_data, event_code, zekken_number, cp_number):
        """
        チェックイン画像をS3にアップロード
        
        Args:
            image_data: 画像データ（URLまたはBase64）
            event_code: イベントコード
            zekken_number: ゼッケン番号
            cp_number: チェックポイント番号
            
        Returns:
            str: S3のURL、失敗時は元のimage_data
        """
        if not self.s3_client or not image_data:
            logger.warning("S3 client not available or no image data, returning original")
            return image_data
            
        try:
            # 画像データを取得
            image_binary = self._get_image_binary(image_data)
            if not image_binary:
                logger.error("Failed to get image binary data, returning original")
                return image_data
            
            # S3キーを生成: {event_code}/{zekken_number}/{cp_number}.jpg
            s3_key = f"{event_code}/{zekken_number}/{cp_number}.jpg"
            
            # S3にアップロード
            self.s3_client.put_object(
                Bucket=self.bucket_name,
                Key=s3_key,
                Body=image_binary,
                ContentType='image/jpeg',
                ACL='public-read'  # 公開読み取り可能
            )
            
            # S3 URLを生成
            aws_region = getattr(settings, 'AWS_REGION', 'us-west-2')
            s3_url = f"https://{self.bucket_name}.s3.{aws_region}.amazonaws.com/{s3_key}"
            
            logger.info(f"Successfully uploaded image to S3: {s3_url}")
            return s3_url
            
        except ClientError as e:
            logger.error(f"S3 upload failed: {e}, returning original URL")
            return image_data
        except Exception as e:
            logger.error(f"Unexpected error during S3 upload: {e}, returning original URL")
            return image_data

    def _get_image_binary(self, image_data):
        """
        画像データからバイナリデータを取得
        
        Args:
            image_data: 画像URL（HTTP）またはBase64エンコードされた画像データ
            
        Returns:
            bytes: 画像のバイナリデータ
        """
        try:
            if isinstance(image_data, str):
                # HTTPURLの場合
                if image_data.startswith('http'):
                    return self._download_image_from_url(image_data)
                # Base64の場合
                elif self._is_base64(image_data):
                    return base64.b64decode(image_data)
                # data:image/jpeg;base64,の形式の場合
                elif image_data.startswith('data:image'):
                    base64_data = image_data.split(',')[1]
                    return base64.b64decode(base64_data)
                    
            logger.error(f"Unsupported image data format: {type(image_data)}")
            return None
            
        except Exception as e:
            logger.error(f"Error processing image data: {e}")
            return None

    def _download_image_from_url(self, url):
        """URLから画像をダウンロード"""
        try:
            response = requests.get(url, timeout=30)
            response.raise_for_status()
            return response.content
        except Exception as e:
            logger.error(f"Failed to download image from URL {url}: {e}")
            return None

    def _is_base64(self, data):
        """文字列がBase64かどうかをチェック"""
        try:
            if isinstance(data, str):
                base64.b64decode(data, validate=True)
                return True
        except Exception:
            return False
        return False

    def generate_s3_url(self, event_code, zekken_number, cp_number):
        """
        S3 URLを生成（アップロード済みの画像用）
        
        Args:
            event_code: イベントコード
            zekken_number: ゼッケン番号
            cp_number: チェックポイント番号
            
        Returns:
            str: S3のURL
        """
        aws_region = getattr(settings, 'AWS_REGION', 'us-west-2')
        s3_key = f"{event_code}/{zekken_number}/{cp_number}.jpg"
        return f"https://{self.bucket_name}.s3.{aws_region}.amazonaws.com/{s3_key}"


# グローバルインスタンス
s3_uploader = S3ImageUploader()
