Plotly.setPlotConfig({
    staticPlot: false,
    displayModeBar: false,
    scrollZoom: true,
    showTips: false,
    doubleClick: 'reset+autosize',
    modeBarButtonsToRemove: ['toImage', 'sendDataToCloud', 'editInChartStudio']
});

// Add this at the top of the file
function debounce(func, wait) {
    let timeout;
    return function(...args) {
        clearTimeout(timeout);
        timeout = setTimeout(() => func.apply(this, args), wait);
    };
}

// Constants
const TIMEFRAME_SECONDS = {
    "1S": 1, "5S": 5, "15S": 15, "30S": 30,
    "1": 60, "3": 180, "5": 300, "15": 900,
    "30": 1800, "45": 2700, "60": 3600, "120": 7200,
    "180": 10800, "240": 14400, "1D": 86400,
    "1W": 604800, "1M": 2592000
};

const DEFAULT_RSI_LINES = [
    { value: 30, color: '#FF69B4' },
    { value: 70, color: '#FF69B4' }
];

const DEFAULT_DATA_LENGTH = 1000;
const DEFAULT_TIMEFRAME = "15";

let lastFetchTime = 0;
const FETCH_COOLDOWN = 500; // 500ms cooldown between fetches

let dataCache = {};
let currentViewport = { start: null, end: null };

const baseLayout = {
    dragmode: 'pan',
    showlegend: false,
    plot_bgcolor: '#131722',
    paper_bgcolor: '#131722',
    font: { color: '#d1d4dc' },
    margin: { t: 30, r: 50, b: 30, l: 50 },
    xaxis: {
        rangeslider: { visible: false },
        showgrid: true,
        gridcolor: '#1f2937',
        color: '#d1d4dc',
        linecolor: '#2a2e39',
        tickcolor: '#2a2e39',
        showline: true,
        linewidth: 2,
        mirror: true,
        showspikes: true,
        spikemode: 'across',
        spikesnap: 'cursor',
        spikecolor: '#919191',
        spikethickness: 1,
        rangeselector: {
            buttons: [
                {count: 1, label: '1d', step: 'day', stepmode: 'backward'},
                {count: 7, label: '1w', step: 'day', stepmode: 'backward'},
                {count: 1, label: '1m', step: 'month', stepmode: 'backward'},
                {step: 'all'}
            ],
            bgcolor: '#131722',
            activecolor: '#2962ff'
        }
    },
    yaxis: {
        fixedrange: false,
        autorange: true,
        showgrid: true,
        gridcolor: '#1f2937',
        color: '#d1d4dc',
        linecolor: '#2a2e39',
        tickcolor: '#2a2e39',
        showline: true,
        linewidth: 2,
        mirror: true,
        showspikes: true,
        spikemode: 'across',
        spikesnap: 'cursor',
        spikecolor: '#919191',
        spikethickness: 1
    },
    hovermode: 'x unified'
};

const config = {
    responsive: true,
    scrollZoom: true,
    displayModeBar: false,
    modeBarButtonsToAdd: ['pan2d', 'zoomIn2d', 'zoomOut2d', 'resetScale2d'],
};

document.addEventListener('DOMContentLoaded', function() {
    console.log("DOMContentLoaded event fired");
    fetchOptions();
    setupTimeframeButtons();
    setupCheckboxes();
    loadUserProfile();
    
    // Set up event listeners for toggle switches
    document.getElementById('autoScaleToggle').addEventListener('change', updateChartLayout);
    document.getElementById('floatingBubbleToggle').addEventListener('change', updateChartLayout);

    document.getElementById('addRSILine').addEventListener('click', addRSILine);
    document.getElementById('resetRSILines').addEventListener('click', resetRSILines);

    // Set the default active timeframe
    const defaultTimeframe = "15"; // Set this to your default timeframe
    updateActiveTimeframeButton(defaultTimeframe);

    // Fetch and render initial data
    fetchAndRenderData();
});

document.getElementById('autoScaleToggle').addEventListener('change', () => {
    updateChartLayout();
});

