import { ReportDimension } from './report-dimension.enum';
import { DateRange } from './date-range.vo';

export class ReportParameters {
  private constructor(
    public readonly dateRange: DateRange,
    public readonly dimensions: ReportDimension[],
    public readonly filters: Record<string, any>,
    public readonly groupBy: string[],
    public readonly orderBy: { field: string; direction: 'ASC' | 'DESC' }[],
    public readonly pagination: { page: number; pageSize: number } | null,
  ) {}

  static create(params: {
    startDate: Date;
    endDate: Date;
    dimensions?: ReportDimension[];
    filters?: Record<string, any>;
    groupBy?: string[];
    orderBy?: { field: string; direction: 'ASC' | 'DESC' }[];
    page?: number;
    pageSize?: number;
  }): ReportParameters {
    return new ReportParameters(
      DateRange.create(params.startDate, params.endDate),
      params.dimensions || [],
      params.filters || {},
      params.groupBy || [],
      params.orderBy || [],
      params.page && params.pageSize
        ? { page: params.page, pageSize: params.pageSize }
        : null,
    );
  }

  withFilter(key: string, value: any): ReportParameters {
    return new ReportParameters(
      this.dateRange,
      this.dimensions,
      { ...this.filters, [key]: value },
      this.groupBy,
      this.orderBy,
      this.pagination,
    );
  }

  withDimension(dimension: ReportDimension): ReportParameters {
    return new ReportParameters(
      this.dateRange,
      [...this.dimensions, dimension],
      this.filters,
      this.groupBy,
      this.orderBy,
      this.pagination,
    );
  }

  hasFilter(key: string): boolean {
    return key in this.filters;
  }

  getFilter<T>(key: string, defaultValue?: T): T | undefined {
    return this.filters[key] ?? defaultValue;
  }
}
