import { ApiProperty } from '@nestjs/swagger';
import { Transform } from 'class-transformer';
import { IsBoolean, IsEnum, IsInt, IsMongoId, IsNumber, IsOptional, IsString, Max, MaxLength, Min, MinLength } from 'class-validator';
import { CommissionType } from '../schema/product.schema';

const trim = ({ value }: { value: unknown }) => (typeof value === 'string' ? value.trim() : value);
const toBool = ({ value }: { value: unknown }) => (value === 'true' || value === true ? true : value === 'false' || value === false ? false : value);

export class CreateProductDto {
    @ApiProperty({ example: 'Elevate Health Shield' })
    @IsString()
    @MinLength(2)
    @MaxLength(120)
    @Transform(trim)
    name: string;

    @ApiProperty({ description: 'Category id (must be active)' })
    @IsMongoId()
    category_id: string;

    @ApiProperty({ description: 'Insurer id from the Insurer Directory (must be active and underwrite the category)' })
    @IsMongoId()
    insurer_id: string;

    @ApiProperty({ example: 18, description: 'GST rate for this product, percent' })
    @IsNumber()
    @Min(0)
    @Max(100)
    gst_rate: number;

    @ApiProperty({ enum: CommissionType, description: 'Commission we pay the agent: percentage of net premium, or flat amount per policy' })
    @IsEnum(CommissionType)
    commission_type: CommissionType;

    @ApiProperty({ example: 15, description: 'Percent (0 to 100) or rupees per policy, depending on commission_type' })
    @IsNumber()
    @Min(0)
    commission_value: number;
}

export class UpdateProductDto {
    @ApiProperty({ required: false })
    @IsOptional()
    @IsString()
    @MinLength(2)
    @MaxLength(120)
    @Transform(trim)
    name?: string;

    @ApiProperty({ required: false })
    @IsOptional()
    @IsMongoId()
    category_id?: string;

    @ApiProperty({ required: false })
    @IsOptional()
    @IsMongoId()
    insurer_id?: string;

    @ApiProperty({ required: false })
    @IsOptional()
    @IsNumber()
    @Min(0)
    @Max(100)
    gst_rate?: number;

    @ApiProperty({ required: false, enum: CommissionType })
    @IsOptional()
    @IsEnum(CommissionType)
    commission_type?: CommissionType;

    @ApiProperty({ required: false })
    @IsOptional()
    @IsNumber()
    @Min(0)
    commission_value?: number;

    @ApiProperty({ required: false, description: 'false stops the product being used for new policies' })
    @IsOptional()
    @IsBoolean()
    is_active?: boolean;
}

export class ProductListDto {
    @ApiProperty({ required: false, default: 1 })
    @IsOptional()
    @Transform(({ value }) => Number(value))
    @IsInt()
    @Min(1)
    page: number = 1;

    @ApiProperty({ required: false, default: 10 })
    @IsOptional()
    @Transform(({ value }) => Number(value))
    @IsInt()
    @Min(1)
    @Max(100)
    limit: number = 10;

    @ApiProperty({ required: false, description: 'Search by product name' })
    @IsOptional()
    @IsString()
    search?: string;

    @ApiProperty({ required: false })
    @IsOptional()
    @IsMongoId()
    category_id?: string;

    @ApiProperty({ required: false })
    @IsOptional()
    @IsMongoId()
    insurer_id?: string;

    @ApiProperty({ required: false, description: 'true or false' })
    @IsOptional()
    @Transform(toBool)
    @IsBoolean()
    is_active?: boolean;

    @ApiProperty({ required: false, description: 'Only products this agent may sell (their assigned categories). Policy Staff can sell everything.' })
    @IsOptional()
    @IsMongoId()
    assignee_id?: string;
}

export class CalculatePremiumDto {
    @ApiProperty({ example: 15000 })
    @Transform(({ value }) => Number(value))
    @IsNumber()
    @Min(0)
    gross_premium: number;
}