// Modify the "Add RSI Line" button event listener
document.getElementById('addRSILine').addEventListener('click', () => {
    const value = prompt("Enter RSI line value (0-100):", "50");
    if (value !== null && !isNaN(value) && value >= 0 && value <= 100) {
        const color = prompt("Enter line color (e.g., #FF0000 for red):", "#FF69B4");
        if (color) {
            const rsiLines = loadRSILines();
            rsiLines.push({ value: parseFloat(value), color });
            saveRSILines(rsiLines);
            // Force an immediate update of the RSI chart
            Plotly.relayout('rsi-chart', {
                shapes: rsiLines.map(line => ({
                    type: 'line',
                    x0: 0,
                    x1: 1,
                    xref: 'paper',
                    y0: line.value,
                    y1: line.value,
                    line: {
                        color: line.color,
                        width: 1,
                        dash: 'dash',
                    }
                }))
            });
        }
    }
});

// Add this to your DOMContentLoaded event listener
document.getElementById('resetRSILines').addEventListener('click', resetRSILines);

// Functions
function fetchOptions() {
    console.log("Fetching options");
    fetch('/api/options')
        .then(response => response.json())
        .then(data => {
            console.log("Options received:", data);
            const coinSelect = document.getElementById('coin');
            
            // Populate coin options
            data.coins.forEach(coin => {
                const option = document.createElement('option');
                option.value = coin;
                option.text = coin;
                coinSelect.appendChild(option);
            });

            // Set default coin value
            coinSelect.value = data.default_coin;

            // Set the active timeframe button
            const defaultTimeframe = "15"; // Make sure this matches the one in DOMContentLoaded
            const defaultTimeframeButton = document.querySelector(`.timeframe-btn[data-timeframe="${defaultTimeframe}"]`);
            if (defaultTimeframeButton) {
                document.querySelectorAll('.timeframe-btn').forEach(btn => btn.classList.remove('active'));
                defaultTimeframeButton.classList.add('active');
            }

            // Set the default active timeframe
            updateActiveTimeframeButton(data.default_timeframe);

            // Fetch and render data with default values
            fetchAndRenderData();
        })
        .catch(error => console.error('Error fetching options:', error));
}

function setupTimeframeButtons() {
    const buttons = document.querySelectorAll('.timeframe-btn');
    buttons.forEach(btn => {
        btn.addEventListener('click', function() {
            buttons.forEach(b => b.classList.remove('active'));
            this.classList.add('active');
            fetchAndRenderData();
        });
    });
}

function updateActiveTimeframeButton(timeframe) {
    const buttons = document.querySelectorAll('.timeframe-btn');
    buttons.forEach(btn => {
        if (btn.dataset.timeframe === timeframe) {
            btn.classList.add('active');
        } else {
            btn.classList.remove('active');
        }
    });
}

// Add an event listener for the coin dropdown
document.getElementById('coin').addEventListener('change', debounce(fetchAndRenderData, 300));

function setupCheckboxes() {
    // Only setup checkboxes that exist in your HTML
    document.getElementById('autoScaleToggle').checked = true;
    document.getElementById('floatingBubbleToggle').checked = false;
}


function getSelectedTimeframe() {
    const selectedButton = document.querySelector('.timeframe-btn.active');
    return selectedButton ? selectedButton.dataset.timeframe : DEFAULT_TIMEFRAME;
}

function fetchAndRenderData() {
    const coin = document.getElementById('coin').value || 'BTC';
    const timeframe = getSelectedTimeframe();

    console.log(`Fetching data for coin: ${coin}, timeframe: ${timeframe}, data length: ${DEFAULT_DATA_LENGTH}`);

    showSpinner();
    const url = `/api/data?coin=${coin}&timeframe=${timeframe}&limit=${DEFAULT_DATA_LENGTH}`;
    
    fetch(url)
        .then(response => {
            console.log(`api/data response status: ${response.status}`);
            if (!response.ok) {
                return response.json().then(err => { throw new Error(err.error || `HTTP error! status: ${response.status}`); });
            }
            return response.json();
        })
        .then(responseData => {
            if (responseData.error) {
                throw new Error(responseData.error);
            }
            console.log(`Received ${responseData.data.length} data points`);
            if (responseData.data.length === 0) {
                throw new Error('No data available for the selected range.');
            }
            window.bufferedData = cleanData(responseData.data);
            
            // Store the data range
            window.dataRange = {
                start: responseData.min_time,
                end: responseData.max_time
            };
            
            // Set the initial view to the latest data
            const latestTime = responseData.max_time;
            const initialStartTime = latestTime - (DEFAULT_DATA_LENGTH * TIMEFRAME_SECONDS[timeframe]);
            
            const containerHeight = document.getElementById('chart-container').offsetHeight;
            createCombinedChart(window.bufferedData, containerHeight);
        })
        .catch(error => {
            console.error('Error fetching data:', error);
            document.getElementById('combined-chart').innerHTML = `<p>Error: ${error.message}</p>`;
        })
        .finally(() => {
            hideSpinner();
        });
}

