from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework import serializers

# 通用响应Schema
class SuccessResponseSchema(serializers.Serializer):
    """通用成功响应"""
    status = serializers.CharField(help_text="操作状态，成功为'success'")
    code = serializers.IntegerField(help_text="状态码，成功为200")
    message = serializers.CharField(help_text="操作结果信息")

class DataResponseSchema(serializers.Serializer):
    """带数据的成功响应"""
    status = serializers.CharField(help_text="操作状态，成功为'success'")
    code = serializers.IntegerField(help_text="状态码，成功为200")
    data = serializers.JSONField(help_text="返回数据")

class ErrorResponseSchema(serializers.Serializer):
    """错误响应"""
    error = serializers.CharField(help_text="错误信息")
    
    class Meta:
        ref_name = "CommonErrorResponse"

class PaginatedResponseSchema(serializers.Serializer):
    """分页响应"""
    count = serializers.IntegerField(help_text="总数据量")
    next = serializers.URLField(help_text="下一页URL", allow_null=True)
    previous = serializers.URLField(help_text="上一页URL", allow_null=True)
    results = serializers.ListField(help_text="当前页数据")

# 标准化的API响应Schema（新增）
class StandardizedResponseSchema(serializers.Serializer):
    """标准化API响应结构"""
    success = serializers.BooleanField(help_text="操作是否成功")
    code = serializers.IntegerField(help_text="状态码")
    message = serializers.CharField(help_text="操作结果信息", required=False, allow_null=True)
    data = serializers.JSONField(help_text="返回数据", required=False, allow_null=True)
    
    class Meta:
        ref_name = "StandardizedResponse"

# 标准化的API响应生成工具
def get_standardized_response_schema(data_schema=None):
    """
    获取标准化的API响应Schema
    
    Args:
        data_schema: 数据字段的Schema类
        
    Returns:
        openapi.Schema: 标准化的响应Schema
    """
    properties = {
        'success': openapi.Schema(type=openapi.TYPE_BOOLEAN, description='操作是否成功'),
        'code': openapi.Schema(type=openapi.TYPE_INTEGER, description='状态码'),
        'message': openapi.Schema(type=openapi.TYPE_STRING, description='操作结果信息')
    }
    
    if data_schema:
        properties['data'] = data_schema
    
    return openapi.Schema(
        type=openapi.TYPE_OBJECT,
        properties=properties
    )

# 通用认证和错误响应
common_responses = {
    400: openapi.Response('请求参数错误', ErrorResponseSchema),
    401: openapi.Response('认证失败', openapi.Schema(
        type=openapi.TYPE_OBJECT,
        properties={
            'detail': openapi.Schema(type=openapi.TYPE_STRING, description='认证失败信息')
        }
    )),
    403: openapi.Response('权限不足', openapi.Schema(
        type=openapi.TYPE_OBJECT,
        properties={
            'detail': openapi.Schema(type=openapi.TYPE_STRING, description='权限错误信息')
        }
    ))
}

# 快速生成 Swagger 文档的装饰器
def swagger_schema(request_schema=None, responses=None, operation_description="", tags=None, methods=None, 
                  manual_parameters=None, security=None, operation_id=None, query_serializer=None):
    """
    快速生成 Swagger 文档的装饰器，简化 swagger_auto_schema 的使用
    
    参数:
        request_schema (serializers.Serializer): 请求体 Schema
        responses (dict): 响应 Schema 字典
        operation_description (str): 操作描述
        tags (list): 标签列表
        methods (list): 支持的方法列表，用于装饰 ViewSet 方法
        manual_parameters (list): 手动参数列表
        security (list): 认证设置
        operation_id (str): 操作 ID
        query_serializer (serializers.Serializer): 查询参数 Schema
    
    示例:
        @swagger_schema(
            request_schema=MyRequestSchema,
            responses={200: MyResponseSchema},
            operation_description="接口描述",
            tags=['标签'],
            security=[{'Bearer': []}]
        )
    """
    # 合并默认错误响应
    if responses:
        merged_responses = {**common_responses}
        for status_code, response in responses.items():
            merged_responses[status_code] = response
    else:
        merged_responses = common_responses
    
    # 构建参数
    kwargs = {
        'responses': merged_responses,
        'operation_description': operation_description
    }
    
    if request_schema:
        kwargs['request_body'] = request_schema
    
    if tags:
        kwargs['tags'] = tags
    
    if manual_parameters:
        kwargs['manual_parameters'] = manual_parameters
    
    if security:
        kwargs['security'] = security
    
    if operation_id:
        kwargs['operation_id'] = operation_id
    
    if query_serializer:
        kwargs['query_serializer'] = query_serializer
    
    if methods:
        return swagger_auto_schema(methods=methods, **kwargs)
    else:
        return swagger_auto_schema(**kwargs) 