/home/devscfvi/crypto.devsquantum.com/js/utils.js
// ============================================
// UTILITY FUNCTIONS
// ============================================

const API_URL = 'api.php';
const BINANCE_FEE = 0.001; // 0.1% fee

// API Helper Functions
async function apiGet(action, params = {}) {
    try {
        const queryString = new URLSearchParams({ action, ...params }).toString();
        const response = await fetch(`${API_URL}?${queryString}`);
        return await response.json();
    } catch (error) {
        console.error('API GET Error:', error);
        return { success: false, error: error.message };
    }
}

async function apiPost(action, data = {}) {
    try {
        const response = await fetch(API_URL, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ action, ...data })
        });
        return await response.json();
    } catch (error) {
        console.error('API POST Error:', error);
        return { success: false, error: error.message };
    }
}

// Toast Notifications
function showToast(message, type = 'success') {
    const toast = document.createElement('div');
    toast.className = `toast toast-${type}`;
    toast.textContent = message;
    document.body.appendChild(toast);
    setTimeout(() => toast.remove(), 3000);
}

// Format Numbers
function formatCurrency(amount) {
    return new Intl.NumberFormat('en-US', {
        style: 'currency',
        currency: 'USD',
        minimumFractionDigits: 2,
        maximumFractionDigits: 2
    }).format(amount);
}

function formatPercent(value) {
    return `${value >= 0 ? '+' : ''}${parseFloat(value).toFixed(2)}%`;
}

function formatNumber(num, decimals = 2) {
    return parseFloat(num).toFixed(decimals);
}

// Date Formatting
function formatDate(dateString) {
    const date = new Date(dateString);
    return date.toLocaleDateString('en-US', {
        year: 'numeric',
        month: 'short',
        day: 'numeric'
    });
}

function formatDateTime(dateString) {
    const date = new Date(dateString);
    return date.toLocaleString('en-US', {
        year: 'numeric',
        month: 'short',
        day: 'numeric',
        hour: '2-digit',
        minute: '2-digit'
    });
}

function formatTime(dateString) {
    const date = new Date(dateString);
    return date.toLocaleTimeString('en-US', {
        hour: '2-digit',
        minute: '2-digit'
    });
}

// Calculate Trade Metrics
function calculateTradeMetrics(positionSize, entryPrice, slPercent, tpPercent) {
    const position = parseFloat(positionSize) || 0;
    const entry = parseFloat(entryPrice) || 0;
    const slPct = parseFloat(slPercent) || 0;
    const tpPct = parseFloat(tpPercent) || 0;

    if (!position || !entry) {
        return null;
    }

    const buyFee = position * BINANCE_FEE;
    const quantity = (position - buyFee) / entry;
    
    const slPrice = entry * (1 - slPct / 100);
    const tpPrice = entry * (1 + tpPct / 100);
    
    const slSellValue = quantity * slPrice;
    const slSellFee = slSellValue * BINANCE_FEE;
    const lossAmount = position - (slSellValue - slSellFee);
    
    const tpSellValue = quantity * tpPrice;
    const tpSellFee = tpSellValue * BINANCE_FEE;
    const profitAmount = (tpSellValue - tpSellFee) - position;
    
    const totalFees = buyFee + Math.max(tpSellFee, slSellFee);
    const rewardRiskRatio = profitAmount / lossAmount;

    return {
        quantity: quantity.toFixed(8),
        slPrice: slPrice.toFixed(2),
        tpPrice: tpPrice.toFixed(2),
        lossAmount: lossAmount.toFixed(2),
        profitAmount: profitAmount.toFixed(2),
        rewardRiskRatio: rewardRiskRatio.toFixed(2),
        fees: totalFees.toFixed(2)
    };
}

// Modal Management
function createModal(content, className = '') {
    const modal = document.createElement('div');
    modal.className = `fixed inset-0 modal-backdrop flex items-center justify-center z-50 p-4 ${className}`;
    modal.onclick = (e) => {
        if (e.target === modal) modal.remove();
    };
    
    const modalContent = document.createElement('div');
    modalContent.className = 'glass rounded-3xl p-6 max-w-2xl w-full max-h-[90vh] overflow-y-auto border border-violet-500/20';
    modalContent.innerHTML = content;
    
    modal.appendChild(modalContent);
    document.body.appendChild(modal);
    
    return modal;
}