function renderCharts(data, startTime, endTime) {
    console.log("Starting to render charts");
    if (!data || data.length === 0) {
        console.warn('No data to render');
        showErrorMessage('No data available for the selected range.');
        return;
    }

    const cleanedData = cleanData(data);
    console.log("Cleaned data length:", cleanedData.length);

    if (cleanedData.length === 0) {
        console.warn('All data points are invalid after cleaning.');
        showErrorMessage('No valid data points available.');
        return;
    }

    const containerHeight = document.getElementById('chart-container').offsetHeight;
    const mainChartHeight = containerHeight * 0.75;
    const rsiChartHeight = containerHeight * 0.25;

    createCandlestickChart(cleanedData, mainChartHeight, startTime, endTime);
    createRSIChart(cleanedData, rsiChartHeight, startTime, endTime);
    
    // Link chart ranges
    const mainChart = document.getElementById('chart');
    const rsiChart = document.getElementById('rsi-chart');

    mainChart.on('plotly_relayout', function(eventdata) {
        console.log("Main chart relayout event:", eventdata);
        if (eventdata['xaxis.range[0]'] && eventdata['xaxis.range[1]']) {
            const newStart = new Date(eventdata['xaxis.range[0]']);
            const newEnd = new Date(eventdata['xaxis.range[1]']);
            console.log("New range:", newStart, "to", newEnd);

            Plotly.relayout('rsi-chart', {
                'xaxis.range': [eventdata['xaxis.range[0]'], eventdata['xaxis.range[1]']]
            });
            updateCandlestickChart(window.bufferedData);
            updateRSIChart(window.bufferedData);
        }
    });

    rsiChart.on('plotly_relayout', function(eventdata) {
        if (eventdata['xaxis.range[0]'] && eventdata['xaxis.range[1]']) {
            Plotly.relayout('chart', {
                'xaxis.range': [eventdata['xaxis.range[0]'], eventdata['xaxis.range[1]']]
            });
            updateCandlestickChart(window.bufferedData);
            updateRSIChart(window.bufferedData);
        }
    });
    console.log("Exiting renderCharts");
}

function createCandlestickChart(data, height, startTime, endTime) {
    const trace = createCandlestickTrace(data);
    const autoScale = document.getElementById('autoScaleToggle').checked;
    const candlestickLayout = { 
        ...baseLayout, 
        height: height,
        margin: { t: 20, r: 50, b: 20, l: 50 },
        yaxis: {
            ...baseLayout.yaxis,
            fixedrange: !autoScale,
            autorange: autoScale
        },
        xaxis: {
            ...baseLayout.xaxis,
            range: [new Date(startTime * 1000), new Date(endTime * 1000)]
        }
    };
    
    Plotly.newPlot('chart', [trace], candlestickLayout, config)
        .then(() => {
            console.log("Candlestick chart plotted successfully");
            const chartDiv = document.getElementById('chart');
            chartDiv.on('plotly_relayout', debounce(updateDataOnPan, 250));
        })
        .catch(err => console.error("Error plotting candlestick chart:", err));
}

