export function copyToClipboard(copyValue, currentSelector, options = {}) {
    const textTrimmed = normalizeCopyText(copyValue, options);

    if (!textTrimmed) return Promise.reject(new Error('Empty text'));

    // 1) iOS app bridge (WKWebView)
    if (window.webkit?.messageHandlers?.copy) {
        try {
            window.webkit.messageHandlers.copy.postMessage(textTrimmed);
            return Promise.resolve(true);
        } catch (e) {
            console.error(e);
        }
    }

    // 2) Android app bridge
    if (window.Android?.copyToClipboard && typeof window.Android.copyToClipboard === 'function') {
        try {
            window.Android.copyToClipboard(textTrimmed);
            return Promise.resolve(true);
        } catch (e) {
            console.error(e);
        }
    }

    if (navigator.clipboard?.writeText) {
        return navigator.clipboard.writeText(textTrimmed).then(() => true);
    }

    return legacyExecCommandCopy(textTrimmed, currentSelector);
}

function normalizeCopyText(copyValue, options) {
    let raw = copyValue == null ? '' : copyValue + '';

    const str = options.noUpperCase ? raw : raw.replace(/(^\w|\s\w)/g, (m) => m.toUpperCase());

    return str
        .split(' ')
        .filter((v) => v !== '')
        .join(' ')
        .trim();
}

function legacyExecCommandCopy(text, currentSelector) {
    return new Promise(function (resolve, reject) {
        try {
            let $parent = $(currentSelector).parent();

            let $temp = $('<textarea>').val(text).attr('readonly', 'readonly').css({
                position: 'fixed',
                top: 0,
                left: '-9999px',
                opacity: 0,
                width: '1px',
                height: '1px',
                padding: 0,
                border: 0,
                margin: 0,
            });

            $parent.append($temp);

            let el = $temp.get(0);

            el.focus();
            let len = (el.value || '').length;
            if (typeof el.setSelectionRange === 'function') {
                el.setSelectionRange(0, len);
            } else {
                $temp.select();
            }

            let ok = document.execCommand('copy');

            $temp.remove();

            if (window.getSelection) {
                let sel = window.getSelection();
                if (sel && sel.removeAllRanges) sel.removeAllRanges();
            }

            ok ? resolve(true) : reject(new Error('execCommand failed'));
        } catch (e) {
            reject(e);
        }
    });
}
