import { CanActivate, ExecutionContext, ForbiddenException, Injectable } from '@nestjs/common';
import type { FastifyRequest } from 'fastify';
import type { AuthenticatedUser } from './authenticated-user';

type AuthenticatedRequest = FastifyRequest & { user?: AuthenticatedUser };

/**
 * A presentation/customer account may inspect every explicitly granted module
 * without changing any server-side state. This is deliberately global: a new
 * write route is protected by default instead of relying on its author to
 * remember one more decorator.
 */
@Injectable()
export class ReadOnlyGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest<AuthenticatedRequest>();
    const user = request.user;
    if (!user?.isReadOnly) return true;

    const method = request.method.toUpperCase();
    if (method === 'GET' || method === 'HEAD' || method === 'OPTIONS') return true;

    // A read-only user must still be able to end their own session.
    const path = request.url.split('?')[0];
    if (method === 'POST' && path.endsWith('/auth/logout')) return true;

    throw new ForbiddenException('Dieser zeitlich begrenzte Zugang ist schreibgeschützt.');
  }
}