function createRSIChart(data, height, startTime, endTime) {
    const trace = {
        x: data.map(d => new Date(d.time * 1000)),
        y: data.map(d => d.RSI),
        type: 'scatter',
        line: { color: '#8A2BE2' },
        name: 'RSI'
    };

    const rsiLines = loadRSILines();
    const autoScale = document.getElementById('autoScaleToggle').checked;

    const layout = {
        ...baseLayout,
        height: height,
        margin: { t: 20, r: 50, b: 20, l: 50 },
        yaxis: { 
            ...baseLayout.yaxis, 
            range: autoScale ? null : [0, 100],
            fixedrange: !autoScale,
            autorange: autoScale
        },
        xaxis: {
            ...baseLayout.xaxis,
            range: [new Date(startTime * 1000), new Date(endTime * 1000)]
        },
        shapes: rsiLines.map(line => ({
            type: 'line',
            x0: 0,
            x1: 1,
            xref: 'paper',
            y0: line.value,
            y1: line.value,
            line: {
                color: line.color,
                width: 1,
                dash: 'dash',
            }
        }))
    };

    Plotly.newPlot('rsi-chart', [trace], layout, config)
        .then(() => {
            console.log("RSI chart plotted successfully");
            const rsiChartDiv = document.getElementById('rsi-chart');
            rsiChartDiv.on('plotly_relayout', debounce(updateDataOnPan, 250));
            rsiChartDiv.on('plotly_click', handleRSILineClick);
        })
        .catch(err => console.error("Error plotting RSI chart:", err));
}

function loadRSILines() {
    const savedLines = localStorage.getItem('rsiLines');
    return savedLines ? JSON.parse(savedLines) : DEFAULT_RSI_LINES;
}

function saveRSILines(lines) {
    localStorage.setItem('rsiLines', JSON.stringify(lines));
}

function resetRSILines() {
    saveRSILines(DEFAULT_RSI_LINES);
    Plotly.relayout('rsi-chart', {
        shapes: DEFAULT_RSI_LINES.map(line => ({
            type: 'line',
            x0: 0,
            x1: 1,
            xref: 'paper',
            y0: line.value,
            y1: line.value,
            line: {
                color: line.color,
                width: 1,
                dash: 'dash',
            }
        }))
    });
}

function handleRSILineClick(event) {
    if (event.points[0].y >= 0 && event.points[0].y <= 100) {
        const value = Math.round(event.points[0].y);
        const color = prompt("Enter line color (e.g., #FF0000 for red):", "#FF69B4");
        if (color) {
            const rsiLines = loadRSILines();
            rsiLines.push({ value, color });
            saveRSILines(rsiLines);
            // Force an immediate update of the RSI chart
            Plotly.relayout('rsi-chart', {
                shapes: rsiLines.map(line => ({
                    type: 'line',
                    x0: 0,
                    x1: 1,
                    xref: 'paper',
                    y0: line.value,
                    y1: line.value,
                    line: {
                        color: line.color,
                        width: 1,
                        dash: 'dash',
                    }
                }))
            });
        }
    }
}

function cleanData(data) {
    return data.filter(d => 
        d.time && 
        !isNaN(parseFloat(d.close)) && 
        !isNaN(parseFloat(d.high)) && 
        !isNaN(parseFloat(d.low)) && 
        !isNaN(parseFloat(d.open)) &&
        !isNaN(parseFloat(d.RSI))
    ).map(d => ({
        time: d.time,
        open: parseFloat(d.open),
        high: parseFloat(d.high),
        low: parseFloat(d.low),
        close: parseFloat(d.close),
        Volume: parseFloat(d.Volume),
        RSI: parseFloat(d.RSI)
    }));
}

function updateActiveTimeframeButton(timeframe) {
    const buttons = document.querySelectorAll('.timeframe-btn');
    buttons.forEach(btn => {
        if (btn.dataset.timeframe === timeframe) {
            btn.classList.add('active');
        } else {
            btn.classList.remove('active');
        }
    });
}

function createCandlestickTrace(data) {
    return {
        x: data.map(d => new Date(d.time * 1000)),
        close: data.map(d => d.close),
        high: data.map(d => d.high),
        low: data.map(d => d.low),
        open: data.map(d => d.open),
        type: 'candlestick',
        xaxis: 'x',
        yaxis: 'y',
        increasing: { line: { color: '#53b987' }, fillcolor: '#53b987' },
        decreasing: { line: { color: '#eb4d5c' }, fillcolor: '#eb4d5c' },
        line: { width: 1 }  // Add this line to ensure wick visibility
    };
}

