from rest_framework.decorators import api_view, parser_classes, authentication_classes, permission_classes
from rest_framework.response import Response
from rest_framework import status
from rest_framework.parsers import MultiPartParser, FormParser
from rest_framework.permissions import IsAuthenticated
from django.views.decorators.csrf import csrf_exempt
from .oss import OSSUploader
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
import logging
import traceback
import os
from userapp.authentication import RedisTokenAuthentication

logger = logging.getLogger(__name__)

@swagger_auto_schema(
    method='post',
    operation_description="通用文件上传接口，上传到OSS",
    manual_parameters=[
        openapi.Parameter(
            'file', 
            openapi.IN_FORM, 
            description="需要上传的文件", 
            type=openapi.TYPE_FILE,
            required=True
        ),
        openapi.Parameter(
            'is_permanent', 
            openapi.IN_FORM, 
            description="是否永久保存文件，默认为临时文件", 
            type=openapi.TYPE_BOOLEAN,
            default=False
        ),
        openapi.Parameter(
            'filename', 
            openapi.IN_FORM, 
            description="自定义文件名（可选），如果不提供则自动生成", 
            type=openapi.TYPE_STRING,
            required=False
        ),
    ],
    responses={
        200: openapi.Response(
            description="上传成功",
            schema=openapi.Schema(
                type=openapi.TYPE_OBJECT,
                properties={
                    'url': openapi.Schema(type=openapi.TYPE_STRING, description="文件访问URL"),
                    'key': openapi.Schema(type=openapi.TYPE_STRING, description="OSS对象键名"),
                    'is_permanent': openapi.Schema(type=openapi.TYPE_BOOLEAN, description="是否永久文件")
                }
            )
        ),
        400: openapi.Response(description="请求错误或上传失败"),
        401: openapi.Response(description="认证失败")
    },
    tags=['文件上传'],
    security=[{'Bearer': []}]
)
@csrf_exempt
@api_view(['POST'])
@parser_classes([MultiPartParser, FormParser])
@authentication_classes([RedisTokenAuthentication])
@permission_classes([IsAuthenticated])
def upload_file(request):
    """
    通用文件上传接口，将文件上传到OSS
    文件保存在 upload/{temporary|permanent}/{date}/{filename} 结构下
    需要提供有效的认证令牌
    """
    try:
        # 检查是否有文件
        if 'file' not in request.FILES:
            print("[Upload] No file in request.FILES, keys:", list(request.FILES.keys()))
            return Response({"error": "No file provided"}, status=status.HTTP_400_BAD_REQUEST)

        file_obj = request.FILES['file']
        original_name = file_obj.name
        file_size = file_obj.size
        content_type = getattr(file_obj, 'content_type', 'unknown')
        print(f"[Upload] File received: {original_name}, size={file_size}, type={content_type}")

        # 获取参数
        is_permanent_raw = request.data.get('is_permanent', 'false')
        is_permanent = str(is_permanent_raw).lower() == 'true'
        filename = request.data.get('filename', None)

        # 上传文件
        uploader = OSSUploader()
        result = uploader.upload_file(file_obj, is_permanent, filename)

        # 返回包含前端需要的字段
        _, ext = os.path.splitext(original_name)
        response_data = {
            'url': result['url'],
            'key': result['key'],
            'is_permanent': result['is_permanent'],
            'filename': original_name,
            'size': file_size,
            'mimeType': content_type,
        }

        print(f"[Upload] Success: {result['url']}")
        return Response(response_data, status=status.HTTP_200_OK)

    except Exception as e:
        error_detail = traceback.format_exc()
        print(f"[Upload] ERROR: {error_detail}")
        logger.error(f"File upload failed: {str(e)}\n{error_detail}")
        return Response(
            {"error": "File upload failed", "detail": str(e)},
            status=status.HTTP_400_BAD_REQUEST
        )