// Global state
let currentStatus = {
    recording: false,
    playing: false,
    has_recording: false,
    loop_enabled: false,
    loop_count: 0
};

let updateInterval = null;
let recordingStartTime = null;

// DOM Elements
const elements = {
    statusBadge: document.getElementById('statusBadge'),
    statusText: document.querySelector('.status-text'),
    recordBtn: document.getElementById('recordBtn'),
    recordTimer: document.getElementById('recordTimer'),
    playBtn: document.getElementById('playBtn'),
    stopBtn: document.getElementById('stopBtn'),
    clearBtn: document.getElementById('clearBtn'),
    loopToggle: document.getElementById('loopToggle'),
    loopCounter: document.getElementById('loopCounter'),
    loopCount: document.getElementById('loopCount'),
    saveBtn: document.getElementById('saveBtn'),
    macroName: document.getElementById('macroName'),
    macroList: document.getElementById('macroList'),
    statDuration: document.getElementById('statDuration'),
    statClicks: document.getElementById('statClicks'),
    statMovements: document.getElementById('statMovements'),
    statEvents: document.getElementById('statEvents'),
    toastContainer: document.getElementById('toastContainer'),
    movementOffset: document.getElementById('movementOffset'),
    movementOffsetInput: document.getElementById('movementOffsetInput'),
    clickOffset: document.getElementById('clickOffset'),
    clickOffsetInput: document.getElementById('clickOffsetInput'),
    speedVariance: document.getElementById('speedVariance'),
    speedVarianceInput: document.getElementById('speedVarianceInput'),
    pauseFrequency: document.getElementById('pauseFrequency'),
    pauseFrequencyInput: document.getElementById('pauseFrequencyInput'),
    jitterIntensity: document.getElementById('jitterIntensity'),
    jitterIntensityInput: document.getElementById('jitterIntensityInput'),
    overshootIntensity: document.getElementById('overshootIntensity'),
    overshootIntensityInput: document.getElementById('overshootIntensityInput'),
    overshootFrequency: document.getElementById('overshootFrequency'),
    overshootFrequencyInput: document.getElementById('overshootFrequencyInput'),
    randomMovement: document.getElementById('randomMovement'),
    randomMovementInput: document.getElementById('randomMovementInput'),
    playbackSpeed: document.getElementById('playbackSpeed'),
    playbackSpeedInput: document.getElementById('playbackSpeedInput')
};

// System Message Functions
function showSystemMessage(text, type = 'info') {
    const banner = document.getElementById('systemMessageBanner');
    const textElement = document.getElementById('systemMessageText');
    const iconElement = document.getElementById('systemMessageIcon');
    
    // Set message text
    textElement.textContent = text;
    
    // Set icon and class based on type
    banner.className = 'system-message-banner ' + type;
    
    switch(type) {
        case 'warning':
            iconElement.textContent = '⚠️';
            break;
        case 'error':
            iconElement.textContent = '❌';
            break;
        default:
            iconElement.textContent = 'ℹ️';
    }
    
    // Show banner
    banner.style.display = 'block';
}

function hideSystemMessage() {
    const banner = document.getElementById('systemMessageBanner');
    if (banner) {
        banner.style.display = 'none';
    }
}

function dismissSystemMessage() {
    hideSystemMessage();
}

// Initialize app
function init() {
    // Set up event listeners
    elements.playBtn.addEventListener('click', handlePlay);
    elements.stopBtn.addEventListener('click', handleStop);
    elements.clearBtn.addEventListener('click', handleClear);
    elements.loopToggle.addEventListener('change', handleLoopToggle);
    elements.saveBtn.addEventListener('click', handleSave);
    
    // Set up humanization control sliders
    // 'input' events fire continuously while dragging (debounced)
    // 'change' events fire immediately on release (instant save)
    elements.movementOffset.addEventListener('input', handleMovementOffsetSlider);
    elements.movementOffset.addEventListener('change', immediateSettingsUpdate);
    elements.movementOffsetInput.addEventListener('input', handleMovementOffsetInput);
    
    elements.clickOffset.addEventListener('input', handleClickOffsetSlider);
    elements.clickOffset.addEventListener('change', immediateSettingsUpdate);
    elements.clickOffsetInput.addEventListener('input', handleClickOffsetInput);
    
    elements.speedVariance.addEventListener('input', handleSpeedVarianceSlider);
    elements.speedVariance.addEventListener('change', immediateSettingsUpdate);
    elements.speedVarianceInput.addEventListener('input', handleSpeedVarianceInput);
    
    elements.pauseFrequency.addEventListener('input', handlePauseFrequencySlider);
    elements.pauseFrequency.addEventListener('change', immediateSettingsUpdate);
    elements.pauseFrequencyInput.addEventListener('input', handlePauseFrequencyInput);
    
    elements.jitterIntensity.addEventListener('input', handleJitterIntensitySlider);
    elements.jitterIntensity.addEventListener('change', immediateSettingsUpdate);
    elements.jitterIntensityInput.addEventListener('input', handleJitterIntensityInput);
    
    elements.overshootIntensity.addEventListener('input', handleOvershootIntensitySlider);
    elements.overshootIntensity.addEventListener('change', immediateSettingsUpdate);
    elements.overshootIntensityInput.addEventListener('input', handleOvershootIntensityInput);
    
    elements.overshootFrequency.addEventListener('input', handleOvershootFrequencySlider);
    elements.overshootFrequency.addEventListener('change', immediateSettingsUpdate);
    elements.overshootFrequencyInput.addEventListener('input', handleOvershootFrequencyInput);
    
    elements.randomMovement.addEventListener('input', handleRandomMovementSlider);
    elements.randomMovement.addEventListener('change', immediateSettingsUpdate);
    elements.randomMovementInput.addEventListener('input', handleRandomMovementInput);
    
    elements.playbackSpeed.addEventListener('input', handlePlaybackSpeedSlider);
    elements.playbackSpeed.addEventListener('change', immediateSettingsUpdate);
    elements.playbackSpeedInput.addEventListener('input', handlePlaybackSpeedInput);
    
    // Load initial status
    updateStatus();
    
    // Load saved macros
    loadMacros();
    
    // Check license status
    checkLicenseStatus();
    
    // Start polling for status updates
    startPolling();
    
    showToast('info', 'Welcome!', 'F2 to record, F3 to play/stop');
}

