export const _ = {
	/**
	 * Проверяет является ли значение булевым
	 * @param {unknown} value
	 * @returns {boolean}
	 */
	isBoolean(value: unknown): value is boolean {
		return typeof value === 'boolean'
	},
	/**
	 * Проверяет является ли значение null
	 * @param {unknown} value
	 * @returns {boolean}
	 */
	isNull(value: unknown): value is null {
		return value === null
	},
	/**
	 * Проверяет является ли значение undefined
	 * @param {unknown} value
	 * @returns {boolean}
	 */
	isUndefined(value: unknown): value is undefined {
		return value === undefined
	},
	/**
	 * Проверяет является ли значение строкой
	 * @param {unknown} value
	 * @returns {boolean}
	 */
	isString(value: unknown): value is string {
		return typeof value === 'string'
	},
	/**
	 * Проверяет является ли значение числом
	 * @param {unknown} value
	 * @returns {boolean}
	 */
	isNumber(value: unknown): value is number {
		return typeof value === 'number'
	},
	/**
	 * Проверяет является ли значение датой
	 * @param {unknown} value
	 * @returns {boolean}
	 */
	isDate(value: unknown): value is Date {
		return value instanceof Date
	},
	/**
	 * Проверяет является ли значение массивом
	 * @param {unknown} value
	 * @returns {boolean}
	 */
	isArray(value: unknown): value is Array<unknown> {
		return Array.isArray(value)
	},
	/**
	 * Проверяет является ли значение объектом
	 * @param {unknown} value
	 * @returns {boolean}
	 */
	isObject(value: unknown): value is Record<string, unknown> {
		return (
			typeof value === 'object' &&
			!this.isNull(value) &&
			!this.isArray(value) &&
			!this.isDate(value) &&
			!(value instanceof RegExp) &&
			!(value instanceof Map) &&
			!(value instanceof Set)
		)
	},
	//////////////////////////////
	/**
	 * Проверка на пустое значение (null, undefined, '', [], {})
	 * @param {unknown} value
	 * @returns {boolean}
	 */
	isEmpty(value: unknown) {
		if (this.isNull(value) || this.isUndefined(value)) return true
		if (this.isString(value) || this.isArray(value)) {
			return value.length === 0
		}
		if (this.isObject(value)) {
			return Object.keys(value).length === 0
		}
		return false
	},
	//////////////////////////////
	/**
	 * Приведение значения к булевому значению
	 * @param {unknown} value
	 * @returns {boolean}
	 */
	toBoolean(value: unknown): boolean {
		if (this.isString(value)) {
			const lowerValue = value.trim().toLowerCase()
			if (lowerValue === 'true') {
				return true
			}
			if (lowerValue === 'false') {
				return false
			}
		}

		return Boolean(value)
	},
	/**
	 * Приведение значения к числу
	 * @param {unknown} value
	 * @returns {number}
	 */
	toNumber(value: unknown): number {
		if (this.isString(value)) {
			const trimmedValue = value.trim()

			if (trimmedValue === '') {
				return 0
			}

			const num = Number(trimmedValue)

			if (!isNaN(num) && isFinite(num)) {
				return num
			}

			const lowerValue = trimmedValue.toLowerCase()
			if (lowerValue === 'true') {
				return 1
			}
			if (lowerValue === 'false') {
				return 0
			}

			return 0
		}

		if (this.isNull(value) || this.isUndefined(value) || value === false) {
			return 0
		}

		if (value === true) {
			return 1
		}

		const num = Number(value)
		return isNaN(num) || !isFinite(num) ? 0 : num
	}
}
