/**
 * Put text on the clipboard, on the addresses this CRM actually runs on.
 *
 * `navigator.clipboard` only exists in a secure context — HTTPS, or localhost.
 * The office runs the CRM from something like `http://solarsystem.test`, which
 * is neither, so the modern API is simply absent there and a button wired
 * straight to it does nothing at all: no error a person can see, no copy, no
 * clue why. That is worth a fallback rather than a console warning.
 *
 * So: the modern API where it is offered, and otherwise a hidden textarea,
 * a selection and `execCommand('copy')`. That call is deprecated but every
 * browser still honours it, and it is the only door left on plain HTTP.
 *
 * Returns whether the text reached the clipboard, so a caller can say so
 * instead of silently pretending.
 */
export async function copyToClipboard(text: string): Promise<boolean> {
    if (!text) {
        return false;
    }

    if (window.isSecureContext && navigator.clipboard?.writeText) {
        try {
            await navigator.clipboard.writeText(text);

            return true;
        } catch {
            // Permission denied, or a browser that insists the document be
            // focused first. The fallback below costs nothing to try.
        }
    }

    return legacyCopy(text);
}

/**
 * The copy a page can still take on plain HTTP.
 *
 * It has to run inside the click that asked for it — no await before it — or
 * the browser no longer treats it as the user's gesture.
 */
function legacyCopy(text: string): boolean {
    const area = document.createElement('textarea');

    area.value = text;
    area.setAttribute('readonly', '');
    // Off-screen rather than hidden: a display:none field cannot be selected.
    area.style.position = 'fixed';
    area.style.top = '0';
    area.style.left = '-9999px';
    area.style.opacity = '0';

    document.body.appendChild(area);

    const selection = document.getSelection();
    const previous =
        selection !== null && selection.rangeCount > 0
            ? selection.getRangeAt(0)
            : null;

    let copied = false;

    try {
        area.select();
        area.setSelectionRange(0, text.length);
        copied = document.execCommand('copy');
    } catch {
        copied = false;
    } finally {
        document.body.removeChild(area);

        // Put the reader's own selection back where it was.
        if (previous !== null) {
            selection?.removeAllRanges();
            selection?.addRange(previous);
        }
    }

    return copied;
}