// API Calls
async function fetchStatus() {
    try {
        const response = await fetch('/api/status');
        return await response.json();
    } catch (error) {
        console.error('Error fetching status:', error);
        return null;
    }
}

async function toggleRecording() {
    try {
        const response = await fetch('/api/record', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ action: 'toggle' })
        });
        return await response.json();
    } catch (error) {
        console.error('Error toggling recording:', error);
        showToast('error', 'Error', 'Failed to toggle recording');
    }
}

async function playMacro() {
    try {
        const response = await fetch('/api/play', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' }
        });
        const data = await response.json();
        
        // If response is 403 (Forbidden), it means license check failed
        if (response.status === 403) {
            return data;  // Return error data
        }
        
        return data;
    } catch (error) {
        console.error('Error playing macro:', error);
        showToast('error', 'Error', 'Failed to play macro');
    }
}

async function stopMacro() {
    try {
        const response = await fetch('/api/stop', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' }
        });
        return await response.json();
    } catch (error) {
        console.error('Error stopping macro:', error);
        showToast('error', 'Error', 'Failed to stop macro');
    }
}

async function clearMacro() {
    try {
        const response = await fetch('/api/clear', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' }
        });
        return await response.json();
    } catch (error) {
        console.error('Error clearing macro:', error);
        showToast('error', 'Error', 'Failed to clear macro');
    }
}

async function toggleLoop() {
    try {
        const response = await fetch('/api/loop', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ action: 'toggle' })
        });
        return await response.json();
    } catch (error) {
        console.error('Error toggling loop:', error);
        showToast('error', 'Error', 'Failed to toggle loop');
    }
}

async function saveMacro(name) {
    try {
        const response = await fetch('/api/save', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ name })
        });
        return await response.json();
    } catch (error) {
        console.error('Error saving macro:', error);
        showToast('error', 'Error', 'Failed to save macro');
    }
}

async function loadMacro(name) {
    try {
        const response = await fetch('/api/load', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ name })
        });
        return await response.json();
    } catch (error) {
        console.error('Error loading macro:', error);
        showToast('error', 'Error', 'Failed to load macro');
    }
}

async function deleteMacro(name) {
    try {
        const response = await fetch('/api/delete', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ name })
        });
        return await response.json();
    } catch (error) {
        console.error('Error deleting macro:', error);
        showToast('error', 'Error', 'Failed to delete macro');
    }
}

async function fetchMacros() {
    try {
        const response = await fetch('/api/macros');
        return await response.json();
    } catch (error) {
        console.error('Error fetching macros:', error);
        return [];
    }
}

async function updateSettings(settings) {
    try {
        const response = await fetch('/api/settings', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(settings)
        });
        return await response.json();
    } catch (error) {
        console.error('Error updating settings:', error);
        showToast('error', 'Error', 'Failed to update settings');
    }
}

// Event Handlers
async function handlePlay() {
    // Check license status first
    const status = await fetchStatus();
    if (!status.licensed) {
        showToast('⚠️ License Required', 'error');
        setTimeout(() => {
            if (confirm('Macro playback requires an active license.\n\nWould you like to activate a license key now?')) {
                openLicenseModal();
            }
        }, 100);
        return;
    }
    
    const result = await playMacro();
    
    // Check if playback was blocked due to license
    if (result && result.requires_license) {
        showToast('⚠️ License Required', 'error');
        setTimeout(() => {
            if (confirm('Macro playback requires an active license.\n\nWould you like to activate a license key now?')) {
                openLicenseModal();
            }
        }, 100);
        return;
    }
    
    showToast('success', 'Playing', 'Macro playback started');
    await updateStatus();
}

async function handleStop() {
    await stopMacro();
    showToast('info', 'Stopped', 'Macro playback stopped');
    await updateStatus();
}

async function handleClear() {
    if (confirm('Are you sure you want to clear the current recording?')) {
        await clearMacro();
        showToast('info', 'Cleared', 'Recording cleared');
        await updateStatus();
    }
}

