from flask import request
from flask_restx import Resource, Namespace, fields
from app.service.task_service import TaskService
from app.utils.jwt_utils import token_required
from app.utils.logger import Logger, log_request_info
from app import db  # 从 app/__init__.py 导入 db

# 1. 创建 API 命名空间，用于组织相关的路由
api = Namespace('tasks', description='Task related operations')

# 2. 定义 DTO (Data Transfer Objects) / API Models
# 用于请求体解析和响应体序列化
task_model = api.model('Task', {
    'id': fields.Integer(readOnly=True, description='The task unique identifier'),
    'title': fields.String(required=True, description='The task title'),
    'description': fields.String(description='The task description'),
    'done': fields.Boolean(description='The task status', default=False)
})

task_input_model = api.model('TaskInput', {
    'title': fields.String(required=True, description='The task title'),
    'description': fields.String(description='The task description'),
})

# 3. 创建资源类，每个类对应一个资源，并绑定 HTTP 方法
@api.route('/')
class TaskListResource(Resource):
    @token_required
    @api.marshal_list_with(task_model)  # 定义响应的 Swagger 文档
    @log_request_info
    def get(self):
        """获取所有任务列表"""
        Logger.info("获取任务列表")
        service = TaskService(db.session)
        tasks = service.get_all_tasks()
        
        Logger.info("任务列表获取成功", {
            'task_count': len(tasks)
        })
        
        return [task.to_dict() for task in tasks]

    @token_required
    @api.expect(task_input_model, validate=True)  # 定义请求体的 Swagger 文档并验证
    @api.marshal_with(task_model, code=201)       # 定义成功响应的 Swagger 文档
    @log_request_info
    def post(self):
        """创建一个新任务"""
        data = request.get_json()
        service = TaskService(db.session)
        
        Logger.info("创建新任务", {
            'title': data.get('title'),
            'description': data.get('description')
        })
        
        try:
            new_task = service.create_new_task(title=data['title'], description=data.get('description'))
            
            Logger.info("任务创建成功", {
                'task_id': new_task.id,
                'title': new_task.title
            })
            
            return new_task.to_dict(), 201
        except ValueError as e:
            Logger.warning("任务创建失败", {
                'title': data.get('title'),
                'error': str(e)
            })
            api.abort(400, str(e))

@api.route('/<int:task_id>')
class TaskResource(Resource):
    @token_required
    @api.marshal_with(task_model)
    @api.response(404, 'Task not found')
    def get(self, task_id):
        """根据 ID 获取单个任务"""
        service = TaskService(db.session)
        try:
            task = service.get_task_by_id(task_id)
            return task.to_dict()
        except ValueError as e:
            api.abort(404, str(e))

    @token_required
    @api.expect(task_input_model)
    @api.marshal_with(task_model)
    @api.response(404, 'Task not found')
    def put(self, task_id):
        """根据 ID 更新一个已存在的任务"""
        data = request.get_json()
        service = TaskService(db.session)
        try:
            updated_task = service.update_existing_task(
                task_id=task_id,
                title=data.get('title'),
                description=data.get('description'),
                done=data.get('done')
            )
            return updated_task.to_dict()
        except ValueError as e:
            api.abort(404, str(e))

    @token_required
    @api.response(204, 'Task deleted')
    @api.response(404, 'Task not found')
    def delete(self, task_id):
        """根据 ID 删除一个任务"""
        service = TaskService(db.session)
        try:
            service.delete_task(task_id)
            return '', 204
        except ValueError as e:
            api.abort(404, str(e))