function updateChartLayout() {
    const showCrosshair = document.getElementById('crosshairToggle').checked;
    const showFloatingBubble = document.getElementById('floatingBubble2Toggle').checked;
    const autoScale = document.getElementById('autoScaleToggle').checked;

    const updatedLayout = {
        xaxis: {
            showspikes: showCrosshair,
            showline: true,
            linecolor: '#2a2e39',
            linewidth: 2,
            mirror: true
        },
        yaxis: {
            showspikes: showCrosshair,
            fixedrange: !autoScale,
            autorange: autoScale,
            showline: true,
            linecolor: '#2a2e39',
            linewidth: 2,
            mirror: true
        },
        hovermode: showFloatingBubble ? 'closest' : 'x unified'
    };

    Plotly.relayout('chart', updatedLayout);
    Plotly.relayout('rsi-chart', {
        ...updatedLayout,
        yaxis: {
            ...updatedLayout.yaxis,
            range: autoScale ? null : [0, 100]
        }
    });

    if (window.bufferedData) {
        updateCandlestickChart(window.bufferedData);
        updateRSIChart(window.bufferedData);
    }
}

function updateDataOnPan(event) {
    if (event['xaxis.range[0]'] && event['xaxis.range[1]']) {
        const newStart = new Date(event['xaxis.range[0]']).getTime() / 1000;
        const newEnd = new Date(event['xaxis.range[1]']).getTime() / 1000;
        
        console.log(`Panning to new range: ${newStart} to ${newEnd}`);
        
        fetchDataForRange(newStart, newEnd);
    }
}

function updateAllSubplots(data, startTime, endTime) {
    const update = {
        'x': [
            data.map(d => new Date(d.time * 1000)),
            data.map(d => new Date(d.time * 1000)),
            data.map(d => new Date(d.time * 1000))
        ],
        'open': [data.map(d => d.open)],
        'high': [data.map(d => d.high)],
        'low': [data.map(d => d.low)],
        'close': [data.map(d => d.close)],
        'y': [
            null,
            data.map(d => d.RSI),
            data.map(d => d.Volume)
        ]
    };

    const layout = {
        xaxis: {range: [new Date(startTime * 1000), new Date(endTime * 1000)]},
        xaxis2: {range: [new Date(startTime * 1000), new Date(endTime * 1000)]},
        xaxis3: {range: [new Date(startTime * 1000), new Date(endTime * 1000)]},
        yaxis: {domain: [0.6, 1], title: 'Price'},
        yaxis2: {domain: [0.3, 0.55], title: 'RSI'},
        yaxis3: {domain: [0, 0.25], title: 'Volume'}
    };

    Plotly.update('combined-chart', update, layout);
}

function fetchDataForRange(startTime, endTime) {
    showSpinner();
    const coin = document.getElementById('coin').value;
    const timeframe = getSelectedTimeframe();
    const url = `/api/data?coin=${coin}&timeframe=${timeframe}&start_time=${Math.floor(startTime)}&end_time=${Math.floor(endTime)}&limit=${DEFAULT_DATA_LENGTH}`;
    
    fetch(url)
        .then(response => response.json())
        .then(responseData => {
            if (responseData.error) {
                throw new Error(responseData.error);
            }
            const newData = cleanData(responseData.data);
            
            // Merge new data with existing buffered data
            window.bufferedData = mergeAndSortData(window.bufferedData || [], newData);
            
            // Update the data range
            window.dataRange = {
                start: Math.min(window.dataRange?.start || Infinity, responseData.min_time),
                end: Math.max(window.dataRange?.end || -Infinity, responseData.max_time)
            };
            
            console.log(`Updated buffer: ${window.bufferedData.length} data points`);
            console.log(`New data range: ${new Date(window.dataRange.start * 1000)} to ${new Date(window.dataRange.end * 1000)}`);
            
            // Update the chart with all buffered data
            updateCombinedChart(window.bufferedData);
        })
        .catch(error => {
            console.error('Error fetching data:', error);
            showErrorMessage('Failed to update data. Please try again.');
        })
        .finally(() => {
            hideSpinner();
        });
}