async function handleLoopToggle() {
    const result = await toggleLoop();
    if (result) {
        const enabled = result.loop_enabled;
        showToast('info', 'Loop Mode', enabled ? 'Loop enabled' : 'Loop disabled');
    }
}

async function handleSave() {
    const name = elements.macroName.value.trim();
    if (!name) {
        showToast('error', 'Error', 'Please enter a macro name');
        return;
    }
    
    const result = await saveMacro(name);
    if (result && result.success) {
        showToast('success', 'Saved', `Macro "${name}" saved successfully`);
        elements.macroName.value = '';
        await loadMacros();
    }
}

async function handleLoadMacro(name) {
    const result = await loadMacro(name);
    if (result && result.success) {
        showToast('success', 'Loaded', `Macro "${name}" loaded`);
        await updateStatus();
    } else {
        const errorMsg = result && result.error ? result.error : 'Failed to load macro';
        showToast('error', 'Error', errorMsg);
    }
}

async function handleDeleteMacro(name) {
    if (confirm(`Delete macro "${name}"?`)) {
        const result = await deleteMacro(name);
        if (result && result.success) {
            showToast('info', 'Deleted', `Macro "${name}" deleted`);
            await loadMacros();
        }
    }
}

// Movement Offset handlers
function handleMovementOffsetSlider(event) {
    const value = parseFloat(event.target.value);
    elements.movementOffsetInput.value = value;
    debouncedSettingsUpdate();
}

function handleMovementOffsetInput(event) {
    let value = parseFloat(event.target.value) || 0;
    value = Math.max(0, Math.min(100, value)); // Clamp 0-100
    elements.movementOffsetInput.value = value;
    elements.movementOffset.value = value;
    debouncedSettingsUpdate();
}

// Click Offset handlers
function handleClickOffsetSlider(event) {
    const value = parseFloat(event.target.value);
    elements.clickOffsetInput.value = value;
    debouncedSettingsUpdate();
}

function handleClickOffsetInput(event) {
    let value = parseFloat(event.target.value) || 0;
    value = Math.max(0, Math.min(100, value));
    elements.clickOffsetInput.value = value;
    elements.clickOffset.value = value;
    debouncedSettingsUpdate();
}

// Speed Variance handlers
function handleSpeedVarianceSlider(event) {
    const value = parseFloat(event.target.value);
    elements.speedVarianceInput.value = value;
    debouncedSettingsUpdate();
}

function handleSpeedVarianceInput(event) {
    let value = parseFloat(event.target.value) || 0;
    value = Math.max(0, Math.min(100, value));
    elements.speedVarianceInput.value = value;
    elements.speedVariance.value = value;
    debouncedSettingsUpdate();
}

// Pause Frequency handlers
function handlePauseFrequencySlider(event) {
    const value = parseFloat(event.target.value);
    elements.pauseFrequencyInput.value = value;
    debouncedSettingsUpdate();
}

function handlePauseFrequencyInput(event) {
    let value = parseFloat(event.target.value) || 0;
    value = Math.max(0, Math.min(100, value));
    elements.pauseFrequencyInput.value = value;
    elements.pauseFrequency.value = value;
    debouncedSettingsUpdate();
}

// Jitter Intensity handlers
function handleJitterIntensitySlider(event) {
    const value = parseFloat(event.target.value);
    elements.jitterIntensityInput.value = value;
    debouncedSettingsUpdate();
}

function handleJitterIntensityInput(event) {
    let value = parseFloat(event.target.value) || 0;
    value = Math.max(0, Math.min(100, value));
    elements.jitterIntensityInput.value = value;
    elements.jitterIntensity.value = value;
    debouncedSettingsUpdate();
}

// Overshoot Intensity handlers
function handleOvershootIntensitySlider(event) {
    const value = parseFloat(event.target.value);
    elements.overshootIntensityInput.value = value;
    debouncedSettingsUpdate();
}

function handleOvershootIntensityInput(event) {
    let value = parseFloat(event.target.value) || 0;
    value = Math.max(0, Math.min(100, value));
    elements.overshootIntensityInput.value = value;
    elements.overshootIntensity.value = value;
    debouncedSettingsUpdate();
}

// Overshoot Frequency handlers
function handleOvershootFrequencySlider(event) {
    const value = parseFloat(event.target.value);
    elements.overshootFrequencyInput.value = value;
    debouncedSettingsUpdate();
}

function handleOvershootFrequencyInput(event) {
    let value = parseFloat(event.target.value) || 0;
    value = Math.max(0, Math.min(100, value));
    elements.overshootFrequencyInput.value = value;
    elements.overshootFrequency.value = value;
    debouncedSettingsUpdate();
}

// Random Movement handlers
function handleRandomMovementSlider(event) {
    const value = parseFloat(event.target.value);
    elements.randomMovementInput.value = value;
    debouncedSettingsUpdate();
}

function handleRandomMovementInput(event) {
    let value = parseFloat(event.target.value) || 0;
    value = Math.max(0, Math.min(100, value));
    elements.randomMovementInput.value = value;
    elements.randomMovement.value = value;
    debouncedSettingsUpdate();
}

