{% extends "base.html" %}
{% set active_page = "timeline" %}

{% block title %}Timeline — IETF Draft Analyzer{% endblock %}

{% block extra_head %}<script src="/static/js/plotly.min.js"></script>{% endblock %}

{% block content %}
<div class="mb-6">
    <h1 class="text-2xl font-bold text-white">Timeline Animation</h1>
    <p class="text-slate-400 text-sm mt-1">Watch the AI/agent draft landscape evolve month by month</p>
</div>

<!-- Stats summary -->
<div class="grid grid-cols-3 gap-4 mb-6" id="statCards">
</div>

<!-- Animated t-SNE map -->
<div class="bg-slate-900 rounded-xl border border-slate-800 p-5 mb-6" id="tsneSection">
    <h2 class="text-sm font-semibold text-slate-300 mb-1">Animated Embedding Landscape</h2>
    <p class="text-xs text-slate-500 mb-3">t-SNE projection with cumulative drafts per month. Color = category, size = composite score. Press Play to animate.</p>
    <div id="monthBadge" class="text-center mb-2">
        <span class="inline-block bg-slate-800 border border-slate-700 rounded-lg px-4 py-1.5 text-sm font-mono text-blue-400"></span>
    </div>
    <div id="tsneAnim" style="height: 560px;"></div>
</div>

<!-- Stacked area chart -->
<div class="bg-slate-900 rounded-xl border border-slate-800 p-5 mb-6">
    <h2 class="text-sm font-semibold text-slate-300 mb-1">Category Submissions Over Time</h2>
    <p class="text-xs text-slate-500 mb-3">Stacked area chart showing draft submissions by category per month.</p>
    <div id="stackedArea" style="height: 400px;"></div>
</div>
{% endblock %}

{% block extra_scripts %}
<script>
const PLOTLY_LAYOUT = {
    paper_bgcolor: 'transparent', plot_bgcolor: 'rgba(15,23,42,0.5)',
    font: { color: '#94a3b8', family: 'Inter, system-ui, sans-serif', size: 12 },
    margin: { t: 20, r: 20, b: 50, l: 50 },
    xaxis: { gridcolor: '#1e293b', zerolinecolor: '#334155' },
    yaxis: { gridcolor: '#1e293b', zerolinecolor: '#334155' },
};
const CFG = { responsive: true, displayModeBar: false };

const PALETTE = [
    '#3b82f6', '#ef4444', '#22c55e', '#a855f7', '#f59e0b',
    '#06b6d4', '#ec4899', '#84cc16', '#f97316', '#8b5cf6',
    '#14b8a6', '#e11d48', '#64748b', '#eab308', '#6366f1',
];

const animData = {{ animation | tojson }};
const points = animData.points;
const months = animData.months;
const catMonthly = animData.category_monthly;

const MONTH_NAMES = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
function fmtMonth(ym) {
    if (!ym) return ym;
    let y, m;
    if (ym.includes('-')) {
        [y, m] = ym.split('-');
    } else if (ym.length >= 6) {
        y = ym.slice(0, 4);
        m = ym.slice(4, 6);
    } else {
        return ym;
    }
    const mi = parseInt(m, 10) - 1;
    return (MONTH_NAMES[mi] || m) + ' ' + y;
}

