import { Injectable } from '@nestjs/common';
import { ClsService } from 'nestjs-cls';
import { CLS_USER_ID } from '../../common/cls/cls.constants';
import {
  getModuleVisibilityScopeFromCls,
  type RowVisibilityModule,
} from '../../common/auth/visibility';
import { type VisibleUserIds } from '../../common/auth/row-visibility';
import { UserRepository } from './repositories/user.repository';

/**
 * Resolves reporting-chain user ids for row-level visibility on
 * queries and bookings (manager sees direct + indirect reports).
 */
@Injectable()
export class UserReportingService {
  constructor(
    private readonly userRepo: UserRepository,
    private readonly cls: ClsService,
  ) {}

  async getDescendantUserIds(managerUserId: string): Promise<string[]> {
    return this.userRepo.findDescendantUserIds(managerUserId);
  }

  async expandWithReports(viewerUserId: string): Promise<string[]> {
    const descendants = await this.getDescendantUserIds(viewerUserId);
    return [viewerUserId, ...descendants];
  }

  /** Null = full visibility for the module; otherwise self + report chain. */
  async resolveVisibleUserIds(module: RowVisibilityModule): Promise<VisibleUserIds> {
    const scope = getModuleVisibilityScopeFromCls(this.cls, module);
    if (scope === 'all') return null;
    const viewer = this.cls.get<string>(CLS_USER_ID);
    if (!viewer) return [];
    return this.expandWithReports(viewer);
  }
}