// Playback Speed handlers
function handlePlaybackSpeedSlider(event) {
    const value = parseFloat(event.target.value);
    elements.playbackSpeedInput.value = value;
    debouncedSettingsUpdate();
}

function handlePlaybackSpeedInput(event) {
    let value = parseFloat(event.target.value) || 100;
    value = Math.max(10, Math.min(300, value));
    elements.playbackSpeedInput.value = value;
    elements.playbackSpeed.value = value;
    debouncedSettingsUpdate();
}

// Debounced settings update to avoid too many API calls (for while dragging)
let settingsUpdateTimeout;
function debouncedSettingsUpdate() {
    clearTimeout(settingsUpdateTimeout);
    settingsUpdateTimeout = setTimeout(async () => {
        await sendSettingsUpdate();
    }, 100); // Reduced from 300ms to 100ms for better responsiveness
}

// Immediate settings update (for on release/change)
function immediateSettingsUpdate() {
    clearTimeout(settingsUpdateTimeout); // Cancel any pending debounced update
    sendSettingsUpdate(); // Send immediately
}

// Actual update function
async function sendSettingsUpdate() {
    await updateSettings({
        movement_offset: parseFloat(elements.movementOffsetInput.value) || 0,
        click_offset: parseFloat(elements.clickOffsetInput.value) || 0,
        speed_variance: parseFloat(elements.speedVarianceInput.value) || 0,
        pause_frequency: parseFloat(elements.pauseFrequencyInput.value) || 0,
        jitter_intensity: parseFloat(elements.jitterIntensityInput.value) || 0,
        overshoot_intensity: parseFloat(elements.overshootIntensityInput.value) || 0,
        overshoot_frequency: parseFloat(elements.overshootFrequencyInput.value) || 0,
        random_movement_intensity: parseFloat(elements.randomMovementInput.value) || 0,
        playback_speed: parseFloat(elements.playbackSpeedInput.value) || 100
    });
}

// UI Updates
async function updateStatus() {
    const status = await fetchStatus();
    if (!status) return;
    
    currentStatus = status;
    
    // Check if license block was attempted (from hotkey)
    if (status.license_block_attempted) {
        showToast('⚠️ License Required', 'error');
        setTimeout(() => {
            if (confirm('Macro playback requires an active license.\n\nWould you like to activate a license key now?')) {
                openLicenseModal();
            }
        }, 100);
    }
    
    // Update status badge
    elements.statusBadge.className = 'status-badge';
    if (status.recording) {
        elements.statusBadge.classList.add('recording');
        elements.statusText.textContent = 'Recording';
    } else if (status.playing) {
        elements.statusBadge.classList.add('playing');
        elements.statusText.textContent = 'Playing';
    } else {
        elements.statusText.textContent = 'Idle';
    }
    
    // Update record button
    if (status.recording) {
        elements.recordBtn.classList.add('recording');
        if (!recordingStartTime) {
            recordingStartTime = Date.now();
        }
    } else {
        elements.recordBtn.classList.remove('recording');
        recordingStartTime = null;
    }
    
    // Update timer
    updateTimer(status);
    
    // Update buttons
    elements.playBtn.disabled = !status.has_recording || status.recording || status.playing;
    elements.stopBtn.disabled = !status.playing;
    elements.clearBtn.disabled = !status.has_recording || status.recording || status.playing;
    elements.saveBtn.disabled = !status.has_recording || status.recording || status.playing;
    
    // Show license badge if unlicensed
    updateLicenseBadge(status.licensed, status.license_status);
    
    // Update loop toggle
    elements.loopToggle.checked = status.loop_enabled;
    
    // Update loop counter
    if (status.playing && status.loop_enabled && status.loop_count > 0) {
        elements.loopCounter.style.display = 'block';
        elements.loopCount.textContent = status.loop_count;
    } else {
        elements.loopCounter.style.display = 'none';
    }
    
    // Update humanization settings (only if not currently being edited)
    if (status.movement_offset_percent !== undefined && 
        !elements.movementOffset.matches(':active') && 
        document.activeElement !== elements.movementOffsetInput) {
        elements.movementOffset.value = status.movement_offset_percent;
        elements.movementOffsetInput.value = status.movement_offset_percent;
    }
    if (status.click_offset_percent !== undefined && 
        !elements.clickOffset.matches(':active') && 
        document.activeElement !== elements.clickOffsetInput) {
        elements.clickOffset.value = status.click_offset_percent;
        elements.clickOffsetInput.value = status.click_offset_percent;
    }
    if (status.speed_variance_percent !== undefined && 
        !elements.speedVariance.matches(':active') && 
        document.activeElement !== elements.speedVarianceInput) {
        elements.speedVariance.value = status.speed_variance_percent;
        elements.speedVarianceInput.value = status.speed_variance_percent;
    }
    if (status.pause_frequency_percent !== undefined && 
        !elements.pauseFrequency.matches(':active') && 
        document.activeElement !== elements.pauseFrequencyInput) {
        elements.pauseFrequency.value = status.pause_frequency_percent;
        elements.pauseFrequencyInput.value = status.pause_frequency_percent;
    }
    if (status.jitter_intensity !== undefined && 
        !elements.jitterIntensity.matches(':active') && 
        document.activeElement !== elements.jitterIntensityInput) {
        elements.jitterIntensity.value = status.jitter_intensity;
        elements.jitterIntensityInput.value = status.jitter_intensity;
    }
    if (status.overshoot_intensity !== undefined && 
        !elements.overshootIntensity.matches(':active') && 
        document.activeElement !== elements.overshootIntensityInput) {
        elements.overshootIntensity.value = status.overshoot_intensity;
        elements.overshootIntensityInput.value = status.overshoot_intensity;
    }
    if (status.overshoot_frequency !== undefined && 
        !elements.overshootFrequency.matches(':active') && 
        document.activeElement !== elements.overshootFrequencyInput) {
        elements.overshootFrequency.value = status.overshoot_frequency;
        elements.overshootFrequencyInput.value = status.overshoot_frequency;
    }
    if (status.random_movement_intensity !== undefined && 
        !elements.randomMovement.matches(':active') && 
        document.activeElement !== elements.randomMovementInput) {
        elements.randomMovement.value = status.random_movement_intensity;
        elements.randomMovementInput.value = status.random_movement_intensity;
    }
    if (status.playback_speed_percent !== undefined && 
        !elements.playbackSpeed.matches(':active') && 
        document.activeElement !== elements.playbackSpeedInput) {
        elements.playbackSpeed.value = status.playback_speed_percent;
        elements.playbackSpeedInput.value = status.playback_speed_percent;
    }
    
    // Update statistics
    updateStatistics(status);
}

