import type { FastifyInstance } from 'fastify';
import { getAllServices, getServiceById, createService, updateService, deleteService } from './repository.js';
import { CreateServiceSchema, UpdateServiceSchema, ServiceParamsSchema } from './types.js';
import { requireAdmin, BadRequestError } from '../../lib/auth.js';
import { createAuditLog } from '../audit/repository.js';

export async function serviceRoutes(fastify: FastifyInstance) {
  // List all services
  fastify.get('/services', async (req, reply) => {
    const services = await getAllServices();
    return reply.send(services);
  });

  // Get single service
  fastify.get('/services/:id', async (req, reply) => {
    const params = ServiceParamsSchema.parse(req.params);
    const service = await getServiceById(params.id);
    if (!service) {
      return reply.code(404).send({ error: 'Service not found' });
    }
    return reply.send(service);
  });

  // Create service (admin only)
  fastify.post('/services', {
    preHandler: async (req) => requireAdmin(req),
  }, async (req, reply) => {
    try {
      const data = CreateServiceSchema.parse(req.body);
      const service = await createService(data);

      await createAuditLog({
        action: 'create',
        entityType: 'service',
        entityId: service.id,
        userId: (req as any).authUserId || 'unknown',
        role: (req as any).authRole || 'unknown',
        details: { serviceName: service.name },
      });

      return reply.code(201).send(service);
    } catch (error) {
      if (error instanceof Error) {
        throw new BadRequestError(error.message);
      }
      throw error;
    }
  });

  // Update service (admin only)
  fastify.put('/services/:id', {
    preHandler: async (req) => requireAdmin(req),
  }, async (req, reply) => {
    try {
      const params = ServiceParamsSchema.parse(req.params);
      const updates = UpdateServiceSchema.parse(req.body);
      const service = await updateService(params.id, updates);

      if (!service) {
        return reply.code(404).send({ error: 'Service not found' });
      }

      await createAuditLog({
        action: 'update',
        entityType: 'service',
        entityId: service.id,
        userId: (req as any).authUserId || 'unknown',
        role: (req as any).authRole || 'unknown',
        details: { serviceName: service.name, updates },
      });

      return reply.send(service);
    } catch (error) {
      if (error instanceof Error) {
        throw new BadRequestError(error.message);
      }
      throw error;
    }
  });

  // Delete service (admin only)
  fastify.delete('/services/:id', {
    preHandler: async (req) => requireAdmin(req),
  }, async (req, reply) => {
    const params = ServiceParamsSchema.parse(req.params);
    const deleted = await deleteService(params.id);

    if (!deleted) {
      return reply.code(404).send({ error: 'Service not found' });
    }

    await createAuditLog({
      action: 'delete',
      entityType: 'service',
      entityId: params.id,
      userId: (req as any).authUserId || 'unknown',
      role: (req as any).authRole || 'unknown',
      details: { serviceId: params.id },
    });

    return reply.code(204).send();
  });
}
