import {
  Injectable,
  CanActivate,
  ExecutionContext,
  UnauthorizedException,
  ForbiddenException,
} from '@nestjs/common';
import { PrismaService } from '@chatapp/database';

/**
 * WorkspaceGuard:
 * 1. Extrae el workspaceId del header `X-Workspace-Id` (o de request.workspace setado por middleware).
 * 2. Verifica que el usuario autenticado es miembro activo del workspace.
 * 3. Setea `request.workspace = { id, role }` para que RolesGuard y el decorador @Workspace funcionen.
 *
 * Esto resuelve la vulnerabilidad CRÍTICA donde el workspace se aceptaba solo del header
 * sin validar membresía, permitiendo acceso a cualquier workspace.
 */
@Injectable()
export class WorkspaceGuard implements CanActivate {
  constructor(private readonly prisma: PrismaService) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest();
    const userId = request.user?.userId;

    if (!userId) {
      throw new UnauthorizedException('Authentication required');
    }

    const wsId = request.workspace?.id || request.headers['x-workspace-id'];
    if (!wsId || typeof wsId !== 'string') {
      throw new ForbiddenException('X-Workspace-Id header is required');
    }

    // Validar que el workspace existe
    const workspace = await this.prisma.workspace.findUnique({
      where: { id: wsId },
      select: { id: true },
    });

    if (!workspace) {
      throw new ForbiddenException('Workspace not found');
    }

    // Validar membresía activa del usuario
    const membership = await this.prisma.workspaceMember.findFirst({
      where: {
        userId,
        workspaceId: wsId,
        deactivatedAt: null,
      },
      select: { role: true },
    });

    if (!membership) {
      throw new ForbiddenException('You are not a member of this workspace');
    }

    // Setear request.workspace con id y role para RolesGuard y el decorador @Workspace
    request.workspace = {
      id: wsId,
      role: membership.role,
    };

    return true;
  }
}