function updateTimer(status) {
    if (status.recording && recordingStartTime) {
        // Live timer during recording
        const elapsed = (Date.now() - recordingStartTime) / 1000;
        elements.recordTimer.textContent = formatDuration(elapsed);
    } else {
        // Show recorded duration
        elements.recordTimer.textContent = formatDuration(status.duration || 0);
    }
}

function updateStatistics(status) {
    elements.statDuration.textContent = formatDuration(status.duration || 0);
    elements.statClicks.textContent = animateNumber(elements.statClicks, status.clicks || 0);
    elements.statMovements.textContent = animateNumber(elements.statMovements, status.movements || 0);
    elements.statEvents.textContent = animateNumber(elements.statEvents, status.event_count || 0);
}

function animateNumber(element, newValue) {
    const oldValue = parseInt(element.textContent) || 0;
    if (oldValue === newValue) return newValue;
    
    // Simple animation - just update with the new value
    // Could be enhanced with a counting animation
    return newValue;
}

async function loadMacros() {
    const macros = await fetchMacros();
    
    if (macros.length === 0) {
        elements.macroList.innerHTML = `
            <div class="empty-state">
                <svg class="empty-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                    <path d="M9 11l3 3L22 4"/>
                    <path d="M21 12v7a2 2 0 01-2 2H5a2 2 0 01-2-2V5a2 2 0 012-2h11"/>
                </svg>
                <p>No saved macros yet</p>
                <p class="empty-hint">Record and save a macro to get started</p>
            </div>
        `;
        return;
    }
    
    elements.macroList.innerHTML = macros.map(macro => `
        <div class="macro-item">
            <div class="macro-info">
                <div class="macro-name">${escapeHtml(macro.name)}</div>
                <div class="macro-meta">
                    <span>${formatDate(macro.created)}</span>
                    <span>${formatDuration(macro.stats.duration)}</span>
                    <span>${macro.stats.clicks} clicks</span>
                    <span>${macro.stats.event_count} events</span>
                </div>
            </div>
            <div class="macro-actions">
                <button class="btn-macro" onclick="handleLoadMacro('${escapeHtml(macro.name)}')">Load</button>
                <button class="btn-macro danger" onclick="handleDeleteMacro('${escapeHtml(macro.name)}')">Delete</button>
            </div>
        </div>
    `).join('');
}

// Utility Functions
function formatDuration(seconds) {
    const mins = Math.floor(seconds / 60);
    const secs = Math.floor(seconds % 60);
    const ms = Math.floor((seconds % 1) * 100);
    return `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}.${String(ms).padStart(2, '0')}`;
}

function formatDate(dateString) {
    const date = new Date(dateString);
    const now = new Date();
    const diffMs = now - date;
    const diffMins = Math.floor(diffMs / 60000);
    const diffHours = Math.floor(diffMs / 3600000);
    const diffDays = Math.floor(diffMs / 86400000);
    
    if (diffMins < 1) return 'Just now';
    if (diffMins < 60) return `${diffMins}m ago`;
    if (diffHours < 24) return `${diffHours}h ago`;
    if (diffDays < 7) return `${diffDays}d ago`;
    
    return date.toLocaleDateString();
}

function escapeHtml(text) {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
}

function showToast(type, title, message) {
    const toast = document.createElement('div');
    toast.className = `toast ${type}`;
    
    const icons = {
        success: '<path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 01-2 2H5a2 2 0 01-2-2V5a2 2 0 012-2h11"/>',
        error: '<circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/>',
        info: '<circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/>'
    };
    
    toast.innerHTML = `
        <svg class="toast-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            ${icons[type] || icons.info}
        </svg>
        <div class="toast-content">
            <div class="toast-title">${title}</div>
            <div class="toast-message">${message}</div>
        </div>
    `;
    
    elements.toastContainer.appendChild(toast);
    
    // Auto-remove after 3 seconds
    setTimeout(() => {
        toast.style.animation = 'toastSlide 0.3s ease reverse';
        setTimeout(() => toast.remove(), 300);
    }, 3000);
}

