// 1. 导入依赖
require('dotenv').config(); // 尽早加载环境变量
const fastify = require('fastify')({ logger: true }); // 开启日志，方便调试
const { ObjectId } = require('mongodb'); // 导入 ObjectId 用于ID操作

// 2. 注册 MongoDB 插件
// Fastify 的插件系统能确保在路由处理前，数据库连接已经准备就绪
fastify.register(require('./db-connector'));

// ------------------- API 路由定义 -------------------

/**
 * @api {post} /todos 创建一个新的 Todo
 */
fastify.post('/todos', async (request, reply) => {
  // fastify.mongo.db 是由我们的插件注入的
  const todosCollection = fastify.mongo.db.collection('todos');
  
  // 从请求体中获取数据
  const { text, completed = false } = request.body;

  if (!text) {
    return reply.code(400).send({ message: '`text` 字段是必需的。' });
  }

  const newTodo = {
    text,
    completed,
    createdAt: new Date(),
  };

  const result = await todosCollection.insertOne(newTodo);
  reply.code(201).send(result); // 201 Created
});

/**
 * @api {get} /todos 获取所有 Todos
 */
fastify.get('/todos', async (request, reply) => {
  const todosCollection = fastify.mongo.db.collection('todos');
  const todos = await todosCollection.find({}).toArray();
  reply.send(todos);
});

/**
 * @api {get} /todos/:id 获取单个 Todo
 */
fastify.get('/todos/:id', async (request, reply) => {
  const { id } = request.params;
  
  // 校验 ID 格式是否正确
  if (!ObjectId.isValid(id)) {
    return reply.code(400).send({ message: '无效的ID格式。' });
  }

  const objectId = new ObjectId(id);
  const todosCollection = fastify.mongo.db.collection('todos');
  const todo = await todosCollection.findOne({ _id: objectId });

  if (!todo) {
    return reply.code(404).send({ message: '未找到指定的 Todo。' });
  }

  reply.send(todo);
});

/**
 * @api {put} /todos/:id 更新一个 Todo
 */
fastify.put('/todos/:id', async (request, reply) => {
  const { id } = request.params;
  const { text, completed } = request.body;

  if (!ObjectId.isValid(id)) {
    return reply.code(400).send({ message: '无效的ID格式。' });
  }

  const objectId = new ObjectId(id);
  const todosCollection = fastify.mongo.db.collection('todos');

  const updateDoc = { $set: {} };
  if (text !== undefined) updateDoc.$set.text = text;
  if (completed !== undefined) updateDoc.$set.completed = completed;

  // 如果没有提供任何更新字段，则返回错误
  if (Object.keys(updateDoc.$set).length === 0) {
    return reply.code(400).send({ message: '请提供需要更新的字段 (text 或 completed)。' })
  }

  const result = await todosCollection.updateOne({ _id: objectId }, updateDoc);

  if (result.matchedCount === 0) {
    return reply.code(404).send({ message: '未找到指定的 Todo 进行更新。' });
  }
  
  reply.send({ message: 'Todo 更新成功。' });
});

/**
 * @api {delete} /todos/:id 删除一个 Todo
 */
fastify.delete('/todos/:id', async (request, reply) => {
  const { id } = request.params;

  if (!ObjectId.isValid(id)) {
    return reply.code(400).send({ message: '无效的ID格式。' });
  }

  const objectId = new ObjectId(id);
  const todosCollection = fastify.mongo.db.collection('todos');
  const result = await todosCollection.deleteOne({ _id: objectId });

  if (result.deletedCount === 0) {
    return reply.code(404).send({ message: '未找到指定的 Todo 进行删除。' });
  }

  reply.code(200).send({ message: 'Todo 删除成功。' });
});

// 3. 启动服务器
const start = async () => {
  try {
    await fastify.listen({ port: 3000 });
    fastify.log.info(`服务器运行在 ${fastify.server.address().port}`);
  } catch (err) {
    fastify.log.error(err);
    process.exit(1);
  }
};

start();