import { SessionInfo } from '@core/types'
import { CallHandler, ExecutionContext, Injectable, NestInterceptor, NotAcceptableException } from '@nestjs/common'
import { Observable } from 'rxjs'
import { SessionStore } from '../helpers'

/**
 * Multi-tenancy interceptor.
 *
 * This interceptor ensures that the tenant ID in the request headers matches the tenant ID
 * in the user's session. It verifies that:
 * 1. The user is authenticated and has a valid tenant ID
 * 2. The request contains a tenant ID header ('X-TENANT-ID')
 * 3. The tenant ID in the header matches the user's assigned tenant
 *
 * If any of these conditions fail, it throws NotAcceptableException.
 * After validation, it sets the user session using SessionService.
 *
 * This interceptor is crucial for maintaining proper multi-tenant data isolation
 * and preventing unauthorized cross-tenant access.
 */
@Injectable()
export class MultiTenancyInterceptor implements NestInterceptor {
	intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {
		const request = context.switchToHttp().getRequest()

		const user = request.user as SessionInfo
		if (!user || !user.tenantId) {
			throw new NotAcceptableException('USER NOT FOUND')
		}

		const tenantId = request.headers['X-TENANT-ID'] || request.headers['x-tenant-id']
		if (!tenantId) {
			throw new NotAcceptableException('TENANT NOT FOUND')
		}
		if (user.tenantId !== tenantId) {
			throw new NotAcceptableException('TENANT NOT VERIFIED')
		}
		SessionStore.set(user)

		return next.handle()
	}
}