function addToCache(startTime, endTime, data) {
    const cacheKey = `${startTime}-${endTime}`;
    dataCache[cacheKey] = data;
}

function getFromCache(startTime, endTime) {
    const cacheKey = `${startTime}-${endTime}`;
    return dataCache[cacheKey];
}

function preloadData(coin, timeframe, startTime, endTime) {
    const chunks = [];
    const chunkSize = 86400; // 1 day in seconds
    for (let i = startTime; i < endTime; i += chunkSize) {
        const chunkEnd = Math.min(i + chunkSize, endTime);
        chunks.push(fetchDataChunkForRange(coin, timeframe, i, chunkEnd));
    }
    return Promise.all(chunks).then(results => {
        return results.flat();
    });
}

function fetchDataChunkForRange(startTime, endTime) {
    showSpinner();
    const coin = document.getElementById('coin').value;
    const timeframe = getSelectedTimeframe();
    
    const url = `/api/data?coin=${coin}&timeframe=${timeframe}&start_time=${startTime}&end_time=${endTime}`;
    
    fetch(url)
        .then(response => {
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            return response.json();
        })
        .then(data => {
            if (data.error) {
                throw new Error(data.error);
            }
            const newData = cleanData(data);
            window.bufferedData = mergeAndSortData(window.bufferedData, newData);
            updateCharts(window.bufferedData, startTime, endTime);
        })
        .catch(error => {
            console.error('Error fetching data chunk:', error);
        })
        .finally(() => {
            hideSpinner();
        });
}

function mergeAndSortData(oldData, newData) {
    const mergedData = [...oldData, ...newData];
    const uniqueData = Array.from(new Map(mergedData.map(item => [item.time, item])).values());
    return uniqueData.sort((a, b) => a.time - b.time);
}

function updateCharts(data, startTime, endTime) {
    updateCombinedChart(data, startTime, endTime);
}

function updateCombinedChart(data) {
    console.log(`Updating combined chart with ${data.length} data points`);
    const autoScale = document.getElementById('autoScaleToggle').checked;
    
    const traces = [
        // Candlestick trace
        {
            x: data.map(d => new Date(d.time * 1000)),
            close: data.map(d => d.close),
            high: data.map(d => d.high),
            low: data.map(d => d.low),
            open: data.map(d => d.open),
            type: 'candlestick',
            yaxis: 'y',
            name: 'Price'
        },
        // RSI trace
        {
            x: data.map(d => new Date(d.time * 1000)),
            y: data.map(d => d.RSI),
            type: 'scatter',
            line: { color: '#8A2BE2' },
            name: 'RSI',
            yaxis: 'y2'
        },
        // Volume trace
        {
            x: data.map(d => new Date(d.time * 1000)),
            y: data.map(d => d.Volume),
            type: 'bar',
            name: 'Volume',
            yaxis: 'y3'
        }
    ];

    const layout = {
        dragmode: 'pan',
        showlegend: false,
        grid: {rows: 3, columns: 1, pattern: 'independent', roworder: 'top to bottom'},
        yaxis: {domain: [0.6, 1], title: 'Price', autorange: autoScale},
        yaxis2: {domain: [0.3, 0.55], title: 'RSI', range: autoScale ? null : [0, 100]},
        yaxis3: {domain: [0, 0.25], title: 'Volume'},
        xaxis: {rangeslider: {visible: false}},
        plot_bgcolor: '#131722',
        paper_bgcolor: '#131722',
        font: { color: '#d1d4dc' },
    };

    Plotly.react('combined-chart', traces, layout, {responsive: true});
}

