import type { FastifyInstance } from 'fastify';
import { authenticate, requireRole } from '../middleware/auth.js';
import { companyService } from '../services/companyService.js';
import { authService } from '../services/authService.js';
import { auditService } from '../services/auditService.js';
import { ticketService } from '../services/ticketService.js';

const staff = [authenticate, requireRole('admin', 'user')];

export async function companyRoutes(fastify: FastifyInstance) {
  fastify.get('/', { preHandler: staff }, async (_req, reply) => {
    return reply.send(await companyService.list());
  });

  fastify.post('/', { preHandler: staff }, async (req, reply) => {
    const { name } = req.body as { name: string };
    if (!name?.trim()) return reply.status(400).send({ error: 'name is required' });
    const c = await companyService.create(name);
    await auditService.log(req.user!.sub, 'user', 'company.created', 'company', c.id, { name: c.name });
    return reply.status(201).send(c);
  });

  fastify.get('/:id', { preHandler: staff }, async (req, reply) => {
    const { id } = req.params as { id: string };
    const company = await companyService.getById(id);
    if (!company) return reply.status(404).send({ error: 'Company not found' });
    const aggregates = await companyService.getDetailAggregates(id);
    const tickets = await ticketService.list({ companyId: id, limit: 200, offset: 0 });
    return reply.send({ ...company, ...aggregates, tickets });
  });

  fastify.patch('/:id', { preHandler: staff }, async (req, reply) => {
    const { id } = req.params as { id: string };
    const { name } = req.body as { name: string };
    if (!name?.trim()) return reply.status(400).send({ error: 'name is required' });
    const c = await companyService.updateName(id, name);
    if (!c) return reply.status(404).send({ error: 'Company not found' });
    await auditService.log(req.user!.sub, 'user', 'company.updated', 'company', id, { name });
    return reply.send(c);
  });

  fastify.post('/:id/users', { preHandler: staff }, async (req, reply) => {
    const { id } = req.params as { id: string };
    const { email, password, display_name } = req.body as {
      email: string;
      password: string;
      display_name?: string | null;
    };
    if (!email || !password) {
      return reply.status(400).send({ error: 'email and password are required' });
    }
    const company = await companyService.getById(id);
    if (!company) return reply.status(404).send({ error: 'Company not found' });
    try {
      const user = await authService.createCompanyPortalUser(email, password, id, display_name);
      await auditService.log(req.user!.sub, 'user', 'company.portal_user_created', 'user', user.id, {
        email,
        companyId: id,
      });
      return reply.status(201).send(user);
    } catch (e: unknown) {
      const err = e as { message?: string };
      return reply.status(409).send({ error: err.message ?? 'Conflict' });
    }
  });
}
