import { Brackets, type ObjectLiteral, type SelectQueryBuilder } from 'typeorm';

/**
 * User ids the current viewer may see for "own" scope queries/bookings:
 * self plus all direct/indirect reports. Null = no filter (full visibility).
 */
export type VisibleUserIds = string[] | null;

export function applyQueryRowVisibility(
  qb: SelectQueryBuilder<ObjectLiteral>,
  queryAlias: string,
  visibleUserIds: VisibleUserIds,
): void {
  if (visibleUserIds === null) return;
  if (visibleUserIds.length === 0) {
    qb.andWhere('1 = 0');
    return;
  }
  qb.andWhere(
    new Brackets((sub) => {
      sub
        .where(`${queryAlias}.created_by IN (:...visibleUserIds)`, { visibleUserIds })
        .orWhere(
          `EXISTS (SELECT 1 FROM jsonb_array_elements_text(${queryAlias}.sales_team) elem WHERE elem IN (:...visibleUserIds))`,
          { visibleUserIds },
        );
    }),
  );
}

export function applyBookingRowVisibility(
  qb: SelectQueryBuilder<ObjectLiteral>,
  bookingAlias: string,
  queryAlias: string,
  visibleUserIds: VisibleUserIds,
): void {
  if (visibleUserIds === null) return;
  if (visibleUserIds.length === 0) {
    qb.andWhere('1 = 0');
    return;
  }
  qb.andWhere(
    new Brackets((sub) => {
      sub
        .where(`${bookingAlias}.created_by IN (:...visibleUserIds)`, { visibleUserIds })
        .orWhere(`${queryAlias}.created_by IN (:...visibleUserIds)`, { visibleUserIds })
        .orWhere(
          `EXISTS (SELECT 1 FROM jsonb_array_elements_text(${queryAlias}.sales_team) elem WHERE elem IN (:...visibleUserIds))`,
          { visibleUserIds },
        );
    }),
  );
}

/** Raw SQL fragment params for single-row visibility checks. */
export function queryVisibilitySql(tableAlias: string): string {
  return `(
    ${tableAlias}.created_by = ANY($3::uuid[])
    OR EXISTS (
      SELECT 1 FROM jsonb_array_elements_text(${tableAlias}.sales_team) elem
      WHERE elem = ANY($3::text[])
    )
  )`;
}

export function bookingVisibilitySql(bookingAlias: string, queryAlias: string): string {
  return `(
    ${bookingAlias}.created_by = ANY($3::uuid[])
    OR ${queryAlias}.created_by = ANY($3::uuid[])
    OR EXISTS (
      SELECT 1 FROM jsonb_array_elements_text(${queryAlias}.sales_team) elem
      WHERE elem = ANY($3::text[])
    )
  )`;
}
