let weeklyUploadersChart = null;

const formatDateToYYYYMMDD = (date) => {
    return date.toISOString().split('T')[0];
};

const getStartOfWeek = (date) => {
    const d = new Date(date);
    const day = d.getDay();
    const diff = d.getDate() - day + (day === 0 ? -6 : 1);
    return new Date(d.setDate(diff));
};

const fetchData = async (url) => {
    const response = await fetch(url);
    return response.json();
};

const removeLoadingElement = (spinnerId) => {
    const spinner = document.getElementById(spinnerId);
    if (spinner) {
        spinner.remove();
    }
};

const renderSchedulerDetails = async () => {
    const data = await fetchData('/metrics/scrapy-schedulers');
    removeLoadingElement('schedulerChartsSkeleton');
    const container = document.getElementById('schedulerChartsContainer');
    container.innerHTML = ''; // Clear loading skeleton

    const enabledWithStats = [];
    const enabledWithoutStats = [];
    const disabledWithStats = [];
    const disabledWithoutStats = [];

    data.forEach(scheduler => {
        if (scheduler.is_scheduler_disabled) {
            if (scheduler.last_run_state) {
                disabledWithStats.push(scheduler);
            } else {
                disabledWithoutStats.push(scheduler);
            }
        } else {
            if (scheduler.last_run_state) {
                enabledWithStats.push(scheduler);
            } else {
                enabledWithoutStats.push(scheduler);
            }
        }
    });

    const createSchedulerSection = (schedulers, sectionTitle) => {
        const section = document.createElement('div');
        section.className = 'scheduler-section';
        const sectionTitleElem = document.createElement('h5');
        sectionTitleElem.textContent = sectionTitle;
        section.appendChild(sectionTitleElem);

        let row;
        schedulers.forEach((scheduler, index) => {
            if (index % 3 === 0) {
                row = document.createElement('div');
                row.className = 'row';
                section.appendChild(row);
            }

            const schedulerCard = document.createElement('div');
            schedulerCard.className = 'col-lg-4 col-md-6 col-sm-12 mb-4';

            let cardClass = 'card-scheduler ';
            if (scheduler.is_scheduler_disabled) {
                cardClass += 'disabled';
            } else if (scheduler.last_run_state === null) {
                cardClass += 'enabled';
            } else {
                const logCounts = {
                    info: scheduler.last_run_state.log_count_info, warning: scheduler.last_run_state.log_count_warning, error: scheduler.last_run_state.log_count_error
                };

                const maxLogCount = Math.max(logCounts.info, logCounts.warning, logCounts.error);
                if (maxLogCount === logCounts.error) {
                    cardClass += 'log-error';
                } else if (maxLogCount === logCounts.warning) {
                    cardClass += 'log-warning';
                } else {
                    cardClass += 'log-info';
                }
            }

            const lastRunState = scheduler.last_run_state ? `
                    <p>Items Scraped: ${scheduler.last_run_state.item_scraped_count}</p>
                    <p>Items Dropped: ${scheduler.last_run_state.item_dropped_count}</p>
                    <p class="text-info">Info: ${scheduler.last_run_state.log_count_info}</p>
                    <p class="text-warning">Warning: ${scheduler.last_run_state.log_count_warning}</p>
                    <p class="text-danger">Error: ${scheduler.last_run_state.log_count_error}</p>
                ` : '';

            const cardContent = `
                    <div class="${cardClass}">
                        <h5>${scheduler.name}</h5>
                        <p>Last Run: ${scheduler.time_since_last_run}</p>
                        <p>${scheduler.is_scheduler_disabled ? 'Scheduler Disabled' : `Next Schedule In: ${scheduler.next_schedule_in}`}</p>
                        ${lastRunState}
                    </div>
                `;
            schedulerCard.innerHTML = cardContent;
            row.appendChild(schedulerCard);
        });

        container.appendChild(section);
    };

    if (enabledWithStats.length > 0) {
        createSchedulerSection(enabledWithStats, 'Enabled Schedulers with Stats');
    }
    if (enabledWithoutStats.length > 0) {
        createSchedulerSection(enabledWithoutStats, 'Enabled Schedulers without Stats');
    }
    if (disabledWithStats.length > 0) {
        createSchedulerSection(disabledWithStats, 'Disabled Schedulers with Stats');
    }
    if (disabledWithoutStats.length > 0) {
        createSchedulerSection(disabledWithoutStats, 'Disabled Schedulers without Stats');
    }
};

