import { IsOptional, IsNumber, IsString, IsUUID, Min, Max } from 'class-validator';
import { Type } from 'class-transformer';

/**
 * Common pagination query params for all list endpoints.
 * Usage: @Query() query: PaginationDto
 *
 * API: GET /hotels?page=1&limit=10&search=burj&sortBy=name&sortOrder=ASC
 *
 * Note on filter pass-throughs: with `forbidNonWhitelisted: true` on
 * the global ValidationPipe, ANY query param not declared here would
 * 400 the request — including the filter fields that controllers
 * pull out via separate `@Query('foo')` decorators. The few filter
 * params that are common across the platform (notably `destination_id`,
 * since this is a multi-destination DMC and every list page filters
 * by destination) are declared here as @IsOptional pass-throughs so
 * shared list endpoints don't need a per-module list DTO just to
 * tolerate them. Module-specific filter params (e.g. `stage`,
 * `supplier_type`, `category`) live on per-module list DTOs that
 * extend this one.
 */
export class PaginationDto {
  @IsOptional()
  @Type(() => Number)
  @IsNumber()
  @Min(1)
  page?: number = 1;

  @IsOptional()
  @Type(() => Number)
  @IsNumber()
  @Min(1)
  @Max(100)
  limit?: number = 10;

  @IsOptional()
  @IsString()
  search?: string;

  @IsOptional()
  @IsString()
  sortBy?: string;

  @IsOptional()
  @IsString()
  sortOrder?: 'ASC' | 'DESC' = 'ASC';

  /**
   * Destination filter — universal across every list page driven
   * by the workspace top-bar destination picker. Declared here so
   * `@Query() query: PaginationDto` doesn't 400 when the FE passes
   * the picker's value through. Controllers that actually need it
   * still extract via `@Query('destination_id')`; this just keeps
   * the whitelist happy.
   */
  @IsOptional()
  @IsUUID()
  destination_id?: string;

  // ── Module-shared filter pass-throughs ─────────────────────────
  // Each is a query param sent by one or more list pages to a
  // controller that uses `@Query() query: PaginationDto`. With
  // forbidNonWhitelisted: true on the global pipe, undeclared params
  // 400 the request. Declaring them here as @IsOptional keeps the
  // whitelist happy; controllers continue to extract via their own
  // @Query('foo') decorators. Add new ones as we discover them — or
  // promote a module to its own list-query DTO when it grows enough
  // module-specific filters to warrant the separation.

  /** Queries module — query lifecycle stage filter. */
  @IsOptional() @IsString() stage?: string;

  /** Queries module — filter by trip source master. */
  @IsOptional() @IsUUID() source_id?: string;

  /** Queries module — filter by assigned salesperson. */
  @IsOptional() @IsUUID() assigned_to?: string;

  /** Bookings + Change-requests — booking lifecycle status filter. */
  @IsOptional() @IsString() status?: string;

  /** Suppliers list — filter by supplier_types[] entry (transport/activity). */
  @IsOptional() @IsString() supplier_type?: string;

  /** Transports + Activities — category filter (one_way / two_way / etc). */
  @IsOptional() @IsString() category?: string;

  /** Generic active/inactive filter — many list pages expose this toggle. */
  @IsOptional() @IsString() is_active?: string;

  /** Generic type filter — used by tax-types, service-types, vehicle-types lookups. */
  @IsOptional() @IsString() type?: string;

  /** Trip Sources list — `source_type` filter pill (agent / direct / etc). */
  @IsOptional() @IsString() source_type?: string;

  /** Trip Sources list — filter by the assigned Agent Cost rule. */
  @IsOptional() @IsUUID() agent_cost_id?: string;

  /** Drivers + Vehicles list — filter rows scoped to a single supplier. */
  @IsOptional() @IsUUID() supplier_id?: string;

  /** Users list — filter by manager (reports to). */
  @IsOptional() @IsUUID() reports_to?: string;
}

/**
 * Standard paginated response shape.
 * Returned by successResponse(data, message, meta)
 */
export interface PaginationMeta {
  total: number;
  page: number;
  limit: number;
  totalPages: number;
}

export interface PaginatedResult<T> {
  items: T[];
  meta: PaginationMeta;
}