function startPolling() {
    // Poll every 200ms for real-time updates
    updateInterval = setInterval(updateStatus, 200);
}

function stopPolling() {
    if (updateInterval) {
        clearInterval(updateInterval);
        updateInterval = null;
    }
}

// Keybind Customization
let isRebinding = false;
let rebindingType = null; // 'record' or 'playback'

function openKeybindModal(type) {
    const modal = document.getElementById('keybindModal');
    const title = document.getElementById('keybindModalTitle');
    const message = document.getElementById('keybindMessage');
    const preview = document.getElementById('keybindPreview');
    
    rebindingType = type;
    isRebinding = true;
    
    if (type === 'record') {
        title.textContent = 'Rebind Recording Hotkey';
        message.textContent = 'Press any key to set as the recording hotkey...';
    } else {
        title.textContent = 'Rebind Playback Hotkey';
        message.textContent = 'Press any key to set as the playback hotkey...';
    }
    
    preview.textContent = 'Waiting for input...';
    modal.classList.add('active');
}

function closeKeybindModal() {
    const modal = document.getElementById('keybindModal');
    modal.classList.remove('active');
    isRebinding = false;
    rebindingType = null;
}

async function saveKeybind(key, type) {
    try {
        const response = await fetch('/api/keybind', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ key, type })
        });
        const result = await response.json();
        
        if (result.success) {
            // Update display
            const displayElement = type === 'record' ? 
                document.getElementById('recordKeyDisplay') : 
                document.getElementById('playbackKeyDisplay');
            displayElement.textContent = key;
            
            showToast('success', 'Hotkey Updated', `${type === 'record' ? 'Recording' : 'Playback'} hotkey set to ${key}`);
        }
    } catch (error) {
        console.error('Error saving keybind:', error);
        showToast('error', 'Error', 'Failed to save keybind');
    }
}

function handleKeybindCapture(event) {
    if (!isRebinding) return;
    
    event.preventDefault();
    event.stopPropagation();
    
    // ESC to cancel
    if (event.key === 'Escape') {
        closeKeybindModal();
        return;
    }
    
    // Get the key name
    let keyName = event.key;
    
    // Format function keys nicely
    if (keyName.startsWith('F') && keyName.length <= 3) {
        keyName = keyName.toUpperCase();
    } else if (keyName.length === 1) {
        keyName = keyName.toUpperCase();
    }
    
    // Show preview
    const preview = document.getElementById('keybindPreview');
    preview.textContent = keyName;
    preview.style.animation = 'none';
    setTimeout(() => preview.style.animation = '', 10);
    
    // Save after short delay
    setTimeout(async () => {
        await saveKeybind(keyName, rebindingType);
        closeKeybindModal();
    }, 500);
}

async function loadKeybinds() {
    try {
        const response = await fetch('/api/keybind');
        const result = await response.json();
        
        if (result.record_key) {
            document.getElementById('recordKeyDisplay').textContent = result.record_key;
        }
        if (result.playback_key) {
            document.getElementById('playbackKeyDisplay').textContent = result.playback_key;
        }
    } catch (error) {
        console.error('Error loading keybinds:', error);
    }
}

// Setup keybind listeners
function setupKeybindListeners() {
    const recordKeyDisplay = document.getElementById('recordKeyDisplay');
    const playbackKeyDisplay = document.getElementById('playbackKeyDisplay');
    const cancelBtn = document.getElementById('keybindCancel');
    
    recordKeyDisplay.addEventListener('click', () => openKeybindModal('record'));
    playbackKeyDisplay.addEventListener('click', () => openKeybindModal('playback'));
    cancelBtn.addEventListener('click', closeKeybindModal);
    
    // Global keydown listener for capturing keys
    document.addEventListener('keydown', handleKeybindCapture);
    
    // Close modal on background click
    document.getElementById('keybindModal').addEventListener('click', (e) => {
        if (e.target.id === 'keybindModal') {
            closeKeybindModal();
        }
    });
    
    // Load current keybinds
    loadKeybinds();
}

