// helpers/validation.ts
import { logger } from './logger';

/**
 * Type guard to validate response against expected interface
 *
 * @param data The data to validate
 * @param requiredProps Array of required property names
 * @param arrayProps Object mapping property names to expected array types
 * @returns boolean indicating if data matches expected format
 */
export function validateResponseFormat<T>(
	data: unknown,
	requiredProps: string[] = [],
	arrayProps: Record<string, boolean> = {},
): data is T {
	if (data === null || typeof data !== 'object') {
		logger.debug('validation', 'Data is not an object');
		return false;
	}

	// Check all required properties exist
	for (const prop of requiredProps) {
		if (!(prop in (data as Record<string, unknown>))) {
			logger.debug('validation', `Required property "${prop}" missing`);
			return false;
		}
	}

	// Validate array properties if specified
	for (const [prop, shouldBeArray] of Object.entries(arrayProps)) {
		const value = (data as Record<string, unknown>)[prop];
		const isArray = Array.isArray(value);

		if (shouldBeArray && !isArray) {
			logger.debug('validation', `Property "${prop}" should be an array but isn't`);
			return false;
		} else if (!shouldBeArray && isArray) {
			logger.debug('validation', `Property "${prop}" shouldn't be an array but is`);
			return false;
		}
	}

	return true;
}

/**
 * Validates that all required parameters are provided
 *
 * @param params Object containing parameters to validate
 * @param required Array of required parameter names
 * @returns Error message if validation fails, otherwise null
 */
export function validateRequiredParameters(
	params: Record<string, unknown>,
	required: string[],
): string | null {
	for (const param of required) {
		const value = params[param];
		if (value === undefined || value === null || value === '') {
			return `Required parameter "${param}" is missing or empty`;
		}
	}
	return null;
}

/**
 * Validates that a parameter's value is within a set of allowed values
 *
 * @param param Parameter name
 * @param value Parameter value
 * @param allowedValues Array of allowed values
 * @returns Error message if validation fails, otherwise null
 */
export function validateAllowedValue<T>(
	param: string,
	value: T,
	allowedValues: T[],
): string | null {
	if (!allowedValues.includes(value)) {
		return `Value "${value}" for parameter "${param}" is not allowed. Allowed values: ${allowedValues.join(', ')}`;
	}
	return null;
}
