import { FastifyInstance } from 'fastify';
import { NodeService } from '../services/node.service';
import { authMiddleware, adminMiddleware } from '../middleware/auth';

const nodeService = new NodeService();

export async function nodeRoutes(app: FastifyInstance): Promise<void> {
  app.post('/api/nodes/register', async (request, reply) => {
    try {
      const { name, host, port } = request.body as { name: string; host: string; port: number };
      if (!name || !host || !port) {
        return reply.status(400).send({
          success: false, error: 'VALIDATION_ERROR',
          message: 'name, host, and port are required',
        });
      }
      const node = await nodeService.registerNode({ name, host, port });
      return reply.send({ success: true, data: node });
    } catch (err) { throw err; }
  });

  app.post('/api/nodes/heartbeat', async (request, reply) => {
    const { node_id, load, status } = request.body as {
      node_id: number; load: number; status: 'online' | 'offline' | 'busy';
    };
    if (!node_id) {
      return reply.status(400).send({
        success: false, error: 'VALIDATION_ERROR', message: 'node_id is required',
      });
    }
    const node = await nodeService.heartbeat(node_id, { load: load ?? 0, status: status ?? 'online' });
    if (!node) {
      return reply.status(404).send({
        success: false, error: 'NODE_NOT_FOUND', message: 'Node not found',
      });
    }
    return reply.send({ success: true, data: node });
  });

  app.get('/api/nodes', { preHandler: [authMiddleware] }, async (_request, reply) => {
    const nodes = await nodeService.getAllNodes();
    return reply.send({ success: true, data: nodes });
  });

  app.get('/api/nodes/available', { preHandler: [authMiddleware] }, async (_request, reply) => {
    const nodes = await nodeService.getAvailableNodes();
    return reply.send({ success: true, data: nodes });
  });

  app.get('/api/admin/nodes', { preHandler: [authMiddleware, adminMiddleware] }, async (_request, reply) => {
    const nodes = await nodeService.getAllNodes();
    return reply.send({ success: true, data: nodes });
  });

  app.delete('/api/admin/nodes/:id', { preHandler: [authMiddleware, adminMiddleware] }, async (request, reply) => {
    const { id } = request.params as { id: string };
    const deleted = await nodeService.deleteNode(parseInt(id));
    if (!deleted) {
      return reply.status(404).send({
        success: false, error: 'NODE_NOT_FOUND', message: 'Node not found',
      });
    }
    return reply.send({ success: true, message: 'Node deleted' });
  });
}