// License warning modal
function showLicenseWarning() {
    // Check if modal already exists
    let modal = document.getElementById('licenseWarningModal');
    
    if (!modal) {
        // Create modal
        modal = document.createElement('div');
        modal.id = 'licenseWarningModal';
        modal.className = 'license-modal';
        modal.innerHTML = `
            <div class="license-modal-overlay"></div>
            <div class="license-modal-content glass-card">
                <div class="license-modal-icon">
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                        <rect x="3" y="11" width="18" height="11" rx="2" ry="2"/>
                        <path d="M7 11V7a5 5 0 0110 0v4"/>
                    </svg>
                </div>
                <h2>License Required</h2>
                <p>Macro playback is disabled. Please activate your license to use this feature.</p>
                <div class="license-modal-actions">
                    <button class="btn-modal-primary" onclick="window.location.href='/activate'">
                        Activate License
                    </button>
                    <button class="btn-modal-secondary" onclick="closeLicenseWarning()">
                        Cancel
                    </button>
                </div>
            </div>
        `;
        
        // Add styles
        const style = document.createElement('style');
        style.textContent = `
            .license-modal {
                position: fixed;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                z-index: 10000;
                display: flex;
                align-items: center;
                justify-content: center;
                animation: fadeIn 0.3s ease;
            }
            
            .license-modal-overlay {
                position: absolute;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                background: rgba(0, 0, 0, 0.7);
                backdrop-filter: blur(10px);
            }
            
            .license-modal-content {
                position: relative;
                max-width: 450px;
                width: 90%;
                padding: 2.5rem;
                text-align: center;
                animation: slideUp 0.4s ease;
            }
            
            .license-modal-icon {
                width: 80px;
                height: 80px;
                margin: 0 auto 1.5rem;
                display: flex;
                align-items: center;
                justify-content: center;
                background: linear-gradient(135deg, rgba(102, 126, 234, 0.2), rgba(118, 75, 162, 0.2));
                border-radius: 50%;
                border: 2px solid rgba(102, 126, 234, 0.3);
            }
            
            .license-modal-icon svg {
                width: 40px;
                height: 40px;
                color: var(--accent-purple);
            }
            
            .license-modal-content h2 {
                font-size: 1.75rem;
                font-weight: 700;
                color: var(--text-primary);
                margin-bottom: 1rem;
            }
            
            .license-modal-content p {
                color: var(--text-secondary);
                margin-bottom: 2rem;
                line-height: 1.6;
            }
            
            .license-modal-actions {
                display: flex;
                gap: 1rem;
                flex-direction: column;
            }
            
            .btn-modal-primary,
            .btn-modal-secondary {
                padding: 1rem 2rem;
                border-radius: 12px;
                font-size: 1rem;
                font-weight: 600;
                cursor: pointer;
                transition: all 0.3s ease;
                border: none;
            }
            
            .btn-modal-primary {
                background: var(--primary-gradient);
                color: white;
            }
            
            .btn-modal-primary:hover {
                transform: translateY(-2px);
                box-shadow: 0 10px 30px rgba(102, 126, 234, 0.4);
            }
            
            .btn-modal-secondary {
                background: rgba(255, 255, 255, 0.05);
                color: var(--text-secondary);
                border: 2px solid rgba(255, 255, 255, 0.1);
            }
            
            .btn-modal-secondary:hover {
                background: rgba(255, 255, 255, 0.08);
                color: var(--text-primary);
            }
            
            @keyframes fadeIn {
                from { opacity: 0; }
                to { opacity: 1; }
            }
            
            @keyframes slideUp {
                from {
                    opacity: 0;
                    transform: translateY(30px);
                }
                to {
                    opacity: 1;
                    transform: translateY(0);
                }
            }
        `;
        
        document.head.appendChild(style);
        document.body.appendChild(modal);
        
        // Close on overlay click
        modal.querySelector('.license-modal-overlay').addEventListener('click', closeLicenseWarning);
    }
    
    modal.style.display = 'flex';
}

function closeLicenseWarning() {
    const modal = document.getElementById('licenseWarningModal');
    if (modal) {
        modal.style.display = 'none';
    }
}

function updateLicenseBadge(licensed, licenseStatus) {
    // Check if badge already exists
    let badge = document.getElementById('licenseBadge');
    
    if (!licensed) {
        if (!badge) {
            // Create unlicensed badge
            badge = document.createElement('div');
            badge.id = 'licenseBadge';
            badge.className = 'license-badge unlicensed';
            badge.innerHTML = `
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                    <circle cx="12" cy="12" r="10"/>
                    <line x1="15" y1="9" x2="9" y2="15"/>
                    <line x1="9" y1="9" x2="15" y2="15"/>
                </svg>
                <span>Unlicensed</span>
            `;
            
            // Add to header
            const header = document.querySelector('.header');
            if (header) {
                header.appendChild(badge);
            }
            
            // Add styles
            const style = document.createElement('style');
            style.textContent = `
                .license-badge {
                    display: flex;
                    align-items: center;
                    gap: 0.5rem;
                    padding: 0.5rem 1rem;
                    border-radius: 8px;
                    font-size: 0.875rem;
                    font-weight: 600;
                    margin-left: auto;
                }
                
                .license-badge.unlicensed {
                    background: rgba(252, 129, 129, 0.1);
                    border: 1px solid rgba(252, 129, 129, 0.3);
                    color: #FC8181;
                }
                
                .license-badge svg {
                    width: 16px;
                    height: 16px;
                }
            `;
            document.head.appendChild(style);
        }
    } else {
        // Remove badge if licensed
        if (badge) {
            badge.remove();
        }
    }
}

// License Management Functions
let licenseStatus = null;

async function checkLicenseStatus() {
    try {
        const response = await fetch('/api/license/status');
        if (response.ok) {
            licenseStatus = await response.json();
            updateLicenseBadge();
            
            // Check for system message
            if (licenseStatus.system_message) {
                showSystemMessage(
                    licenseStatus.system_message.text,
                    licenseStatus.system_message.type
                );
            } else {
                hideSystemMessage();
            }
        }
    } catch (error) {
        console.error('Failed to check license status:', error);
    }
}

