import { registerDecorator, ValidationArguments, ValidationOptions, ValidatorConstraint, ValidatorConstraintInterface } from 'class-validator';
import { TimeTrackingPolicyAutoCloseMode } from '../../../business/enum/timeTracking/policy';

interface AutoCloseValidationObject {
    autoCloseMode?: TimeTrackingPolicyAutoCloseMode;
    autoCloseLimitHours?: number;
    autoCloseFixedHoursValue?: number | null;
    autoCloseFixedMinutesValue?: number | null;
}

export function AutoCloseLimitHoursValidator(validationOptions?: ValidationOptions) {
    return (object: unknown, propertyName: string) => {
        registerDecorator({
            constraints: [],
            options: validationOptions,
            propertyName,
            target: object?.constructor as (...args: any) => any,
            validator: AutoCloseLimitHoursValidatorConstraint,
        });
    };
}

@ValidatorConstraint({ name: 'AutoCloseLimitHoursValidator' })
class AutoCloseLimitHoursValidatorConstraint implements ValidatorConstraintInterface {
    validate(value: number | null | undefined, args: ValidationArguments): boolean {
        const object = args.object as AutoCloseValidationObject;

        // Skip validation if mode is not FIXED_HOURS
        if (object.autoCloseMode !== TimeTrackingPolicyAutoCloseMode.FIXED_HOURS) {
            return true;
        }

        // Skip validation for partial updates where autoCloseLimitHours is not provided
        if (value == null) {
            return true;
        }

        // Skip validation if fixed values are not provided (partial update scenario)
        if (object.autoCloseFixedHoursValue == null && object.autoCloseFixedMinutesValue == null) {
            return true;
        }

        const autoCloseLimitHours = value;
        const autoCloseFixedHoursValue = object.autoCloseFixedHoursValue ?? 0;
        const autoCloseFixedMinutesValue = object.autoCloseFixedMinutesValue ?? 0;

        const fixedTotalInHours = autoCloseFixedHoursValue + autoCloseFixedMinutesValue / 60;

        return autoCloseLimitHours >= fixedTotalInHours;
    }

    defaultMessage(): string {
        return 'autoCloseLimitHours must be greater than or equal to (autoCloseFixedHoursValue + autoCloseFixedMinutesValue / 60)';
    }
}
