import { PartialType } from '@nestjs/mapped-types';
import { Transform } from 'class-transformer';
import { IsIn, IsInt, IsOptional, IsString, Matches, MaxLength, Min } from 'class-validator';
import { DecimalString } from '../../../common/http/decimal.transform';

export const PORTFOLIO_TRANSACTION_TYPES = [
  'buy',
  'sell',
  'deposit',
  'withdrawal',
  'order-buy',
  'order-sell',
] as const;

export class CreatePortfolioTransactionDto {
  @IsIn(PORTFOLIO_TRANSACTION_TYPES)
  type!: (typeof PORTFOLIO_TRANSACTION_TYPES)[number];

  @Matches(/^\d{4}-\d{2}-\d{2}$/)
  date!: string;

  @IsOptional()
  @Transform(({ value }) => (typeof value === 'string' ? value.trim().toUpperCase() : value))
  @IsString()
  @Matches(/^[A-Z0-9._-]{1,30}$/)
  asset?: string;

  @IsOptional()
  @DecimalString()
  qty?: string | null;

  @IsOptional()
  @DecimalString()
  price?: string | null;

  @IsOptional()
  @Transform(({ value }) => (typeof value === 'string' ? value.trim().toUpperCase() : value))
  @IsString()
  @Matches(/^[A-Z]{2,12}$/)
  currency?: string;

  @IsOptional()
  @DecimalString()
  feeQty?: string | null;

  @IsOptional()
  @Transform(({ value }) => (typeof value === 'string' ? value.trim().toUpperCase() : value))
  @IsString()
  @Matches(/^[A-Z0-9._-]{1,30}$/)
  feeAsset?: string;

  @IsOptional()
  @DecimalString()
  cashAmount?: string | null;

  @IsOptional()
  @Transform(({ value }) => (typeof value === 'string' ? value.trim().toUpperCase() : value))
  @IsString()
  @Matches(/^[A-Z]{2,12}$/)
  cashCurrency?: string;

  @IsOptional()
  @IsString()
  @MaxLength(10_000)
  note?: string;
}

export class UpdatePortfolioTransactionDto extends PartialType(CreatePortfolioTransactionDto) {
  @IsInt()
  @Min(1)
  version!: number;
}
