import type { FastifyRequest, FastifyReply } from 'fastify';

export interface AuthDeps {
  findSession: (token: string) => Promise<{ userId: string; expiresAt: Date } | null>;
}

declare module 'fastify' {
  interface FastifyRequest {
    userId?: string;
    rbacScope?: { wildcard: boolean; names: Set<string> };
  }
}

export function createAuthMiddleware(deps: AuthDeps) {
  return async function authMiddleware(request: FastifyRequest, reply: FastifyReply): Promise<void> {
    const header = request.headers.authorization;
    if (header === undefined || !header.startsWith('Bearer ')) {
      reply.code(401).send({ error: 'Missing or invalid Authorization header' });
      return;
    }

    const token = header.slice(7);
    if (token.length === 0) {
      reply.code(401).send({ error: 'Empty token' });
      return;
    }

    const session = await deps.findSession(token);
    if (session === null) {
      reply.code(401).send({ error: 'Invalid token' });
      return;
    }

    if (session.expiresAt < new Date()) {
      reply.code(401).send({ error: 'Token expired' });
      return;
    }

    request.userId = session.userId;
  };
}
