exports.formatImage = (string, path = 'profile-uploads') => {
	if (!string) return string;
	return process.env.FILES_BASE_URL + '/public/' + path + '/' + string;
};

exports.formatCase = (_data, casing = 'camel') => {
	const toCamel = casing === 'camel';
	try {
		const data = _data?.dataValues ?? _data;

		if (!data) return false;

		const isArray = Array.isArray(data);

		if (isArray) {
			return data.map((item) => formatDataDeep(item?.dataValues ?? item, toCamel));
		} else {
			return formatDataDeep(data?.dataValues ?? data, toCamel);
		}
	} catch (error) {
		throw new Error(error.message);
	}
};

function formatDataDeep(data, toCamel) {
	if (typeof data !== 'object' || data === null) {
		return data;
	}

	if (data instanceof Date) {
		return data;
	}

	const formattedData = Array.isArray(data) ? [] : {};

	for (const key in data) {
		const formattedKey = toCamel ? toCamelCase(key) : toSnakeCase(key);
		formattedData[formattedKey] = formatDataDeep(data[key]?.dataValues ?? data[key], toCamel);
	}

	return formattedData;
}

function toSnakeCase(str) {
	return str.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase();
}

function toCamelCase(str) {
	return str.replace(/_([a-z0-9])/g, (match, char) => char.toUpperCase());
}

exports.parseJsonSafe = (data) => {
	if (!data) return null;

	if (typeof data === 'object' || Array.isArray(data)) return data;

	try {
		let parsed = JSON.parse(data);
		if (typeof parsed === 'string') {
			parsed = JSON.parse(parsed);
		}
		return parsed;
	} catch (error) {
		console.error('JSON parsing error:', error);
		return null;
	}
};

exports.calculateAverageRating = (activity) => {
	const guideAvg = parseFloat(activity.guide_review_average);
	const transportationAvg = parseFloat(activity.transportation_review_average);
	const valueAvg = parseFloat(activity.value_for_money_review_average);

	const validAverages = [guideAvg, transportationAvg, valueAvg].filter((avg) => !isNaN(avg));

	if (validAverages.length > 0) {
		const sumOfAverages = validAverages.reduce((sum, avg) => sum + avg, 0);
		const derivedOverallAverage = sumOfAverages / validAverages.length;
		return parseFloat(derivedOverallAverage.toFixed(1));
	} else {
		return 0;
	}
};
