/**
 * Is number
 *
 * @param {any} value Value
 * @return {boolean}
 */
export const isNumber = (value) => {
    return Number.isFinite(value);
}

/**
 * Is numeric
 *
 * @param {any} value Value
 * @return {boolean}
 */
export const isNumeric = (value) => {
    return typeof value === 'number' ? Number.isFinite(value) : (typeof value === 'string' && value.trim() !== '' && !isNaN(value));
}

/**
 * Copy to clipboard
 *
 * @param {string} text Text to copy
 * @return {Promise<{data, success: boolean}|{success: boolean}|{data: *, success: boolean}|{success: boolean}>}
 */
export const copyToClipboard = async (text) => {
    try {
        if (navigator.clipboard && window.isSecureContext) {
            // Use Clipboard API if available and secure context
            return await navigator.clipboard.writeText(text).then(() => ({success: true})).catch(e => ({
                success: false,
                error: e
            }));
        } else {
            // Fallback method for older browsers or non-secure contexts
            const textArea = document.createElement('textarea');
            textArea.value = text;
            document.body.appendChild(textArea);
            textArea.select();
            try {
                document.execCommand('copy');
                document.body.removeChild(textArea);
                return {success: true};
            } catch (e) {
                document.body.removeChild(textArea);
                return {success: false, error: e};
            }
        }
    } catch (e) {
        return {success: false, error: e};
    }
}

/**
 * Chat message rerun chat object
 *
 * @param {function} rerunChat Rerun the chat
 * @return {{icon: string, onClick: actionRerunChat.onClick}}
 */
export const actionRerunChat = (rerunChat) => ({
    icon: 'chat-rerun',
    onClick: () => {
        rerunChat();
    }
});

/**
 * Load the file
 *
 * @param {File} file File
 */
export const loadTheFile = (file) => new Promise((resolve, reject) => {
    try {
        const reader = new FileReader();
        reader.readAsDataURL(file)
        reader.onload = () => {
            try {
                resolve({
                    lastModifiedDate: file.lastModifiedDate,
                    name: file.name,
                    size: file.size,
                    type: file.type,
                    base64: reader.result
                });
            } catch (e) {
                console.error(e);
                reject(`Failed to get data from the loaded file (${file.name}).`);
            }
        }
    } catch (e) {
        console.error(e);
        reject("Failed to load file.");
    }
})

/**
 * HEX to RGB string
 * @param {string} hex
 * @return {`${number}, ${number}, ${number}`}
 */
export const hexToRgb = (hex) => {
    try {
        // Expand shorthand form to full form
        hex = hex.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i, function(m, r, g, b) {
            return r + r + g + g + b + b;
        });

        hex = hex.replace(/^#/, '');

        const  bigint = parseInt(hex, 16);

        const r = (bigint >> 16) & 255;
        const g = (bigint >> 8) & 255;
        const b = bigint & 255;

        return `${r}, ${g}, ${b}`;
    } catch (e) {
        console.error(e);
        return null;
    }
}

/**
 * Delay
 *
 * @param {number} ms Milliseconds
 * @return {Promise<unknown>}
 */
export const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));

/**
 * Math floor
 *
 * @param {number} num Number
 * @return {number|null}
 */
export const mathFloor = (num) => {
    try {
        return Math.floor(num);
    } catch (e) {
        console.error(e);
        return null;
    }
}