import { ActivityLogType, Permission } from '@pulse/shared';
import { eq } from 'drizzle-orm';
import { z } from 'zod';
import { db } from '../../db';
import { fallbackUsersToDefaultRole } from '../../db/mutations/users';
import { publishRole } from '../../db/publishers';
import { getRole } from '../../db/queries/roles';
import { roles } from '../../db/schema';
import { enqueueActivityLog } from '../../queues/activity-log';
import { invariant } from '../../utils/invariant';
import { protectedProcedure } from '../../utils/trpc';

const deleteRoleRoute = protectedProcedure
  .input(
    z.object({
      roleId: z.number()
    })
  )
  .mutation(async ({ input, ctx }) => {
    await ctx.needsPermission(Permission.MANAGE_ROLES);

    invariant(ctx.activeServerId, {
      code: 'BAD_REQUEST',
      message: 'No active server'
    });

    const role = await getRole(input.roleId);

    invariant(role, {
      code: 'NOT_FOUND',
      message: 'Role not found'
    });

    invariant(role.serverId === ctx.activeServerId, {
      code: 'NOT_FOUND',
      message: 'Role not found in this server'
    });
    invariant(!role.isPersistent, {
      code: 'FORBIDDEN',
      message: 'Cannot delete a persistent role'
    });
    invariant(!role.isDefault, {
      code: 'FORBIDDEN',
      message: 'Cannot delete the default role'
    });

    await fallbackUsersToDefaultRole(role.id);
    await db.delete(roles).where(eq(roles.id, role.id));

    publishRole(role.id, 'delete', role.serverId);
    enqueueActivityLog({
      type: ActivityLogType.DELETED_ROLE,
      userId: ctx.user.id,
      details: {
        roleId: role.id,
        roleName: role.name
      }
    });
  });

export { deleteRoleRoute };