function closeAllModals() {
    document.querySelectorAll('.modal-backdrop').forEach(modal => modal.remove());
}

// Loading State
function showLoading(targetId = 'app') {
    const target = document.getElementById(targetId);
    if (target) {
        target.innerHTML = `
            <div class="flex items-center justify-center min-h-screen">
                <div class="spinner"></div>
            </div>
        `;
    }
}

// Local Storage Helpers
function saveToStorage(key, value) {
    try {
        localStorage.setItem(key, JSON.stringify(value));
        return true;
    } catch (error) {
        console.error('Storage Error:', error);
        return false;
    }
}

function getFromStorage(key, defaultValue = null) {
    try {
        const item = localStorage.getItem(key);
        return item ? JSON.parse(item) : defaultValue;
    } catch (error) {
        console.error('Storage Error:', error);
        return defaultValue;
    }
}

// Validation
function validateEmail(email) {
    const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return re.test(email);
}

function validateNumber(value, min = null, max = null) {
    const num = parseFloat(value);
    if (isNaN(num)) return false;
    if (min !== null && num < min) return false;
    if (max !== null && num > max) return false;
    return true;
}

// Array Helpers
function groupBy(array, key) {
    return array.reduce((result, item) => {
        const group = item[key];
        if (!result[group]) {
            result[group] = [];
        }
        result[group].push(item);
        return result;
    }, {});
}

function sumBy(array, key) {
    return array.reduce((sum, item) => sum + (parseFloat(item[key]) || 0), 0);
}

function avgBy(array, key) {
    if (array.length === 0) return 0;
    return sumBy(array, key) / array.length;
}

// Emotion & Category Data
const EMOTIONS = [
    { value: 'confident', label: 'Confident', color: 'green' },
    { value: 'fearful', label: 'Fearful', color: 'red' },
    { value: 'fomo', label: 'FOMO', color: 'yellow' },
    { value: 'greedy', label: 'Greedy', color: 'orange' },
    { value: 'calm', label: 'Calm', color: 'blue' },
    { value: 'anxious', label: 'Anxious', color: 'purple' }
];

const CATEGORIES = [
    { value: 'scalping', label: 'Scalping' },
    { value: 'swing', label: 'Swing Trade' },
    { value: 'breakout', label: 'Breakout' },
    { value: 'pullback', label: 'Pullback' },
    { value: 'reversal', label: 'Reversal' },
    { value: 'trend', label: 'Trend Following' }
];

const MISTAKE_CATEGORIES = [
    'Timing',
    'Risk Management',
    'Profit Management',
    'Psychology',
    'Planning',
    'Analysis'
];

// Get emotion/category label
function getEmotionLabel(value) {
    const emotion = EMOTIONS.find(e => e.value === value);
    return emotion ? emotion.label : value;
}

function getCategoryLabel(value) {
    const category = CATEGORIES.find(c => c.value === value);
    return category ? category.label : value;
}

// Chart Colors
const CHART_COLORS = {
    primary: '#8b5cf6',
    success: '#10b981',
    danger: '#ef4444',
    warning: '#f59e0b',
    info: '#3b82f6',
    purple: '#a855f7',
    pink: '#ec4899',
    teal: '#14b8a6'
};

// Export to CSV
function exportToCSV(data, filename) {
    const csv = data.map(row => row.join(',')).join('\n');
    const blob = new Blob([csv], { type: 'text/csv' });
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `${filename}-${Date.now()}.csv`;
    a.click();
    window.URL.revokeObjectURL(url);
}

// Debounce function
function debounce(func, wait) {
    let timeout;
    return function executedFunction(...args) {
        const later = () => {
            clearTimeout(timeout);
            func(...args);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
    };
}

// Copy to clipboard
async function copyToClipboard(text) {
    try {
        await navigator.clipboard.writeText(text);
        showToast('Copied to clipboard!', 'success');
        return true;
    } catch (error) {
        console.error('Copy failed:', error);
        showToast('Failed to copy', 'error');
        return false;
    }
}

// Generate unique ID
function generateId() {
    return Date.now().toString(36) + Math.random().toString(36).substr(2);
}

// Sleep function
function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

// Confirm dialog
function confirmAction(message) {
    return confirm(message);
}

// Prompt dialog
function promptInput(message, defaultValue = '') {
    return prompt(message, defaultValue);
}