import { ApiProperty } from "@nestjs/swagger"
import {
  IsNotEmpty,
  IsEnum,
  IsNumber,
  IsDateString,
  IsOptional,
  Min,
  ValidateIf,
  IsString,
} from "class-validator"
import { Transform } from "class-transformer"
import { validationMessage } from "../../../utils/helpers"
import { messageKey } from "../../../constants/message-keys"
import { PartyTypeCategory } from "../entities/party-type.entity"
import { PaymentTypeEnum } from "../enums/payment-type.enum"

export class UpsertPartyPaymentDto {
  @ApiProperty({
    description: "Party Type Category",
    example: "CONTRACTOR",
    enum: PartyTypeCategory,
  })
  @IsNotEmpty({
    message: validationMessage(messageKey.field_required, {
      ":field": "party_type",
    }),
  })
  @IsEnum(PartyTypeCategory, {
    message: validationMessage(messageKey.field_enum_validation_error, {
      ":field": "party_type",
      ":values": "CONTRACTOR, VENDOR, CONSULTANT",
    }),
  })
  party_type: PartyTypeCategory

  @ApiProperty({
    description: "Payment Type",
    example: "MONTHLY",
    enum: PaymentTypeEnum,
  })
  @IsNotEmpty({
    message: validationMessage(messageKey.field_required, {
      ":field": "payment_type",
    }),
  })
  @IsEnum(PaymentTypeEnum, {
    message: validationMessage(messageKey.field_enum_validation_error, {
      ":field": "payment_type",
      ":values": "FIXED, MONTHLY",
    }),
  })
  payment_type: PaymentTypeEnum

  @ApiProperty({
    description: "Payment Amount",
    example: 25000,
  })
  @IsNotEmpty({
    message: validationMessage(messageKey.field_required, {
      ":field": "amount",
    }),
  })
  @IsNumber(
    { maxDecimalPlaces: 2 },
    {
      message: validationMessage(messageKey.field_type_validation_error, {
        ":field": "amount",
        ":type": "number",
      }),
    },
  )
  @Min(0.01, {
    message: validationMessage(messageKey.field_min_validation_error, {
      ":field": "amount",
      ":min": "0.01",
    }),
  })
  @Transform(({ value }) => parseFloat(value))
  amount: number

  @ApiProperty({
    description: "Payment Start Date",
    example: "2026-01-27",
  })
  @IsOptional()
  @IsDateString(
    {},
    {
      message: validationMessage(messageKey.field_type_validation_error, {
        ":field": "start_date",
        ":type": "date string (YYYY-MM-DD)",
      }),
    },
  )
  start_date?: string

  @ApiProperty({
    description: "Payment End Date (Optional)",
    example: null,
    required: false,
  })
  @IsOptional()
  @ValidateIf((o) => o.end_date !== null && o.end_date !== undefined)
  @IsDateString(
    {},
    {
      message: validationMessage(messageKey.field_type_validation_error, {
        ":field": "end_date",
        ":type": "date string (YYYY-MM-DD)",
      }),
    },
  )
  end_date?: string

  @ApiProperty({
    description: "Company ID",
    example: 1,
  })
  @IsNotEmpty({
    message: validationMessage(messageKey.field_required, {
      ":field": "company_id",
    }),
  })
  @IsNumber(
    {},
    {
      message: validationMessage(messageKey.field_type_validation_error, {
        ":field": "company_id",
        ":type": "number",
      }),
    },
  )
  @Transform(({ value }) => parseInt(value))
  company_id: number

  @ApiProperty({
    description: "Project ID (Optional)",
    example: 10,
    required: false,
  })
  @IsOptional()
  @IsNumber(
    {},
    {
      message: validationMessage(messageKey.field_type_validation_error, {
        ":field": "project_id",
        ":type": "number",
      }),
    },
  )
  @Transform(({ value }) => (value ? parseInt(value) : null))
  project_id?: number

  @ApiProperty({
    description: "Notes (Optional)",
    example: "Payment for the month of January 2026",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "notes",
      ":type": "string",
    }),
  })
  notes?: string

  @ApiProperty({
    description: "Paid Date (Optional)",
    example: "2026-01-27",
    required: false,
  })
  @IsOptional()
  @IsDateString(
    {},
    {
      message: validationMessage(messageKey.field_type_validation_error, {
        ":field": "paid_date",
        ":type": "date string (YYYY-MM-DD)",
      }),
    },
  )
  paid_date?: string
}
