#!/usr/bin/env python3
"""
Cloud Storage Module
云存储模块

Handles file upload and download operations with cloud storage services.
"""

import os
import time
import mimetypes
from typing import Dict, Any, Optional

import sys
from python_core.config import settings
from python_core.utils import setup_logger
logger = setup_logger(__name__)

class CloudStorage:
    """Cloud storage service for handling file uploads and downloads."""
    
    def __init__(self, 
                 bucket_name: str = None,
                 secret_id: str = None, 
                 secret_key: str = None,
                 region: str = None):
        """
        Initialize cloud storage client.
        
        Args:
            bucket_name: COS bucket name
            secret_id: COS secret ID
            secret_key: COS secret key
            region: COS region
        """
        # Use provided credentials or fallback to environment variables
        self.bucket_name = bucket_name or os.getenv('COS_BUCKET_NAME', 'sucai-1324682537')
        self.secret_id = secret_id or os.getenv('COS_SECRET_ID', 'AKIDsrihIyjZOBsjimt8TsN8yvv1AMh5dB44')
        self.secret_key = secret_key or os.getenv('COS_SECRET_KEY', 'CPZcxdk6W39Jd4cGY95wvupoyMd0YFqW')
        self.region = region or os.getenv('COS_REGION', 'ap-shanghai')
        
        self.client = None
        self._initialize_client()
    
    def _initialize_client(self):
        """Initialize COS client."""
        try:
            from qcloud_cos import CosConfig, CosS3Client
            self.cos_available = True
            
            config = CosConfig(
                Region=self.region,
                SecretId=self.secret_id,
                SecretKey=self.secret_key
            )
            self.client = CosS3Client(config)
            logger.info("COS client initialized successfully")
            
        except ImportError:
            logger.warning("qcloud_cos not installed. Cloud storage features will be disabled.")
            self.client = None
            self.cos_available = False
        except Exception as e:
            logger.error(f"Failed to initialize COS client: {str(e)}")
            self.client = None
    
    def upload_file(self, file_path: str, remove_src_file: bool = False) -> Dict[str, Any]:
        """
        Upload file to cloud storage.
        
        Args:
            file_path: Local file path to upload
            remove_src_file: Whether to remove source file after upload
            
        Returns:
            Dictionary with upload result
        """
        result = {'status': False, 'data': '', 'msg': ''}
        
        if not self.cos_available:
            # Fallback to local file path when cloud storage is not available
            if os.path.exists(file_path):
                # Convert to file:// URL for consistency
                file_url = f"file://{os.path.abspath(file_path)}"
                result['status'] = True
                result['data'] = file_url
                result['msg'] = 'Using local file (cloud storage not available)'
                logger.info(f"Using local file: {file_url}")
                return result
            else:
                result['msg'] = f'Local file not found: {file_path}'
                return result

        if not self.client:
            result['msg'] = 'Cloud storage client not available'
            return result
        
        if not os.path.exists(file_path):
            result['msg'] = f'File not found: {file_path}'
            return result
        
        try:
            # Determine file type and generate object key
            mime_type, _ = mimetypes.guess_type(file_path)
            if not mime_type:
                mime_type = 'application/octet-stream'
            
            category = mime_type.split('/')[0]
            file_name = os.path.basename(file_path)
            suffix = file_name.split('.')[-1] if '.' in file_name else 'bin'
            real_name = f'{int(time.time() * 1000)}.{suffix}'
            object_key = f'mixvideo/{category}/{real_name}'
            
            # Upload file
            response = self.client.upload_file(
                Bucket=self.bucket_name,
                Key=object_key,
                LocalFilePath=file_path,
                EnableMD5=False,
                progress_callback=None
            )
            
            # Generate public URL
            url = f'https://{self.bucket_name}.cos.{self.region}.myqcloud.com/{object_key}'
            
            result['status'] = True
            result['data'] = url
            result['msg'] = 'Upload successful'
            
        except Exception as e:
            import traceback
            error_details = {
                'error_type': type(e).__name__,
                'error_message': str(e),
                'traceback': traceback.format_exc()
            }
            logger.error(f"Failed to upload file: {error_details['error_type']}: {error_details['error_message']}")
            logger.error(f"Traceback: {error_details['traceback']}")
            result['msg'] = f"Upload failed - {error_details['error_type']}: {error_details['error_message']}"
            result['error_details'] = error_details
        
        finally:
            if remove_src_file and result['status'] and os.path.exists(file_path):
                try:
                    os.remove(file_path)
                    logger.info(f"Source file removed: {file_path}")
                except Exception as e:
                    logger.warning(f"Failed to remove source file: {str(e)}")
        
        return result
    
    def download_file(self, url: str, save_path: str, filename: str = None) -> str:
        """
        Download file from URL to local path.
        
        Args:
            url: File URL to download
            save_path: Directory to save the file
            filename: Optional custom filename
            
        Returns:
            Local file path if successful, None if failed
        """
        try:
            import requests
            
            if not filename:
                filename = f'{int(time.time() * 1000)}.mp4'
            
            full_path = os.path.join(save_path, filename)
            
            # Ensure save directory exists
            os.makedirs(save_path, exist_ok=True)
            
            # Download file
            response = requests.get(url, stream=True)
            response.raise_for_status()
            
            with open(full_path, 'wb') as f:
                for chunk in response.iter_content(chunk_size=1024 * 1024 * 5):
                    if chunk:
                        f.write(chunk)
            
            logger.info(f"File downloaded successfully: {full_path}")
            return full_path
            
        except Exception as e:
            logger.error(f"Failed to download file: {str(e)}")
            return None
    
    def list_files(self, prefix: str = 'mixvideo/') -> Dict[str, Any]:
        """
        List files in cloud storage.
        
        Args:
            prefix: Object key prefix to filter
            
        Returns:
            Dictionary with file list
        """
        result = {'status': False, 'files': [], 'msg': ''}
        
        if not self.client:
            result['msg'] = 'Cloud storage client not available'
            return result
        
        try:
            response = self.client.list_objects(
                Bucket=self.bucket_name,
                Prefix=prefix
            )
            
            files = []
            if 'Contents' in response:
                for obj in response['Contents']:
                    files.append({
                        'key': obj['Key'],
                        'size': obj['Size'],
                        'last_modified': obj['LastModified'],
                        'url': f'https://{self.bucket_name}.cos.{self.region}.myqcloud.com/{obj["Key"]}'
                    })
            
            result['status'] = True
            result['files'] = files
            result['msg'] = f'Found {len(files)} files'
            
        except Exception as e:
            logger.error(f"Failed to list files: {str(e)}")
            result['msg'] = str(e)
        
        return result
    
    def delete_file(self, object_key: str) -> Dict[str, Any]:
        """
        Delete file from cloud storage.
        
        Args:
            object_key: Object key to delete
            
        Returns:
            Dictionary with deletion result
        """
        result = {'status': False, 'msg': ''}
        
        if not self.client:
            result['msg'] = 'Cloud storage client not available'
            return result
        
        try:
            self.client.delete_object(
                Bucket=self.bucket_name,
                Key=object_key
            )
            
            result['status'] = True
            result['msg'] = 'File deleted successfully'
            logger.info(f"File deleted: {object_key}")
            
        except Exception as e:
            logger.error(f"Failed to delete file: {str(e)}")
            result['msg'] = str(e)
        
        return result