function updateCandlestickChart(data) {
    console.log("Entering updateCandlestickChart");
    const autoScale = document.getElementById('autoScaleToggle').checked;
    const chart = document.getElementById('chart');
    
    console.log("Auto Scale:", autoScale);
    console.log("Total data points:", data.length);

    let layout = {
        yaxis: {
            autorange: false,  // We'll manually set the range
            showline: true,
            linecolor: '#2a2e39',
            linewidth: 2,
            mirror: true
        }
    };

    if (autoScale && chart.layout.xaxis.range) {
        const [startTime, endTime] = chart.layout.xaxis.range.map(date => new Date(date).getTime() / 1000);
        console.log("Visible range:", new Date(startTime * 1000), "to", new Date(endTime * 1000));
        
        const visibleData = filterVisibleData(data, startTime, endTime);
        console.log("Visible data points:", visibleData.length);
        
        const yRange = calculateYRange(visibleData);
        console.log("Calculated Y range:", yRange);
        
        layout.yaxis.range = yRange;
    } else {
        // If auto-scale is off, use the current Y-axis range
        layout.yaxis.range = chart.layout.yaxis.range;
    }

    console.log("Setting Y-axis range:", layout.yaxis.range);

    Plotly.update('chart', {
        x: [data.map(d => new Date(d.time * 1000))],
        open: [data.map(d => d.open)],
        high: [data.map(d => d.high)],
        low: [data.map(d => d.low)],
        close: [data.map(d => d.close)]
    }, layout).then(() => {
        // Check if the update was applied correctly
        const updatedRange = chart.layout.yaxis.range;
        console.log("Updated Y-axis range:", updatedRange);
        if (JSON.stringify(updatedRange) !== JSON.stringify(layout.yaxis.range)) {
            console.warn("Y-axis range was not updated as expected");
            // Force the update if it wasn't applied
            Plotly.relayout('chart', {'yaxis.range': layout.yaxis.range});
        }
    });

    console.log("Exiting updateCandlestickChart");
}

function updateRSIChart(data) {
    const autoScale = document.getElementById('autoScaleToggle').checked;
    const chart = document.getElementById('rsi-chart');
    
    const layout = {
        yaxis: {
            autorange: autoScale,
            range: autoScale ? null : [0, 100],
            showline: true,
            linecolor: '#2a2e39',
            linewidth: 2,
            mirror: true
        }
    };

    if (autoScale && chart.layout.xaxis.range) {
        const [startTime, endTime] = chart.layout.xaxis.range.map(date => new Date(date).getTime() / 1000);
        const visibleData = filterVisibleData(data, startTime, endTime);
        const yRange = calculateRSIRange(visibleData);
        layout.yaxis.range = yRange;
    }

    Plotly.update('rsi-chart', {
        x: [data.map(d => new Date(d.time * 1000))],
        y: [data.map(d => d.RSI)]
    }, layout);
}

function getVisibleRange(chartId) {
    const chart = document.getElementById(chartId);
    const xaxis = chart.layout.xaxis;
    if (xaxis && xaxis.range) {
        return {
            start: new Date(xaxis.range[0]).getTime() / 1000,
            end: new Date(xaxis.range[1]).getTime() / 1000
        };
    }
    return null;
}

function filterVisibleData(data, start, end) {
    console.log("Filtering visible data");
    console.log("Start time:", new Date(start * 1000));
    console.log("End time:", new Date(end * 1000));
    const filteredData = data.filter(d => d.time >= start && d.time <= end);
    console.log("Filtered data points:", filteredData.length);
    return filteredData;
}

function calculateYRange(data) {
    const values = data.flatMap(d => [d.low, d.high]);
    const min = Math.min(...values);
    const max = Math.max(...values);
    const padding = (max - min) * 0.1;  // 10% padding
    return [min - padding, max + padding];
}

function calculateRSIRange(data) {
    const values = data.map(d => d.RSI);
    const min = Math.min(...values);
    const max = Math.max(...values);
    const padding = (max - min) * 0.1;
    return [Math.max(0, min - padding), Math.min(100, max + padding)];
}

function showSpinner() {
    document.getElementById('spinner').style.display = 'flex';
}

function hideSpinner() {
    document.getElementById('spinner').style.display = 'none';
}

function handleMissingData(coin, timeframe, startTime, endTime) {
    showErrorMessage(`No data available for ${coin} in ${timeframe} timeframe between ${new Date(startTime * 1000)} and ${new Date(endTime * 1000)}`);
    // Optionally, you could fetch data for a different timeframe or show placeholder data
}