function updateLicenseBadge() {
    const badge = document.getElementById('licenseBadge');
    const textSpan = badge.querySelector('.license-text');
    
    if (!licenseStatus) {
        textSpan.textContent = 'Checking...';
        badge.className = 'license-badge';
        return;
    }
    
    if (licenseStatus.licensed) {
        textSpan.textContent = 'Click to view key';
        badge.className = 'license-badge licensed';
    } else {
        textSpan.textContent = 'Click to add key';
        badge.className = 'license-badge unlicensed';
    }
}

function openLicenseModal() {
    const modal = document.getElementById('licenseModal');
    const modalBody = document.getElementById('licenseModalBody');
    
    if (!licenseStatus) {
        modalBody.innerHTML = '<p style="color: var(--text-secondary);">Loading license information...</p>';
        modal.classList.add('active');
        return;
    }
    
    if (licenseStatus.licensed) {
        // Show licensed user interface
        modalBody.innerHTML = `
            <div class="license-info">
                <h3 style="margin-bottom: 1rem; color: var(--accent-green);">✓ License Active</h3>
                <p style="color: var(--text-secondary); margin-bottom: 0.75rem;">Your License Key:</p>
                <div class="license-key-display">${licenseStatus.license_key || 'N/A'}</div>
                <div class="license-details">
                    <p><strong>Status:</strong> ${licenseStatus.status}</p>
                    <p><strong>Activated:</strong> ${licenseStatus.activated_at || 'N/A'}</p>
                    <p><strong>Last Validated:</strong> ${licenseStatus.last_validated || 'N/A'}</p>
                </div>
            </div>
            <div class="modal-actions">
                <button class="btn-modal btn-modal-danger" onclick="removeLicense()">Remove License</button>
                <button class="btn-modal btn-modal-secondary" onclick="closeLicenseModal()">Close</button>
            </div>
        `;
    } else {
        // Show unlicensed user interface
        modalBody.innerHTML = `
            <div class="license-info">
                <h3 style="margin-bottom: 1rem; color: var(--accent-red);">⚠️ No License</h3>
                <p style="color: var(--text-secondary); margin-bottom: 1rem;">
                    Enter a valid license key to activate full functionality.
                </p>
                <div class="license-input-group">
                    <label for="modalLicenseKey">License Key</label>
                    <input 
                        type="text" 
                        id="modalLicenseKey" 
                        placeholder="MACRO-XXXX-XXXX-XXXX-XXXX"
                        maxlength="29"
                        style="text-transform: uppercase;"
                    />
                </div>
            </div>
            <div class="modal-actions">
                <button class="btn-modal btn-modal-primary" onclick="activateLicenseFromModal()">Activate License</button>
                <button class="btn-modal btn-modal-secondary" onclick="closeLicenseModal()">Cancel</button>
            </div>
        `;
    }
    
    modal.classList.add('active');
}

function closeLicenseModal() {
    const modal = document.getElementById('licenseModal');
    modal.classList.remove('active');
}

async function activateLicenseFromModal() {
    const input = document.getElementById('modalLicenseKey');
    const licenseKey = input.value.trim().toUpperCase();
    
    if (!licenseKey) {
        showToast('Please enter a license key', 'error');
        return;
    }
    
    try {
        const response = await fetch('/api/license/activate', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ license_key: licenseKey })
        });
        
        const data = await response.json();
        
        if (data.success) {
            showToast('License activated successfully!', 'success');
            closeLicenseModal();
            await checkLicenseStatus();
            setTimeout(() => window.location.reload(), 1500);
        } else {
            showToast(data.error || 'Activation failed', 'error');
        }
    } catch (error) {
        showToast('Failed to activate license', 'error');
        console.error('Activation error:', error);
    }
}

async function removeLicense() {
    if (!confirm('Are you sure you want to remove your license? You will need to reactivate it to use macro playback.')) {
        return;
    }
    
    try {
        const response = await fetch('/api/license/deactivate', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' }
        });
        
        const data = await response.json();
        
        if (data.success) {
            showToast('License removed successfully', 'success');
            closeLicenseModal();
            await checkLicenseStatus();
            setTimeout(() => window.location.reload(), 1500);
        } else {
            showToast(data.error || 'Failed to remove license', 'error');
        }
    } catch (error) {
        showToast('Failed to remove license', 'error');
        console.error('Remove license error:', error);
    }
}

// Make functions globally available for inline handlers
window.handleLoadMacro = handleLoadMacro;
window.handleDeleteMacro = handleDeleteMacro;
window.closeLicenseWarning = closeLicenseWarning;
window.openLicenseModal = openLicenseModal;
window.closeLicenseModal = closeLicenseModal;
window.activateLicenseFromModal = activateLicenseFromModal;
window.removeLicense = removeLicense;

// Initialize on page load
document.addEventListener('DOMContentLoaded', () => {
    init();
    setupKeybindListeners();
});

// Clean up on page unload
window.addEventListener('beforeunload', () => {
    stopPolling();
});

