import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import {
  IsOptional,
  IsInt,
  IsString,
  IsDateString,
  IsEnum,
  Min,
  Max,
  IsArray,
} from 'class-validator';
import { Type, Transform } from 'class-transformer';

/**
 * Query parameters for fetching orders
 */
export class GetOrdersQueryDto {
  @ApiPropertyOptional({ description: 'Order ID to search for' })
  @IsOptional()
  @IsInt()
  @Type(() => Number)
  orderId?: number;

  @ApiPropertyOptional({ description: 'Filter by order type' })
  @IsOptional()
  @IsInt()
  @Type(() => Number)
  orderType?: number;

  @ApiPropertyOptional({ description: 'Filter by referrer ID' })
  @IsOptional()
  @IsInt()
  @Type(() => Number)
  referrerId?: number;

  @ApiPropertyOptional({ description: 'Filter by status ID' })
  @IsOptional()
  @IsInt()
  @Type(() => Number)
  statusId?: number;

  @ApiPropertyOptional({ description: 'External order ID' })
  @IsOptional()
  @IsString()
  externalOrderId?: string;

  @ApiPropertyOptional({ description: 'Filter by creation date (from)' })
  @IsOptional()
  @IsDateString()
  createdAtFrom?: string;

  @ApiPropertyOptional({ description: 'Filter by creation date (to)' })
  @IsOptional()
  @IsDateString()
  createdAtTo?: string;

  @ApiPropertyOptional({ description: 'Page number', default: 1 })
  @IsOptional()
  @IsInt()
  @Min(1)
  @Type(() => Number)
  page?: number = 1;

  @ApiPropertyOptional({ description: 'Items per page', default: 50, maximum: 250 })
  @IsOptional()
  @IsInt()
  @Min(1)
  @Max(250)
  @Type(() => Number)
  itemsPerPage?: number = 50;

  @ApiPropertyOptional({
    description: 'Relations to include (comma-separated)',
    example: 'amounts,orderItems,addresses',
  })
  @IsOptional()
  @IsString()
  with?: string;
}

/**
 * Query parameters for fetching stock
 */
export class GetStockQueryDto {
  @ApiPropertyOptional({ description: 'Filter by variation ID' })
  @IsOptional()
  @IsInt()
  @Type(() => Number)
  variationId?: number;

  @ApiPropertyOptional({ description: 'Filter by item ID' })
  @IsOptional()
  @IsInt()
  @Type(() => Number)
  itemId?: number;

  @ApiPropertyOptional({ description: 'Filter by warehouse ID' })
  @IsOptional()
  @IsInt()
  @Type(() => Number)
  warehouseId?: number;

  @ApiPropertyOptional({ description: 'Page number', default: 1 })
  @IsOptional()
  @IsInt()
  @Min(1)
  @Type(() => Number)
  page?: number = 1;

  @ApiPropertyOptional({ description: 'Items per page', default: 50 })
  @IsOptional()
  @IsInt()
  @Min(1)
  @Max(250)
  @Type(() => Number)
  itemsPerPage?: number = 50;
}

/**
 * Query parameters for statistics
 */
export class GetStatsQueryDto {
  @ApiProperty({ description: 'Start date (YYYY-MM-DD)', example: '2024-01-01' })
  @IsDateString()
  dateFrom: string;

  @ApiProperty({ description: 'End date (YYYY-MM-DD)', example: '2024-01-31' })
  @IsDateString()
  dateTo: string;

  @ApiPropertyOptional({
    description: 'Group by period',
    enum: ['day', 'week', 'month'],
    default: 'day',
  })
  @IsOptional()
  @IsEnum(['day', 'week', 'month'])
  groupBy?: 'day' | 'week' | 'month' = 'day';

  @ApiPropertyOptional({ description: 'Filter by referrer ID' })
  @IsOptional()
  @IsInt()
  @Type(() => Number)
  referrerId?: number;

  @ApiPropertyOptional({ description: 'Filter by status ID' })
  @IsOptional()
  @IsInt()
  @Type(() => Number)
  statusId?: number;
}

// ============================================================================
// Response DTOs
// ============================================================================

export class OrderAmountResponseDto {
  @ApiProperty()
  currency: string;

  @ApiProperty()
  netTotal: number;

  @ApiProperty()
  grossTotal: number;

  @ApiProperty()
  vatTotal: number;

  @ApiProperty()
  paidAmount: number;

  @ApiProperty()
  shippingCostsGross: number;
}

export class OrderItemResponseDto {
  @ApiProperty()
  id: number;

  @ApiProperty()
  itemVariationId: number;

  @ApiProperty()
  quantity: number;

  @ApiProperty()
  orderItemName: string;

  @ApiPropertyOptional()
  priceGross?: number;

  @ApiPropertyOptional()
  priceNet?: number;
}

export class OrderResponseDto {
  @ApiProperty()
  id: number;

  @ApiProperty()
  typeId: number;

  @ApiProperty()
  statusId: number;

  @ApiPropertyOptional()
  statusName?: string;

  @ApiProperty()
  referrerId: number;

  @ApiProperty()
  createdAt: string;

  @ApiProperty()
  updatedAt: string;

  @ApiPropertyOptional({ type: [OrderAmountResponseDto] })
  amounts?: OrderAmountResponseDto[];

  @ApiPropertyOptional({ type: [OrderItemResponseDto] })
  orderItems?: OrderItemResponseDto[];
}

export class PaginatedOrdersResponseDto {
  @ApiProperty()
  page: number;

  @ApiProperty()
  totalsCount: number;

  @ApiProperty()
  isLastPage: boolean;

  @ApiProperty()
  itemsPerPage: number;

  @ApiProperty({ type: [OrderResponseDto] })
  entries: OrderResponseDto[];
}

export class StockItemResponseDto {
  @ApiProperty()
  itemId: number;

  @ApiProperty()
  variationId: number;

  @ApiProperty()
  warehouseId: number;

  @ApiPropertyOptional()
  warehouseName?: string;

  @ApiProperty()
  stockPhysical: number;

  @ApiProperty()
  reservedStock: number;

  @ApiProperty()
  stockNet: number;

  @ApiProperty()
  reorderDelta: number;

  @ApiProperty()
  updatedAt: string;
}

export class PaginatedStockResponseDto {
  @ApiProperty()
  page: number;

  @ApiProperty()
  totalsCount: number;

  @ApiProperty()
  isLastPage: boolean;

  @ApiProperty()
  itemsPerPage: number;

  @ApiProperty({ type: [StockItemResponseDto] })
  entries: StockItemResponseDto[];
}

export class OrderStatsResponseDto {
  @ApiProperty()
  totalOrders: number;

  @ApiProperty()
  totalRevenue: number;

  @ApiProperty()
  totalRevenueNet: number;

  @ApiProperty()
  averageOrderValue: number;

  @ApiProperty()
  currency: string;

  @ApiProperty({ type: 'object', additionalProperties: { type: 'number' } })
  ordersByStatus: Record<number, number>;

  @ApiProperty({ type: 'object', additionalProperties: { type: 'number' } })
  ordersByReferrer: Record<number, number>;
}

export class RevenueStatsResponseDto {
  @ApiProperty()
  date: string;

  @ApiProperty()
  ordersCount: number;

  @ApiProperty()
  itemsCount: number;

  @ApiProperty()
  revenue: number;

  @ApiProperty()
  revenueNet: number;

  @ApiProperty()
  currency: string;
}
