import { DefaultValue } from '@humand-packages/common';
import { Expose, Transform, Type } from 'class-transformer';
import {
    ArrayMinSize,
    IsArray,
    IsBoolean,
    IsDateString,
    IsDefined,
    IsIn,
    IsNumber,
    IsOptional,
    IsString,
    Max,
    Min,
    MaxLength,
    ValidateIf,
    IsInt,
    ValidateNested,
} from 'class-validator';
import { GROUP_MEMBER_POLICIES } from '../../../regions/business/types/regions';
import {
    MAX_AUTO_CLOSE_LIMIT_HOURS,
    MIN_AUTO_CLOSE_LIMIT_HOURS,
    MIN_AUTO_CLOSE_FIXED_HOURS_VALUE,
    MAX_AUTO_CLOSE_FIXED_HOURS_VALUE,
    MAX_AUTO_CLOSE_FIXED_MINUTES_VALUE,
    MIN_AUTO_CLOSE_FIXED_MINUTES_VALUE,
} from '../../business/constants/timeTrackingPolicy';
import { TimeTrackingPolicyAutoCloseMode } from '../../business/enum/timeTracking/policy';
import { AutoCloseLimitHoursValidator } from './decorators/autoCloseLimitHoursValidator';
import { TimeTrackingPolicyHourCategoryForCreationVC } from './TimeTrackingPolicyHourCategoryForCreationVC';
import { TimeTrackingApprovalUsersGatheringVC } from './updateTimeTrackingApprovalUsersVC';

export const MAX_LATENESS_TOLERANCE = 240;
export const MIN_LATENESS_TOLERANCE = 0;
export const DEFAULT_LATENESS_TOLERANCE = 10;

export class TimeTrackingPoliciesCreationVC {
    @IsDefined()
    @IsString()
    @MaxLength(255)
    @Expose()
    name!: string;

    @IsDefined()
    @IsString()
    @Expose()
    description!: string;

    @IsDefined()
    @IsBoolean()
    @Expose()
    clockingInAppEnabled!: boolean;

    @IsOptional()
    @IsBoolean()
    @Expose()
    clockingInWebEnabled!: boolean;

    @IsDefined()
    @IsBoolean()
    @Expose()
    faceRecognitionEnabled!: boolean;

    @IsDefined()
    @IsBoolean()
    @Expose()
    faceRecognitionBlocking!: boolean;

    @IsOptional()
    @IsBoolean()
    @Expose()
    nightShift?: boolean;

    @IsDefined()
    @IsBoolean()
    @Expose()
    notificationsEnabled!: boolean;

    @IsOptional()
    @IsBoolean()
    @Expose()
    clockingInKioskEnabled?: boolean;

    @IsOptional()
    @IsDateString()
    @Expose()
    fromDate?: string;

    @IsDefined()
    @IsIn(Object.values(GROUP_MEMBER_POLICIES))
    @IsString()
    @Expose()
    userMode!: string;

    @ValidateIf((params: TimeTrackingPoliciesCreationVC) => params.userMode === GROUP_MEMBER_POLICIES.TARGETED_USERS)
    @IsArray()
    @ArrayMinSize(1)
    @IsNumber({}, { each: true })
    @Expose()
    collaborators?: number[];

    @IsInt()
    @Transform(({ value }) => (value === undefined ? DEFAULT_LATENESS_TOLERANCE : value) as number | null)
    @Min(MIN_LATENESS_TOLERANCE)
    @Max(MAX_LATENESS_TOLERANCE)
    @Expose()
    latenessTolerance?: number | null;

    @IsOptional()
    @IsInt()
    @Expose()
    @Min(MIN_AUTO_CLOSE_LIMIT_HOURS)
    @Max(MAX_AUTO_CLOSE_LIMIT_HOURS)
    @AutoCloseLimitHoursValidator({
        message: 'autoCloseLimitHours must be greater than or equal to (autoCloseFixedHoursValue + autoCloseFixedMinutesValue / 60)',
    })
    autoCloseLimitHours!: number;

    @IsOptional()
    @IsIn(Object.values(TimeTrackingPolicyAutoCloseMode))
    @Expose()
    autoCloseMode?: TimeTrackingPolicyAutoCloseMode;

    @IsOptional()
    @IsInt()
    @Expose()
    @Min(MIN_AUTO_CLOSE_FIXED_HOURS_VALUE)
    @Max(MAX_AUTO_CLOSE_FIXED_HOURS_VALUE)
    autoCloseFixedHoursValue!: number | null;

    @IsOptional()
    @IsInt()
    @Expose()
    @Min(MIN_AUTO_CLOSE_FIXED_MINUTES_VALUE)
    @Max(MAX_AUTO_CLOSE_FIXED_MINUTES_VALUE)
    autoCloseFixedMinutesValue!: number | null;

    @IsOptional()
    @IsArray()
    @Expose()
    @ValidateNested({ each: true })
    @Type(() => TimeTrackingPolicyHourCategoryForCreationVC)
    policyHourCategories?: TimeTrackingPolicyHourCategoryForCreationVC[];

    @IsOptional()
    @IsBoolean()
    @DefaultValue(false)
    @Expose()
    geofencing?: boolean;

    @IsOptional()
    @IsBoolean()
    @DefaultValue(false)
    @Expose()
    enableRemoteWork?: boolean;

    @IsOptional()
    @IsBoolean()
    @DefaultValue(false)
    @Expose()
    saveRemoteWorkLocation?: boolean;

    @IsOptional()
    @IsArray()
    @ValidateNested({ each: true })
    @Type(() => TimeTrackingApprovalUsersGatheringVC)
    @Expose()
    approvalUsers?: TimeTrackingApprovalUsersGatheringVC[];
}
