{% extends "admin/change_list.html" %}
{% load static %}

{% if chart_payload and chart_period %}
{% block extrahead %}
{{ block.super }}

<script src="{% static 'admin_list_charts/js/chart.bundle.min.js' %}"></script>
<style>
#listChartLayout {
    display: flex;
    gap: 10px;
    align-items: stretch;
    margin: 0 0 .15em;
}

#listChartMain {
    flex: 1;
    min-width: 0;
}

#listChartContext {
    width: 246px;
    display: none;
    height: 320px;
}

#chartContextCharts {
    height: 100%;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.chartContextSlot {
    flex: 1;
    min-height: 0;
}

.chartContextSlot canvas {
    width: 100%;
    height: 100%;
}

@media (max-width: 900px) {
    #listChartLayout {
        display: block;
    }

    #listChartMain {
        width: 100%;
    }

    #listChartContext {
        width: 100%;
        margin-top: .65em;
        height: 295px;
    }
}
</style>
{% endblock %}

{% block content %}
<script>
document.addEventListener('DOMContentLoaded', () => {
    var payload = {{ chart_payload|safe }};
    var period = payload.period;
    var objectLabel = payload.object_label || 'Records';
    var palette = payload.palette || {};
    var listChartCanvas = document.getElementById('listChart');

    listChartCanvas.style.height = payload.facets_on ? '320px' : '144px';

    function getAdminVar(name, fallback) {
        var value = getComputedStyle(document.documentElement).getPropertyValue(name);
        value = value ? value.trim() : '';
        return value || fallback;
    }

    function toRgba(color, alpha) {
        if (!color) {
            return 'rgba(0, 0, 0, ' + alpha + ')';
        }
        if (color.indexOf('rgba(') === 0) {
            return color.replace(/rgba\(([^)]+),\s*[^)]+\)/, 'rgba($1, ' + alpha + ')');
        }
        if (color.indexOf('rgb(') === 0) {
            return color.replace('rgb(', 'rgba(').replace(')', ', ' + alpha + ')');
        }
        if (color[0] === '#') {
            var hex = color.slice(1);
            if (hex.length === 3) {
                hex = hex.split('').map((c) => c + c).join('');
            }
            if (hex.length === 6) {
                var r = parseInt(hex.slice(0, 2), 16);
                var g = parseInt(hex.slice(2, 4), 16);
                var b = parseInt(hex.slice(4, 6), 16);
                return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + alpha + ')';
            }
        }
        return color;
    }

    var accent = palette.accent || getAdminVar('--primary', getAdminVar('--link-fg', '#2563eb'));
    var secondary = getAdminVar('--secondary', '#16a34a');
    var linkColor = getAdminVar('--link-fg', '#0ea5e9');
    var danger = getAdminVar('--delete-button-bg', '#c0392b');
    var warning = getAdminVar('--message-warning-bg', '#ea580c');
    var neutral = getAdminVar('--body-quiet-color', '#6b7280');
    var gridColor = getAdminVar('--hairline-color', getAdminVar('--border-color', 'rgba(107, 114, 128, 0.32)'));
    var defaultSeries = [accent, secondary, linkColor, danger, warning, neutral];
    var colors = Array.isArray(palette.series) && palette.series.length ? palette.series : defaultSeries;

    function getFormatter(unit) {
        var formatters = {
            hour: new Intl.DateTimeFormat(undefined, { month: 'short', day: 'numeric', hour: 'numeric' }),
            day: new Intl.DateTimeFormat(undefined, { month: 'short', day: 'numeric' }),
            week: new Intl.DateTimeFormat(undefined, { month: 'short', day: 'numeric' }),
            month: new Intl.DateTimeFormat(undefined, { year: 'numeric', month: 'short' })
        };
        return formatters[unit] || formatters.month;
    }

    function normalizeSeries(points) {
        return (points || [])
            .map((point) => ({ x: new Date(point.x), y: point.y }))
            .filter((point) => !Number.isNaN(point.x.getTime()))
            .sort((a, b) => a.x - b.x);
    }

    function pointMap(points) {
        var mapped = {};
        normalizeSeries(points).forEach((point) => {
            mapped[point.x.toISOString()] = point.y;
        });
        return mapped;
    }

    function sumSeries(points) {
        return normalizeSeries(points).reduce((sum, point) => sum + point.y, 0);
    }

    var formatter = getFormatter(period);
    var volumePoints = normalizeSeries(payload.volume || []);
    var volumeLabels = volumePoints.map((point) => formatter.format(point.x));
    var volumeValues = volumePoints.map((point) => point.y);
    var volumeCtx = listChartCanvas.getContext('2d');
    var datasets = [{
        type: 'bar',
        label: objectLabel,
        data: volumeValues,
        backgroundColor: toRgba(accent, payload.facets_on ? 0.2 : 0.14),
        borderColor: accent,
        borderWidth: 1,
        yAxisID: 'yCount'
    }];

    var rateSeries = (payload.rates || []).slice(0, 3);
    rateSeries.forEach((series, idx) => {
        var values = pointMap(series.data);
        datasets.push({
            type: 'line',
            label: series.label,
            data: volumePoints.map((point) => values[point.x.toISOString()] ? values[point.x.toISOString()] * 100 : 0),
            borderColor: colors[idx % colors.length],
            backgroundColor: colors[idx % colors.length],
            borderWidth: 2,
            pointRadius: 1,
            pointHoverRadius: 3,
            tension: 0.22,
            yAxisID: 'yRate'
        });
    });

    new Chart(volumeCtx, {
        data: {
            labels: volumeLabels,
            datasets: datasets
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            animation: false,
            plugins: {
                legend: {
                    display: payload.facets_on,
                    position: 'bottom',
                    labels: { boxWidth: 10, padding: 10 }
                },
                tooltip: {
                    mode: 'index',
                    intersect: false,
                    callbacks: {
                        label: (context) => {
                            if (context.dataset.yAxisID === 'yRate') {
                                return context.dataset.label + ': ' + context.formattedValue + '%';
                            }
                            return context.dataset.label + ': ' + context.formattedValue;
                        }
                    }
                }
            },
            scales: {
                x: {
                    ticks: {
                        display: true,
                        maxRotation: 0,
                        autoSkip: true,
                        maxTicksLimit: payload.facets_on ? 12 : 10
                    },
                    grid: {
                        display: payload.facets_on,
                        color: gridColor
                    }
                },
                yCount: {
                    type: 'linear',
                    position: 'left',
                    beginAtZero: true,
                    grid: { color: gridColor },
                    ticks: { precision: 0 }
                },
                yRate: {
                    type: 'linear',
                    position: 'right',
                    beginAtZero: true,
                    suggestedMax: 100,
                    grid: { drawOnChartArea: false, color: gridColor },
                    ticks: { callback: (value) => value + '%' }
                }
            }
        }
    });

    if (!payload.facets_on || !(payload.facets || []).length) {
        return;
    }

    var contextPanel = document.getElementById('listChartContext');
    var chartContextCharts = document.getElementById('chartContextCharts');
    contextPanel.style.display = 'block';
    var mainOverlayFields = new Set(rateSeries.map((series) => series.field).filter(Boolean));

    var facetDistributions = (payload.facets || []).map((facet) => {
        var totals = (facet.series || []).map((series) => ({
            label: series.label,
            value: sumSeries(series.data)
        }));
        totals = totals
            .filter((item) => item.value > 0)
            .sort((a, b) => b.value - a.value)
            .slice(0, 7);
        return {
            field: facet.field,
            title: facet.label,
            totals: totals
        };
    }).filter((facet) => facet.totals.length && !mainOverlayFields.has(facet.field));

    var MAX_SIDEBAR_CHARTS = 3;
    var selectedFacets = facetDistributions.slice(0, MAX_SIDEBAR_CHARTS);
    if (!selectedFacets.length) {
        contextPanel.style.display = 'none';
        return;
    }
    selectedFacets.forEach((_, idx) => {
        var slot = document.createElement('div');
        slot.className = 'chartContextSlot';
        slot.innerHTML = '<canvas id="chartContextFacet' + idx + '"></canvas>';
        chartContextCharts.appendChild(slot);
    });

    selectedFacets.forEach((facet, idx) => {
        var target = document.getElementById('chartContextFacet' + idx);
        if (!target) {
            return;
        }

        var config = {
            type: 'bar',
            data: {
                labels: facet.totals.map((item) => item.label),
                datasets: [{
                    label: facet.title,
                    data: facet.totals.map((item) => item.value),
                    backgroundColor: facet.totals.map((_, colorIndex) => toRgba(colors[colorIndex % colors.length], 0.34)),
                    borderColor: facet.totals.map((_, colorIndex) => colors[colorIndex % colors.length]),
                    borderWidth: 1
                }]
            },
            options: {
                indexAxis: 'y',
                responsive: true,
                maintainAspectRatio: false,
                animation: false,
                plugins: {
                    legend: { display: false }
                },
                scales: {
                    x: {
                        beginAtZero: true,
                        reverse: true,
                        grid: { color: gridColor },
                        ticks: { precision: 0 }
                    },
                    y: { ticks: { autoSkip: false, font: { size: 10 } } }
                }
            }
        };

        // Keep sidebar visuals legible in dense, reduced-height cards.
        new Chart(target.getContext('2d'), config);
    });
});
</script>

<div id="listChartLayout">
    <div id="listChartMain">
        <canvas id="listChart" style="width:100%; height:144px;"></canvas>
    </div>
    <aside id="listChartContext">
        <div id="chartContextCharts"></div>
    </aside>
</div>

{{ block.super }}
{% endblock %}
{% endif %}