if (points.length > 0 && months.length > 0) {

    // --- Stat cards ---
    const firstMonth = months[0];
    const lastMonth = months[months.length - 1];
    const allCats = [...new Set(points.map(p => p.category))];
    document.getElementById('statCards').innerHTML = `
        <div class="stat-card rounded-xl border border-slate-800 p-5 relative overflow-hidden">
            <div class="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-blue-500 to-blue-400"></div>
            <div class="text-3xl font-bold text-blue-400">${months.length}</div>
            <div class="text-xs text-slate-400 mt-1 uppercase tracking-wider">Months Span</div>
            <div class="text-xs text-slate-500 mt-0.5">${fmtMonth(firstMonth)} – ${fmtMonth(lastMonth)}</div>
        </div>
        <div class="stat-card rounded-xl border border-slate-800 p-5 relative overflow-hidden">
            <div class="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-emerald-500 to-emerald-400"></div>
            <div class="text-3xl font-bold text-emerald-400">${points.length}</div>
            <div class="text-xs text-slate-400 mt-1 uppercase tracking-wider">Total Drafts</div>
        </div>
        <div class="stat-card rounded-xl border border-slate-800 p-5 relative overflow-hidden">
            <div class="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-purple-500 to-purple-400"></div>
            <div class="text-3xl font-bold text-purple-400">${allCats.length}</div>
            <div class="text-xs text-slate-400 mt-1 uppercase tracking-wider">Categories</div>
        </div>
    `;

    // --- Build category list sorted by frequency ---
    const catCounts = {};
    points.forEach(p => { catCounts[p.category] = (catCounts[p.category] || 0) + 1; });
    const catList = Object.keys(catCounts).sort((a, b) => catCounts[b] - catCounts[a]);
    const catColor = {};
    catList.forEach((c, i) => { catColor[c] = PALETTE[i % PALETTE.length]; });

    // --- Helper: build traces for points up to a given month ---
    function buildTraces(upToMonth) {
        const filtered = points.filter(p => p.month <= upToMonth);
        const groups = {};
        filtered.forEach(p => {
            if (!groups[p.category]) groups[p.category] = { x: [], y: [], size: [], text: [], names: [] };
            groups[p.category].x.push(p.x);
            groups[p.category].y.push(p.y);
            groups[p.category].size.push(Math.max(p.score * 4, 6));
            groups[p.category].text.push(p.title);
            groups[p.category].names.push(p.name);
        });
        return catList.map(cat => {
            const g = groups[cat] || { x: [], y: [], size: [], text: [], names: [] };
            return {
                x: g.x, y: g.y, text: g.text, name: cat,
                customdata: g.names,
                mode: 'markers', type: 'scatter',
                marker: {
                    size: g.size,
                    color: catColor[cat],
                    opacity: 0.8,
                    line: { width: 0.5, color: 'rgba(255,255,255,0.15)' },
                },
                hovertemplate: '<b>%{text}</b><extra>' + cat + '</extra>',
            };
        });
    }

    // --- Build frames ---
    const frames = months.map(month => {
        const cumCount = points.filter(p => p.month <= month).length;
        return {
            name: month,
            data: buildTraces(month),
        };
    });

    // --- Initial plot (first month) ---
    const firstTraces = buildTraces(months[0]);
    const firstCount = points.filter(p => p.month <= months[0]).length;

    // Slider steps
    const sliderSteps = months.map(month => ({
        method: 'animate',
        label: fmtMonth(month),
        args: [[month], { frame: { duration: 500, redraw: true }, transition: { duration: 300 }, mode: 'immediate' }],
    }));

    const layout = {
        ...PLOTLY_LAYOUT,
        xaxis: { visible: false, showgrid: false, zeroline: false },
        yaxis: { visible: false, showgrid: false, zeroline: false },
        legend: { font: { size: 10, color: '#94a3b8' }, bgcolor: 'transparent' },
        hovermode: 'closest',
        margin: { t: 40, r: 20, b: 60, l: 20 },
        updatemenus: [{
            type: 'buttons', showactive: false, x: 0.05, y: 1.08,
            buttons: [
                {
                    label: '&#9654; Play',
                    method: 'animate',
                    args: [null, { frame: { duration: 500, redraw: true }, transition: { duration: 300 }, fromcurrent: true }]
                },
                {
                    label: '&#9724; Pause',
                    method: 'animate',
                    args: [[null], { frame: { duration: 0, redraw: true }, mode: 'immediate' }]
                }
            ]
        }],
        sliders: [{
            active: 0,
            steps: sliderSteps,
            x: 0.05, len: 0.9,
            xanchor: 'left',
            y: -0.02,
            yanchor: 'top',
            pad: { t: 30, b: 10 },
            currentvalue: { visible: false },
            transition: { duration: 300 },
            font: { size: 9, color: '#64748b' },
            bgcolor: '#1e293b',
            activebgcolor: '#3b82f6',
            bordercolor: '#334155',
            borderwidth: 1,
            ticklen: 4,
            tickcolor: '#475569',
        }],
    };

    Plotly.newPlot('tsneAnim', firstTraces, layout, CFG).then(() => {
        Plotly.addFrames('tsneAnim', frames);
    });

    // Update badge on animation frame
    const badge = document.querySelector('#monthBadge span');
    badge.textContent = `${fmtMonth(months[0])} — ${firstCount} drafts`;

    document.getElementById('tsneAnim').on('plotly_animatingframe', function(ev) {
        const month = ev.name;
        const cumCount = points.filter(p => p.month <= month).length;
        badge.textContent = `${fmtMonth(month)} — ${cumCount} drafts`;
    });

    // Click to navigate
    document.getElementById('tsneAnim').on('plotly_click', function(data) {
        const pt = data.points[0];
        if (pt.customdata) {
            window.location.href = '/drafts/' + pt.customdata;
        }
    });

    // --- Stacked area chart ---
    // Collect all categories across all months
    const areaCats = {};
    Object.values(catMonthly).forEach(mc => {
        Object.keys(mc).forEach(c => { areaCats[c] = true; });
    });
    // Sort by total count
    const areaCatList = Object.keys(areaCats).sort((a, b) => {
        const totalA = months.reduce((s, m) => s + ((catMonthly[m] || {})[a] || 0), 0);
        const totalB = months.reduce((s, m) => s + ((catMonthly[m] || {})[b] || 0), 0);
        return totalB - totalA;
    });

    const monthLabels = months.map(fmtMonth);
    const areaTraces = areaCatList.map((cat, i) => ({
        x: monthLabels,
        y: months.map(m => (catMonthly[m] || {})[cat] || 0),
        name: cat,
        type: 'scatter',
        mode: 'lines',
        stackgroup: 'one',
        line: { width: 0.5, color: catColor[cat] || PALETTE[i % PALETTE.length] },
        fillcolor: (catColor[cat] || PALETTE[i % PALETTE.length]) + '80',
        hovertemplate: '%{x}<br>' + cat + ': %{y}<extra></extra>',
    }));

    Plotly.newPlot('stackedArea', areaTraces, {
        ...PLOTLY_LAYOUT,
        xaxis: { ...PLOTLY_LAYOUT.xaxis, title: { text: 'Month', font: { size: 11 } } },
        yaxis: { ...PLOTLY_LAYOUT.yaxis, title: { text: 'Drafts', font: { size: 11 } } },
        legend: { font: { size: 10, color: '#94a3b8' }, orientation: 'h', y: -0.25, x: 0.5, xanchor: 'center' },
        hovermode: 'x unified',
        margin: { t: 20, r: 20, b: 80, l: 50 },
    }, CFG);

} else {
    document.getElementById('tsneSection').innerHTML = '<p class="text-slate-500 text-sm text-center py-20">No timeline animation data available. Run the analysis pipeline first.</p>';
    document.getElementById('stackedArea').innerHTML = '<p class="text-slate-500 text-sm text-center py-20">No data available.</p>';
    document.getElementById('statCards').style.display = 'none';
}
</script>
{% endblock %}