function setupResizeHandle() {
    let isResizing = false;
    let startY;

    const container = document.getElementById('chart-container');
    const chart = document.getElementById('chart');
    const rsiChart = document.getElementById('rsi-chart');
    const handle = document.getElementById('resize-handle');

    handle.addEventListener('mousedown', startResize);

    function startResize(e) {
        isResizing = true;
        startY = e.clientY;
        document.addEventListener('mousemove', resize);
        document.addEventListener('mouseup', stopResize);
    }

    function resize(e) {
        if (!isResizing) return;
        
        const deltaY = e.clientY - startY;
        const containerHeight = container.offsetHeight;
        
        let newMainHeight = chart.offsetHeight + deltaY;
        let newRsiHeight = rsiChart.offsetHeight - deltaY;
        
        // Ensure minimum heights
        const minHeight = containerHeight * 0.1; // 10% of container height
        newMainHeight = Math.max(newMainHeight, minHeight);
        newRsiHeight = Math.max(newRsiHeight, minHeight);
        
        const mainRatio = newMainHeight / containerHeight;
        const rsiRatio = newRsiHeight / containerHeight;
        
        chart.style.flex = mainRatio;
        rsiChart.style.flex = rsiRatio;
        
        Plotly.Plots.resize('chart');
        Plotly.Plots.resize('rsi-chart');
        
        startY = e.clientY;
    }

    function stopResize() {
        isResizing = false;
        document.removeEventListener('mousemove', resize);
        document.removeEventListener('mouseup', stopResize);
    }
}

function saveUserProfile(settings) {
    localStorage.setItem('userProfile', JSON.stringify(settings));
}

function loadUserProfile() {
    const profile = JSON.parse(localStorage.getItem('userProfile'));
    if (profile) {
        document.getElementById('chart').style.height = `${profile.mainChartHeight}px`;
        document.getElementById('rsi-chart').style.height = `${profile.rsiChartHeight}px`;
    }
}

function showErrorMessage(message) {
    const errorDiv = document.createElement('div');
    errorDiv.className = 'error-message';
    errorDiv.textContent = `Error: ${message}`;
    document.body.appendChild(errorDiv);
    setTimeout(() => errorDiv.remove(), 5000);  // Remove after 5 seconds
}

function createCombinedChart(data, height) {
    const traces = [
        // Candlestick trace
        {
            x: data.map(d => new Date(d.time * 1000)),
            close: data.map(d => d.close),
            high: data.map(d => d.high),
            low: data.map(d => d.low),
            open: data.map(d => d.open),
            type: 'candlestick',
            yaxis: 'y',
            name: 'Price'
        },
        // RSI trace
        {
            x: data.map(d => new Date(d.time * 1000)),
            y: data.map(d => d.RSI),
            type: 'scatter',
            line: { color: '#8A2BE2' },
            name: 'RSI',
            yaxis: 'y2'
        },
        // Volume trace
        {
            x: data.map(d => new Date(d.time * 1000)),
            y: data.map(d => d.Volume),
            type: 'bar',
            name: 'Volume',
            yaxis: 'y3'
        }
    ];

    const layout = {
        height: height,
        dragmode: 'pan',
        showlegend: false,
        grid: {rows: 3, columns: 1, pattern: 'independent', roworder: 'top to bottom'},
        yaxis: {domain: [0.6, 1], title: 'Price'},
        yaxis2: {domain: [0.3, 0.55], title: 'RSI'},
        yaxis3: {domain: [0, 0.25], title: 'Volume'},
        xaxis: {rangeslider: {visible: false}},
        plot_bgcolor: '#131722',
        paper_bgcolor: '#131722',
        font: { color: '#d1d4dc' },
    };

    const config = {
        responsive: true,
        scrollZoom: true,
        displayModeBar: false,
    };

    Plotly.newPlot('combined-chart', traces, layout, config)
        .then(() => {
            console.log("Combined chart plotted successfully");
            const chartDiv = document.getElementById('combined-chart');
            chartDiv.on('plotly_relayout', debounce((event) => updateDataOnPan(event), 250));
        })
        .catch(err => console.error("Error plotting combined chart:", err));
}Why does my chart reset its zoom level every time I try to zoom in or out?
How can I fix a chart that returns to its original view whenever I attempt to pan across it?
What might be causing my interactive chart to snap back to the start when I'm trying to explore data?