import os
import uuid
import json
import string
import random
from django.core.files.storage import FileSystemStorage
from django.conf import settings
from rest_framework.parsers import MultiPartParser
import boto3
from botocore.client import Config
import firebase_admin
from firebase_admin import credentials, storage as firebase_storage
from DepositAPI.api.Api import BaseApiView
from DepositAPI.api.Response import ErrorResponse, SuccessResponse
from DepositAPI.settings import HPOConfig as hpoconfig


class FileUpload(BaseApiView):
    parser_classes = [MultiPartParser]
    
    def __init__(self):
        super().__init__()
        # Khởi tạo Firebase nếu chưa có
        if not firebase_admin._apps:
            try:
                # Đường dẫn đến service account key
                cred = credentials.Certificate(hpoconfig.FIREBASE_SERVICE_ACCOUNT_PATH)
                firebase_admin.initialize_app(cred, {
                    'storageBucket': hpoconfig.FIREBASE_STORAGE_BUCKET
                })
            except Exception as e:
                print(f"Firebase initialization error: {e}")

    def delete_file_cloudfare(self, request):
            """Delete file from Cloudflare R2 Storage"""
            # ===== CLOUDFLARE R2 CONFIG =====
            R2_ACCOUNT_ID = getattr(hpoconfig, 'R2_ACCOUNT_ID', 'f2926c016b5f22486a49115a72c1b761')
            R2_ACCESS_KEY_ID = getattr(hpoconfig, 'R2_ACCESS_KEY_ID', 'f7f0188d0a3a2c2f5770c69bf81f4a40')
            R2_SECRET_ACCESS_KEY = getattr(hpoconfig, 'R2_SECRET_ACCESS_KEY', '0ca21742e8f0e944c99fb562df69e47101ddb35f130de8d59fd279d6877124ed')
            R2_BUCKET_NAME = getattr(hpoconfig, 'R2_BUCKET_NAME', 'mamdtech')

            if request.method != 'DELETE':
                return ErrorResponse(error="Method", status=405, reason="Chỉ hỗ trợ method DELETE")

            # Parse JSON body manually
            try:
                body = json.loads(request.body)
                file_path = body.get('filePath')
            except (json.JSONDecodeError, AttributeError):
                file_path = request.data.get('filePath') if hasattr(request, 'data') else None
            
            if not file_path:
                return ErrorResponse(error="PathNotFound", status=400, reason="Không tìm thấy đường dẫn file")

            try:
                r2_client = boto3.client(
                    's3',
                    endpoint_url=f'https://{R2_ACCOUNT_ID}.r2.cloudflarestorage.com',
                    aws_access_key_id=R2_ACCESS_KEY_ID,
                    aws_secret_access_key=R2_SECRET_ACCESS_KEY,
                    config=Config(signature_version='s3v4'),
                    region_name='auto'
                )
                r2_client.delete_object(Bucket=R2_BUCKET_NAME, Key=file_path)
                return SuccessResponse(data={'message': 'File đã được xóa thành công'})
            except Exception as e:
                return ErrorResponse(
                    error="DeleteError",
                    status=500,
                    reason=f"Lỗi xóa file trên Cloudflare R2: {str(e)}"
                )
                
    def upload_to_cloudfare(self, request):
        """Upload file to Cloudflare R2 Storage and return public URL"""
        # ===== CLOUDFLARE R2 CONFIG =====
        R2_ACCOUNT_ID = getattr(hpoconfig, 'R2_ACCOUNT_ID', 'f2926c016b5f22486a49115a72c1b761')
        R2_ACCESS_KEY_ID = getattr(hpoconfig, 'R2_ACCESS_KEY_ID', 'f7f0188d0a3a2c2f5770c69bf81f4a40')
        R2_SECRET_ACCESS_KEY = getattr(hpoconfig, 'R2_SECRET_ACCESS_KEY', '0ca21742e8f0e944c99fb562df69e47101ddb35f130de8d59fd279d6877124ed')
        R2_BUCKET_NAME = getattr(hpoconfig, 'R2_BUCKET_NAME', 'mamdtech')
        R2_PUBLIC_URL = getattr(hpoconfig, 'R2_PUBLIC_URL', 'https://cdn.mamdtech.com')

        if request.method != 'POST':
            return ErrorResponse(error="Method", status=405, reason="Chỉ hỗ trợ method POST")

        if 'file' not in request.FILES:
            return ErrorResponse(error="FileNotFound", status=400, reason="Không tìm thấy file")

        uploaded_file = request.FILES['file']
        file_type = request.data.get('fileType', 'bill')

        # Validate file type
        allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx', 'xls', 'xlsx']
        file_extension = uploaded_file.name.split('.')[-1].lower()
        if file_extension not in allowed_extensions:
            return ErrorResponse(
                error="InvalidFileType",
                status=400,
                reason=f"Định dạng file không được hỗ trợ. Chỉ chấp nhận: {', '.join(allowed_extensions)}"
            )

        try:
            # Generate unique filename
            unique_filename = f"{uuid.uuid4().hex}.{file_extension}"
            r2_path = f"thpglobal/{file_type}/{unique_filename}"

            # Use boto3 to upload file directly from memory
            r2_client = boto3.client(
                's3',
                endpoint_url=f'https://{R2_ACCOUNT_ID}.r2.cloudflarestorage.com',
                aws_access_key_id=R2_ACCESS_KEY_ID,
                aws_secret_access_key=R2_SECRET_ACCESS_KEY,
                config=Config(signature_version='s3v4'),
                region_name='auto'
            )

            # Upload file object directly
            # Note: Cloudflare R2 doesn't support ACL, so we only set ContentType
            r2_client.upload_fileobj(
                uploaded_file.file,
                R2_BUCKET_NAME,
                r2_path,
                ExtraArgs={'ContentType': uploaded_file.content_type or 'application/octet-stream'}
            )

            # Tạo URL công khai
            file_url = f"{R2_PUBLIC_URL}/{r2_path}"

            return SuccessResponse(data={
                'name': uploaded_file.name,
                'url': file_url,
                'path': r2_path,
                'size': uploaded_file.size,
                'content_type': uploaded_file.content_type
            })

        except Exception as e:
            return ErrorResponse(
                error="UploadError",
                status=500,
                reason=f"Lỗi upload file lên Cloudflare R2: {str(e)}"
            )
    
    def upload_to_firebase(self, request):
        """Upload file to Firebase Storage through backend proxy"""
        if request.method != 'POST':
            return ErrorResponse(error="Method", status=405, reason="Chỉ hỗ trợ method POST")
        
        if 'file' not in request.FILES:
            return ErrorResponse(error="FileNotFound", status=400, reason="Không tìm thấy file")
        
        uploaded_file = request.FILES['file']
        file_type = request.data.get('fileType', 'bill')  # bill, product, etc.
        
        # Validate file type
        allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx', 'xls', 'xlsx']
        file_extension = uploaded_file.name.split('.')[-1].lower()
        
        if file_extension not in allowed_extensions:
            return ErrorResponse(
                error="InvalidFileType", 
                status=400, 
                reason=f"Định dạng file không được hỗ trợ. Chỉ chấp nhận: {', '.join(allowed_extensions)}"
            )
        
        try:
            # Generate unique filename
            unique_filename = f"{uuid.uuid4().hex}.{file_extension}"
            firebase_path = f"{hpoconfig.FIREBASE_PREFIX}/{file_type}/{unique_filename}"
            
            # Upload to Firebase Storage
            bucket = firebase_storage.bucket()
            blob = bucket.blob(firebase_path)
            
            # Upload file content
            blob.upload_from_file(uploaded_file.file, content_type=uploaded_file.content_type)
            
            # Make the blob publicly accessible
            blob.make_public()
            
            # Get public URL
            download_url = blob.public_url
            
            return SuccessResponse(data={
                'name': uploaded_file.name,
                'url': download_url,
                'path': firebase_path,
                'size': uploaded_file.size,
                'content_type': uploaded_file.content_type
            })
            
        except Exception as e:
            return ErrorResponse(
                error="UploadError", 
                status=500, 
                reason=f"Lỗi upload file: {str(e)}"
            )
    
    def upload_multiple_files(self, request):
        """Upload multiple files to Firebase Storage"""
        if request.method != 'POST':
            return ErrorResponse(error="Method", status=405, reason="Chỉ hỗ trợ method POST")
        
        if not request.FILES:
            return ErrorResponse(error="FileNotFound", status=400, reason="Không tìm thấy file nào")
        
        file_type = request.data.get('fileType', 'bill')
        uploaded_files = []
        errors = []
        
        for field_name, uploaded_file in request.FILES.items():
            try:
                # Validate file type
                allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx', 'xls', 'xlsx']
                file_extension = uploaded_file.name.split('.')[-1].lower()
                
                if file_extension not in allowed_extensions:
                    errors.append({
                        'file': uploaded_file.name,
                        'error': f"Định dạng file không được hỗ trợ: {file_extension}"
                    })
                    continue
                
                # Generate unique filename
                unique_filename = f"{uuid.uuid4().hex}.{file_extension}"
                firebase_path = f"{hpoconfig.FIREBASE_PREFIX}/{file_type}/{unique_filename}"
                
                # Upload to Firebase Storage
                bucket = firebase_storage.bucket()
                blob = bucket.blob(firebase_path)
                
                # Upload file content
                blob.upload_from_file(uploaded_file.file, content_type=uploaded_file.content_type)
                
                # Make the blob publicly accessible
                blob.make_public()
                
                # Get public URL
                download_url = blob.public_url
                
                uploaded_files.append({
                    'name': uploaded_file.name,
                    'url': download_url,
                    'path': firebase_path,
                    'size': uploaded_file.size,
                    'content_type': uploaded_file.content_type
                })
                
            except Exception as e:
                errors.append({
                    'file': uploaded_file.name,
                    'error': str(e)
                })
        
        return SuccessResponse(data={
            'uploaded_files': uploaded_files,
            'errors': errors,
            'total_uploaded': len(uploaded_files),
            'total_errors': len(errors)
        })
    
    def delete_file(self, request):
        """Delete file from Firebase Storage"""
        if request.method != 'DELETE':
            return ErrorResponse(error="Method", status=405, reason="Chỉ hỗ trợ method DELETE")
        
        # Parse JSON body manually
        try:
            body = json.loads(request.body)
            file_path = body.get('filePath')
        except (json.JSONDecodeError, AttributeError):
            file_path = request.data.get('filePath') if hasattr(request, 'data') else None
        
        if not file_path:
            return ErrorResponse(error="PathNotFound", status=400, reason="Không tìm thấy đường dẫn file")
        
        try:
            bucket = firebase_storage.bucket()
            blob = bucket.blob(file_path)
            blob.delete()
            
            return SuccessResponse(data={'message': 'File đã được xóa thành công'})
            
        except Exception as e:
            return ErrorResponse(
                error="DeleteError", 
                status=500, 
                reason=f"Lỗi xóa file: {str(e)}"
            )