const renderMetadataCountsChart = async () => {
    const data = await fetchData('/metrics/metadata');
    removeLoadingElement('metadataCountsSkeleton');
    const ctx = document.getElementById('metadataCountsChart').getContext('2d');
    new Chart(ctx, {
        type: 'pie', data: {
            labels: ['Movies', 'Series', 'TV Channels'], datasets: [{
                label: 'Metadata Counts',
                data: [data.movies, data.series, data.tv_channels],
                backgroundColor: ['rgba(153, 102, 255, 0.6)', 'rgba(54, 162, 235, 0.6)', 'rgba(75, 192, 192, 0.6)'],
                borderColor: ['rgba(153, 102, 255, 1)', 'rgba(54, 162, 235, 1)', 'rgba(75, 192, 192, 1)'],
            }]
        }, options: {
            responsive: true, maintainAspectRatio: false, plugins: {
                legend: {
                    display: false
                }, datalabels: {
                    formatter: (value, context) => {
                        return context.chart.data.labels[context.dataIndex] + ': ' + value.toLocaleString();
                    }, color: '#fff', anchor: 'center', align: 'center', offset: 0, borderRadius: 4, backgroundColor: (context) => {
                        return context.dataset.backgroundColor;
                    }, font: {
                        weight: 'bold'
                    }
                }
            }
        }
    });
};

const renderTotalTorrentsCount = async () => {
    const data = await fetchData('/metrics/torrents');
    removeLoadingElement('totalTorrentsSkeleton');
    const totalTorrentsValue = document.getElementById('totalTorrentsValue');
    totalTorrentsValue.textContent = `${data.total_torrents.toLocaleString()} (${data.total_torrents_readable})`;
};

const renderTorrentSourcesChart = async () => {
    const data = await fetchData('/metrics/torrents/sources');
    removeLoadingElement('torrentSourcesSkeleton');
    const ctx = document.getElementById('torrentSourcesChart').getContext('2d');
    new Chart(ctx, {
        type: 'bar', data: {
            datasets: data.map(source => {
                return {
                    label: source.name, data: [{x: source.name, y: source.count}],
                };
            }),
        }, options: {
            grouped: false, responsive: true, maintainAspectRatio: false, scales: {
                y: {
                    beginAtZero: true, display: false
                }, x: {
                    ticks: {
                        color: '#fff',
                    }
                }
            }, layout: {
                padding: {
                    top: 50  // Add padding to prevent label cutoff
                }
            }, plugins: {
                legend: {
                    display: false
                }, tooltip: {
                    callbacks: {
                        label: function (context) {
                            return `${context.raw.y.toLocaleString()} Torrents`;
                        }
                    }
                }, datalabels: {
                    align: 'end', anchor: 'end', rotation: 0, color: '#fff', formatter: (value, context) => {
                        return value.y.toLocaleString();
                    }, font: {
                        weight: 'bold'
                    },
                }
            }
        }
    });
};

const renderTorrentUploadersChart = async () => {
    const data = await fetchData('/metrics/torrents/uploaders');
    removeLoadingElement('torrentUploadersSkeleton');
    const ctx = document.getElementById('torrentUploadersChart').getContext('2d');

    const sortedData = data.sort((a, b) => b.count - a.count);

    new Chart(ctx, {
        type: 'bar', data: {
            labels: sortedData.map(item => item.name), datasets: [{
                data: sortedData.map(item => item.count), backgroundColor: 'rgba(75, 192, 192, 0.6)', borderColor: 'rgba(75, 192, 192, 1)', borderWidth: 1
            }]
        }, options: {
            indexAxis: 'y', responsive: true, maintainAspectRatio: false, layout: {
                padding: {
                    right: 50  // Add padding to prevent label cutoff
                }
            }, plugins: {
                legend: {
                    display: false
                }, tooltip: {
                    callbacks: {
                        label: function (context) {
                            return `${context.raw.toLocaleString()} Torrents`;
                        }
                    }
                }, datalabels: {
                    color: '#fff', anchor: 'end', align: 'end', formatter: (value) => value.toLocaleString(), font: {
                        weight: 'bold'
                    }
                }
            }, scales: {
                x: {
                    beginAtZero: true, grid: {
                        color: 'rgba(255, 255, 255, 0.1)'
                    }, ticks: {
                        color: '#fff'
                    }
                }, y: {
                    grid: {
                        display: false
                    }, ticks: {
                        color: '#fff'
                    }
                }
            }
        }
    });
};

const renderDebridCacheMetrics = async () => {
    const data = await fetchData('/metrics/debrid-cache');
    removeLoadingElement('debridChartSkeleton');

    // Create the bar chart for service comparison
    const ctx = document.getElementById('debridCacheChart').getContext('2d');

    // Prepare data for the chart
    const services = Object.keys(data.services);
    const cachedTorrents = services.map(service => data.services[service].cached_torrents);

    new Chart(ctx, {
        type: 'bar', data: {
            labels: services, datasets: [{
                label: 'Cached Torrents', data: cachedTorrents, backgroundColor: 'rgba(54, 162, 235, 0.6)', borderColor: 'rgba(54, 162, 235, 1)', borderWidth: 1
            }]
        }, options: {
            responsive: true, maintainAspectRatio: false, plugins: {
                legend: {
                    display: false
                }, tooltip: {
                    callbacks: {
                        label: function (context) {
                            return `Cached Torrents: ${context.raw.toLocaleString()}`;
                        }
                    }
                }, datalabels: {
                    color: '#fff', anchor: 'end', align: 'end', formatter: (value) => value.toLocaleString(), font: {
                        weight: 'bold'
                    }
                }
            }, scales: {
                y: {
                    beginAtZero: true, title: {
                        display: true, text: 'Number of Cached Torrents', color: '#fff'
                    }, ticks: {
                        color: '#fff'
                    }, grid: {
                        color: 'rgba(255, 255, 255, 0.1)'
                    }
                }, x: {
                    ticks: {
                        color: '#fff'
                    }, grid: {
                        display: false
                    }
                }
            }
        }
    });
};


