import type { FastifyInstance } from 'fastify';
import { z } from 'zod';
import { eq } from 'drizzle-orm';
import { tenants } from '../../db/schema/index.js';
import { slugify } from '@org/utils';

const createTenantBody = z.object({
  name: z.string().min(2).max(100),
  type: z.enum(['SCHOOL', 'COACHING', 'COLLEGE']),
});

const updateTenantBody = z.object({
  name: z.string().min(2).max(100).optional(),
  status: z.enum(['ACTIVE', 'INACTIVE']).optional(),
});

export default async function tenantRoutes(fastify: FastifyInstance) {
  const superAdminGuard = [fastify.authenticate, fastify.authorize(['SUPER_ADMIN'])];

  fastify.get('/', { preHandler: superAdminGuard }, async () => {
    return fastify.db.select().from(tenants).orderBy(tenants.createdAt);
  });

  fastify.post('/', { preHandler: superAdminGuard }, async (request, reply) => {
    const body = createTenantBody.parse(request.body);
    const slug = slugify(body.name);

    const existing = await fastify.db.select({ id: tenants.id }).from(tenants).where(eq(tenants.slug, slug)).limit(1);
    if (existing.length > 0) return reply.code(409).send({ error: 'Tenant with this name already exists' });

    const [tenant] = await fastify.db.insert(tenants).values({ name: body.name, slug, type: body.type }).returning();
    return reply.code(201).send(tenant);
  });

  fastify.patch('/:id', { preHandler: superAdminGuard }, async (request, reply) => {
    const { id } = request.params as { id: string };
    const body = updateTenantBody.parse(request.body);

    const [updated] = await fastify.db
      .update(tenants)
      .set({ ...body, updatedAt: new Date() })
      .where(eq(tenants.id, id))
      .returning();

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

  fastify.get('/:id', { preHandler: superAdminGuard }, async (request, reply) => {
    const { id } = request.params as { id: string };
    const [tenant] = await fastify.db.select().from(tenants).where(eq(tenants.id, id)).limit(1);
    if (!tenant) return reply.code(404).send({ error: 'Tenant not found' });
    return tenant;
  });
}
