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

const deviceService = new DeviceService();

export async function deviceRoutes(app: FastifyInstance): Promise<void> {
  app.addHook('preHandler', authMiddleware);

  app.post('/api/devices/register', async (request, reply) => {
    try {
      const { device_name, device_fingerprint, public_key } = request.body as {
        device_name: string;
        device_fingerprint: string;
        public_key: string;
      };

      if (!device_name || !device_fingerprint) {
        return reply.status(400).send({
          success: false, error: 'VALIDATION_ERROR',
          message: 'device_name and device_fingerprint are required',
        });
      }

      const device = await deviceService.registerDevice(request.user!.user_id, {
        device_name, device_fingerprint,
        public_key: public_key || '',
      });

      return reply.send({ success: true, data: device });
    } catch (err: any) {
      if (err.message === 'DEVICE_ALREADY_EXISTS') {
        return reply.status(409).send({
          success: false, error: 'DEVICE_ALREADY_EXISTS',
          message: 'Device already registered',
        });
      }
      throw err;
    }
  });

  app.get('/api/devices', async (request, reply) => {
    const devices = await deviceService.getUserDevices(request.user!.user_id);
    return reply.send({ success: true, data: devices });
  });

  app.patch('/api/devices/:id/status', async (request, reply) => {
    const { id } = request.params as { id: string };
    const { status } = request.body as { status: 'online' | 'offline' };

    if (!status || !['online', 'offline'].includes(status)) {
      return reply.status(400).send({
        success: false, error: 'VALIDATION_ERROR',
        message: 'Status must be "online" or "offline"',
      });
    }

    const device = await deviceService.updateDeviceStatus(parseInt(id), status);
    if (!device) {
      return reply.status(404).send({
        success: false, error: 'DEVICE_NOT_FOUND',
        message: 'Device not found',
      });
    }

    return reply.send({ success: true, data: device });
  });

  app.delete('/api/devices/:id', async (request, reply) => {
    const { id } = request.params as { id: string };
    const deleted = await deviceService.deleteDevice(parseInt(id), request.user!.user_id);

    if (!deleted) {
      return reply.status(404).send({
        success: false, error: 'DEVICE_NOT_FOUND',
        message: 'Device not found',
      });
    }

    return reply.send({ success: true, message: 'Device deleted' });
  });

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