const renderWeeklyUploadersChart = async (selectedDate = null) => {
    if (!selectedDate) {
        selectedDate = new Date();
    }

    const startOfWeek = getStartOfWeek(selectedDate);
    const formattedDate = formatDateToYYYYMMDD(startOfWeek);

    try {
        // Show loading state
        document.getElementById('weeklyUploadersSkeleton').style.display = 'block';
        if (weeklyUploadersChart) {
            weeklyUploadersChart.destroy();
        }

        const data = await fetchData(`/metrics/torrents/uploaders/weekly/${formattedDate}`);

        if (data.error) {
            console.error('Error fetching data:', data.error);
            return;
        }

        // Update date range display
        const weekStart = new Date(data.week_start);
        const weekEnd = new Date(data.week_end);

        const dateRangeElement = document.getElementById('weekDateRange');
        dateRangeElement.innerHTML = `
            <span class="text-white">
                ${weekStart.toLocaleDateString()} - ${weekEnd.toLocaleDateString()}
            </span>
        `;

        // Update week selector value
        document.getElementById('weekSelector').value = formattedDate;

        const ctx = document.getElementById('weeklyUploadersChart').getContext('2d');

        weeklyUploadersChart = new Chart(ctx, {
            type: 'bar', data: {
                labels: data.uploaders.map(uploader => uploader.name), datasets: [{
                    data: data.uploaders.map(uploader => uploader.count), backgroundColor: 'rgba(147, 112, 219, 0.6)', borderColor: 'rgba(147, 112, 219, 1)', borderWidth: 1
                }]
            }, options: {
                indexAxis: 'y', responsive: true, maintainAspectRatio: false, layout: {
                    padding: {
                        right: 50
                    }
                }, plugins: {
                    legend: {
                        display: false
                    }, tooltip: {
                        callbacks: {
                            label: function (context) {
                                const uploader = data.uploaders[context.dataIndex];
                                const lastUpload = new Date(uploader.latest_upload);
                                return [`Torrents: ${context.raw}`, `Last Upload: ${lastUpload.toLocaleDateString()}`];
                            }
                        }
                    }, datalabels: {
                        color: '#fff', anchor: 'end', align: 'right', formatter: (value) => value, font: {
                            weight: 'bold', size: 12
                        }, padding: {
                            right: 6
                        }
                    }
                }, scales: {
                    x: {
                        beginAtZero: true, grid: {
                            color: 'rgba(255, 255, 255, 0.1)'
                        }, ticks: {
                            color: '#fff', callback: function (value) {
                                return value.toLocaleString();
                            }
                        }
                    }, y: {
                        grid: {
                            display: false
                        }, ticks: {
                            color: '#fff'
                        }
                    }
                }
            }
        });
    } finally {
        // Hide loading state
        document.getElementById('weeklyUploadersSkeleton').style.display = 'none';
    }
};

document.addEventListener('DOMContentLoaded', function () {
    const weekSelector = document.getElementById('weekSelector');
    const prevWeekBtn = document.getElementById('prevWeek');
    const nextWeekBtn = document.getElementById('nextWeek');

    // Set initial date to start of current week
    const currentDate = new Date();
    const startOfWeek = getStartOfWeek(currentDate);
    weekSelector.value = formatDateToYYYYMMDD(startOfWeek);

    // Event listeners for navigation
    weekSelector.addEventListener('change', (e) => {
        renderWeeklyUploadersChart(new Date(e.target.value));
    });

    prevWeekBtn.addEventListener('click', () => {
        const currentDate = new Date(weekSelector.value);
        const prevWeek = new Date(currentDate.setDate(currentDate.getDate() - 7));
        renderWeeklyUploadersChart(prevWeek);
    });

    nextWeekBtn.addEventListener('click', () => {
        const currentDate = new Date(weekSelector.value);
        const nextWeek = new Date(currentDate.setDate(currentDate.getDate() + 7));
        renderWeeklyUploadersChart(nextWeek);
    });

    // Initial render
    renderWeeklyUploadersChart();
});

document.addEventListener('DOMContentLoaded', function () {

    const initCharts = () => {
        renderSchedulerDetails();
        renderMetadataCountsChart();
        renderTotalTorrentsCount();
        renderTorrentSourcesChart();
        renderTorrentUploadersChart();
        renderDebridCacheMetrics();
    };

    Chart.register(ChartDataLabels);
    initCharts();
});
