import { BaseStatusDto } from 'src/core/modules/infrastructure/dto/base-status.dto';
import { ItemEntity } from '../../domain/entities/item.entity';
import { ItemType } from 'src/modules/item-related/item-category/constants';
import { LimitType } from '../../constants';
import { ApiProperty } from '@nestjs/swagger';
import {
  IsArray,
  IsBoolean,
  IsNumber,
  IsObject,
  IsString,
  ValidateIf,
} from 'class-validator';
import { ItemCategoryEntity } from 'src/modules/item-related/item-category/domain/entities/item-category.entity';
import { Transform } from 'class-transformer';

export class ItemDto extends BaseStatusDto implements ItemEntity {
  @ApiProperty({
    type: String,
    required: true,
    example: 'Entrace Ticket',
  })
  @IsString()
  name: string;

  @ApiProperty({
    type: String,
    required: false,
    example: '...',
  })
  @IsString()
  @ValidateIf((body) => body.image)
  image_url: string;

  @ApiProperty({
    isArray: true,
    required: false,
  })
  // @IsString()
  @ValidateIf((body) => body.video_url)
  @Transform(({ value }) => {
    if (!value) return [];
    return Array.isArray(value) ? value : [value];
  })
  video_url: string[];

  @ApiProperty({
    type: 'string',
    required: true,
    description: `Select (${JSON.stringify(Object.values(ItemType))})`,
    example: ItemType.BUNDLING,
  })
  @IsString()
  item_type: ItemType;

  @ApiProperty({
    type: Object,
    required: false,
    example: {
      id: 'uuid',
    },
  })
  @IsObject()
  @ValidateIf((body) => body.item_category)
  item_category: ItemCategoryEntity;

  @ApiProperty({
    type: Number,
    required: false,
    example: 100000,
  })
  @IsNumber()
  @ValidateIf((body) => body.item_type.toLowerCase() != ItemType.FREE_GIFT)
  hpp: number;

  @ApiProperty({
    type: Number,
    required: false,
    example: 50,
  })
  @IsNumber()
  @ValidateIf(
    (body) =>
      ![ItemType.FREE_GIFT, ItemType.BUNDLING].includes(
        body.item_type.toLowerCase(),
      ),
  )
  sales_margin: number;

  @ApiProperty({
    type: Number,
    required: false,
    example: 100000,
  })
  @IsNumber()
  @ValidateIf((body) => body.item_type.toLowerCase() == ItemType.BUNDLING)
  total_price: number;

  @ApiProperty({
    type: Number,
    required: false,
    example: 100000,
  })
  @IsNumber()
  @ValidateIf((body) => body.item_type.toLowerCase() != ItemType.FREE_GIFT)
  base_price: number;

  @ApiProperty({
    type: 'string',
    required: false,
    description: `Select (${JSON.stringify(Object.values(LimitType))})`,
    example: LimitType.NO_LIMIT,
  })
  @IsString()
  @ValidateIf((body) => body.item_type.toLowerCase() == ItemType.WAHANA)
  limit_type: LimitType;

  @ApiProperty({
    type: Number,
    required: false,
    example: 60,
  })
  @IsNumber()
  @ValidateIf(
    (body) =>
      body.item_type.toLowerCase() == ItemType.WAHANA &&
      body.limit_type.toLowerCase() != LimitType.NO_LIMIT,
  )
  limit_value: number;

  @ApiProperty({ type: Boolean, required: false })
  @IsBoolean()
  @ValidateIf((body) => body.use_queue)
  use_queue: boolean;

  @ApiProperty({ type: Boolean, required: false })
  @IsBoolean()
  @ValidateIf((body) => body.show_to_booking)
  show_to_booking: boolean;

  @ApiProperty({
    type: String,
    required: false,
    example: '...',
  })
  @ValidateIf((body) => body.show_to_booking)
  @IsString({
    message: 'Booking description is required when show to booking is enabled.',
  })
  booking_description: string;

  @ApiProperty({
    name: 'bundling_items',
    type: [Object],
    example: [
      {
        id: 'uuid',
      },
    ],
  })
  @IsArray({
    message: (body) => {
      const value = body.value;
      if (!value || value?.length === 0) {
        return 'Product bundling tidak boleh kosong.';
      }
      return 'Product bundling tidak sesuai.';
    },
  })
  @ValidateIf((body) => body.item_type.toLowerCase() == ItemType.BUNDLING)
  bundling_items: ItemEntity[];
}
