// Helper utilities and algorithms

/**
 * Format timestamps (supports Unix epoch seconds/ms, strings and ISO dates)
 * @param {string|number|Date} dateVal 
 * @returns {string} Formatted HH:MM AM/PM string
 */
export function formatTime(dateVal) {
    if (!dateVal) return '';
    let date;
    if (typeof dateVal === 'number') {
        date = new Date(dateVal < 10000000000 ? dateVal * 1000 : dateVal);
    } else if (typeof dateVal === 'string' && /^\d+$/.test(dateVal)) {
        const num = parseInt(dateVal, 10);
        date = new Date(num < 10000000000 ? num * 1000 : num);
    } else {
        date = new Date(dateVal);
    }
    
    let hours = date.getHours();
    let minutes = date.getMinutes();
    const ampm = hours >= 12 ? 'PM' : 'AM';
    hours = hours % 12;
    hours = hours ? hours : 12;
    minutes = minutes < 10 ? '0' + minutes : minutes;
    return `${hours}:${minutes} ${ampm}`;
}

/**
 * Adjust outgoing messages backdated behind incoming messages due to clock drift.
 * Uses a 30-second sliding bubble-sort window.
 * @param {Array} messages List of raw messages from WAHA
 * @returns {Array} Compensated chronological message array
 */
export function compensateMessageOrdering(messages) {
    if (!Array.isArray(messages)) return [];

    // Convert timestamps to numeric milliseconds for stable comparison
    const msgs = messages.map(m => {
        let t = m.timestamp;
        if (typeof t === 'number') {
            if (t < 10000000000) t = t * 1000;
        } else {
            t = new Date(t).getTime();
        }
        return { ...m, _time: t };
    });

    // Initial chronological sort
    msgs.sort((a, b) => a._time - b._time);

    // Apply drift bubble adjustments
    let changed = true;
    while (changed) {
        changed = false;
        for (let i = 0; i < msgs.length - 1; i++) {
            const current = msgs[i];
            const next = msgs[i + 1];
            const timeDiff = next._time - current._time;
            
            // Swap if an outgoing message is sorted before an incoming message within a 30-sec window
            if (current.fromMe && !next.fromMe && timeDiff >= 0 && timeDiff <= 30000) {
                msgs[i] = next;
                msgs[i + 1] = current;
                
                // Advance the outgoing message's timestamp to be exactly 1 second after the incoming one
                current._time = next._time + 1000;
                if (typeof current.timestamp === 'number') {
                    current.timestamp = Math.floor(current._time / 1000);
                } else {
                    current.timestamp = new Date(current._time).toISOString();
                }
                
                changed = true;
            }
        }
    }

    // Clean up temporary property
    return msgs.map(({ _time, ...m }) => m);
}
