import { ConsoleColor, ResultTypes } from "@business-logic/types/Enums";

export default class LoggingUtils {

	public static CONSOLE_WIDTH: number = 100;
	//public static ICON_OK: string = "✅";
	public static ICON_OK: string = "\u2705";
	//public static ICON_SKIP: string = "⏩";
	public static ICON_SKIP: string = "\u23ED";
	//public static ICON_WARNING: string = "⚠️";
	public static ICON_WARNING: string = "\u26A0\uFE0F";
	//public static ICON_FAIL: string = "❗";
	public static ICON_FAIL: string = "\u2757";

	public static log(message: string | null, color: ConsoleColor = ConsoleColor.Default): void {
		if (message == null)
			return;
		console.log(`${color}%s${ConsoleColor.Reset}`, message);
	}

	public static icon(value: boolean): string;
	public static icon(value: ResultTypes): string;
	public static icon(value: any): string {
		if (typeof value === "boolean")
			return value ? this.ICON_OK : this.ICON_FAIL;

		switch (value) {
			case ResultTypes.Failure:
				return this.ICON_FAIL;
			case ResultTypes.Success:
				return this.ICON_OK;
			case ResultTypes.Skipped:
				return this.ICON_SKIP;
		}
		return "";
	}

	public static logFunc(name: string, value: string | null = null, result: boolean | null = null): string {
		let icon = this.ICON_SKIP;
		if (result != null)
			icon = result ? this.ICON_OK : this.ICON_FAIL;

		if (value != null)
			return `${this.getShortDateTime()} [${this.centerPadString(`${name}: ${this.truncateString(value)}`)}] -> ${icon}`;

		return `${this.getShortDateTime()} [${this.centerPadString(name)}] -> ${icon}`;
	}

	public static logValidate(text: string, success: boolean) {
		return `${this.getShortDateTime()} [${this.centerPadString(text)}] -> ${success ? this.ICON_OK : this.ICON_FAIL}`;
	}

	public static truncateString(value: any, maxLength: number = this.CONSOLE_WIDTH): string {
		let str = typeof value === 'string' ? value : String(value);
		str = str.replace(/\s+/g, ' ').trim();
		if (str.length <= maxLength) {
			return str;
		}
		return str.slice(0, maxLength - 2) + '..';
	}

	public static sanitizeFileName(input: string): string {
		// Remove characters that are invalid in both Windows and Linux file systems
		let sanitized = input.replace(/[<>:"/\\|?*\x00-\x1F]/g, '');

		// Remove leading and trailing spaces and dots
		sanitized = sanitized.trim().replace(/^\.+|\.+$/g, '');

		// Replace remaining dots and spaces with underscores
		sanitized = sanitized.replace(/[\s.]+/g, '_');

		// Ensure the name isn't empty after sanitization
		if (sanitized.length === 0) {
			sanitized = 'unnamed';
		}

		// Truncate to a reasonable maximum length (e.g., 255 characters)
		sanitized = sanitized.slice(0, 255);

		return sanitized;
	}

	public static replaceEmptyLinesWithMiddleDot(input: string): string {
		const emptyLinesRegex: RegExp = /(.+?)(\n\s*\n)+/g;

		return input.replace(emptyLinesRegex, (_match, line) => {
			return line + '·\n';
		}).replace(/\n$/, '');
	}

	private static centerPadString(str: string, length: number = this.CONSOLE_WIDTH): string {
		if (str.length >= length) {
			return this.truncateString(str);
		}

		str = this.truncateString(str);

		const totalPadding = length - str.length;
		const leftPadding = Math.ceil(totalPadding / 2);
		const rightPadding = Math.floor(totalPadding / 2);

		return ' '.repeat(leftPadding) + str + ' '.repeat(rightPadding);
	}

	private static getShortDateTime() {
		return new Date().toLocaleString('en-US', {
			year: '2-digit',
			month: '2-digit',
			day: '2-digit',
			hour: '2-digit',
			minute: '2-digit',
			second: '2-digit',
			hour12: false
		});
	}

	public static normalizeSalesForceType(input: string, prefix: string = "Apttus_Config2__", suffix: string = "__c") {
		let result = input;

		if (result.startsWith(prefix))
			result = result.slice(prefix.length);

		if (result.endsWith(suffix))
			result = result.slice(0, -suffix.length);
				
		return result;
	}
}