import { Module } from '@nestjs/common';
import { ClsModule } from 'nestjs-cls';
import { randomUUID } from 'node:crypto';
import type { Request, Response } from 'express';
import type { WorkspaceClsStore } from './workspace.types';
import { WorkspacePrismaPool } from './workspace-prisma-pool.service';

// CLS middleware roda ANTES dos guards (ordem NestJS).
// Aqui: apenas requestId + idEmpresa default (0 = não autenticado).
// JwtAuthGuard atualiza idEmpresa, userId e prisma após validar o token.
// CODING-RULES PGD-DB-009: prisma via cls.get('prisma'), nunca singleton.
// CODING-RULES PGD-AUTHZ-002: idEmpresa real vem do JWT (guard), não do env.
// ADR 0006 revogado: workspaceId: string → idEmpresa: number

@Module({
  imports: [
    ClsModule.forRootAsync({
      global: true,
      useFactory: () => ({
        middleware: {
          mount: true,
          generateId: true,
          idGenerator: (req: Request) => {
            const fromPino = (req as Request & { id?: unknown }).id;
            if (typeof fromPino === 'string' && fromPino.length > 0) return fromPino;
            const headerVal = req.headers['x-request-id'];
            return typeof headerVal === 'string' && headerVal.length > 0 ? headerVal : randomUUID();
          },
          setup: (cls, req: Request, res: Response) => {
            const store = cls as unknown as {
              set: <K extends keyof WorkspaceClsStore>(key: K, value: WorkspaceClsStore[K]) => void;
              getId: () => string;
            };

            const requestId = store.getId();
            res.setHeader('x-request-id', requestId);
            store.set('requestId', requestId);
            // Fallback para rotas públicas (ping, health). Guard sobrescreve em rotas protegidas.
            store.set('idEmpresa', 0);
          },
        },
      }),
    }),
  ],
  providers: [WorkspacePrismaPool],
  exports: [ClsModule, WorkspacePrismaPool],
})
export class WorkspaceModule {}
