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

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

{% block extra_head %}
<style>
    .arch-layer {
        border-left: 3px solid;
        transition: all 0.2s;
    }
    .arch-layer:hover { background: rgba(255,255,255,0.02); }
    .layer-transport { border-color: #6366f1; }
    .layer-identity { border-color: #f59e0b; }
    .layer-discovery { border-color: #10b981; }
    .layer-communication { border-color: #3b82f6; }
    .layer-coordination { border-color: #8b5cf6; }
    .layer-intelligence { border-color: #ec4899; }
    .layer-safety { border-color: #ef4444; }
    .layer-application { border-color: #06b6d4; }

    .comp-node {
        background: rgba(30, 41, 59, 0.8);
        backdrop-filter: blur(10px);
        cursor: pointer;
        transition: all 0.2s;
    }
    .comp-node:hover {
        transform: translateY(-2px);
        box-shadow: 0 4px 12px rgba(0,0,0,0.3);
    }
    .comp-node.selected {
        box-shadow: 0 0 0 2px #3b82f6;
    }
    .gap-marker.selected {
        box-shadow: 0 0 0 2px #ef4444;
    }

    .gap-marker {
        background: rgba(239, 68, 68, 0.1);
        border: 1px dashed rgba(239, 68, 68, 0.4);
        animation: pulse-border 2s ease-in-out infinite;
    }
    @keyframes pulse-border {
        0%, 100% { border-color: rgba(239, 68, 68, 0.4); }
        50% { border-color: rgba(239, 68, 68, 0.8); }
    }

    .severity-critical { color: #ef4444; }
    .severity-high { color: #f59e0b; }
    .severity-medium { color: #3b82f6; }
    .severity-low { color: #6b7280; }

    .source-dot {
        width: 8px; height: 8px; border-radius: 50%;
        display: inline-block;
    }
    .source-ietf { background: #3b82f6; }
    .source-w3c { background: #f59e0b; }
    .source-etsi { background: #f97316; }
    .source-itu { background: #ec4899; }
    .source-iso { background: #a855f7; }
    .source-nist { background: #06b6d4; }

    .detail-panel {
        background: linear-gradient(135deg, rgba(30, 41, 59, 0.95), rgba(15, 23, 42, 0.95));
        backdrop-filter: blur(20px);
    }

    .maturity-bar {
        height: 4px;
        border-radius: 2px;
        background: rgba(51, 65, 85, 0.5);
        overflow: hidden;
    }
    .maturity-fill {
        height: 100%;
        border-radius: 2px;
        transition: width 0.3s;
    }
</style>
{% endblock %}

{% block content %}
<!-- Header -->
<div class="mb-6">
    <h1 class="text-2xl font-bold text-white">System-of-Systems Architecture</h1>
    <p class="text-slate-400 text-sm mt-1">
        Holistic view of the AI agent standards landscape — {{ arch.stats.total_components }} components across
        {{ arch.layers|length }} architectural layers, with {{ arch.stats.total_gaps }} identified gaps.
        Built from {{ arch.stats.total_dependencies }} cross-component relationships.
    </p>
</div>

<!-- Stats row -->
<div class="grid grid-cols-2 md:grid-cols-4 gap-3 mb-6">
    {% set severity_colors = {"critical": "red", "high": "amber", "medium": "blue", "low": "slate"} %}
    <div class="bg-slate-800/50 rounded-lg border border-slate-700/50 p-4 text-center">
        <div class="text-2xl font-bold text-white">{{ arch.stats.total_components }}</div>
        <div class="text-xs text-slate-500">Components</div>
    </div>
    <div class="bg-slate-800/50 rounded-lg border border-slate-700/50 p-4 text-center">
        <div class="text-2xl font-bold text-white">{{ arch.layers|length }}</div>
        <div class="text-xs text-slate-500">Layers</div>
    </div>
    <div class="bg-slate-800/50 rounded-lg border border-slate-700/50 p-4 text-center">
        <div class="text-2xl font-bold text-white">{{ arch.stats.total_dependencies }}</div>
        <div class="text-xs text-slate-500">Dependencies</div>
    </div>
    <div class="bg-slate-800/50 rounded-lg border border-slate-700/50 p-4 text-center">
        <div class="text-2xl font-bold text-red-400">{{ arch.stats.total_gaps }}</div>
        <div class="text-xs text-slate-500">Gaps</div>
    </div>
</div>

<!-- Layer Coverage Overview -->
<div class="bg-slate-800/30 rounded-xl border border-slate-700/50 p-4 mb-6">
    <div class="flex items-center justify-between mb-3">
        <h2 class="text-sm font-semibold text-slate-300">Coverage by Standards Body</h2>
        <div class="flex items-center gap-3">
            {% for src in ['ietf', 'w3c', 'etsi', 'itu', 'iso', 'nist'] %}
            <div class="flex items-center gap-1">
                <span class="source-dot source-{{ src }}"></span>
                <span class="text-xs text-slate-500">{{ src|upper }}</span>
            </div>
            {% endfor %}
            <div class="flex items-center gap-1 ml-2">
                <svg class="w-3 h-3 text-red-400" fill="currentColor" viewBox="0 0 24 24"><path d="M12 2L2 19h20L12 2z"/></svg>
                <span class="text-xs text-slate-500">Gaps</span>
            </div>
        </div>
    </div>
    <div id="coverageChart"></div>
</div>

<!-- Layered Stack View + Detail Panel side-by-side -->
<div id="stackView" class="flex gap-4">
<div class="flex-1 min-w-0">
    {% for layer in arch.layers | sort(attribute='order', reverse=True) %}
    <div class="arch-layer layer-{{ layer.id }} rounded-r-lg mb-3 p-4 bg-slate-800/30">
        <div class="flex items-center justify-between mb-3">
            <div>
                <h3 class="text-sm font-semibold text-white">{{ layer.label }}</h3>
                <div class="flex items-center gap-3 mt-1">
                    <span class="text-xs text-slate-500">{{ layer.component_count }} components</span>
                    <span class="text-xs text-slate-500">{{ layer.idea_count }} ideas</span>
                    <span class="text-xs text-slate-500">{{ layer.total_drafts }} drafts</span>
                    {% if layer.gap_count > 0 %}
                    <span class="text-xs text-red-400">{{ layer.gap_count }} gap{{ 's' if layer.gap_count > 1 }}</span>
                    {% endif %}
                </div>
            </div>
            <!-- Source coverage dots -->
            <div class="flex items-center gap-1.5">
                {% for src, count in layer.coverage.items() %}
                <div class="flex items-center gap-1" title="{{ src|upper }}: {{ count }} drafts">
                    <span class="source-dot source-{{ src }}"></span>
                    <span class="text-xs text-slate-500">{{ count }}</span>
                </div>
                {% endfor %}
            </div>
        </div>

        <!-- Components in this layer -->
        <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-2">
            {% for comp in arch.components if comp.layer == layer.id %}
            <div class="comp-node rounded-lg border border-slate-700/50 p-3" data-comp-id="{{ comp.id }}" onclick="selectComponent({{ comp.id }})">
                <div class="flex items-center justify-between mb-1.5">
                    <span class="text-xs font-semibold text-slate-200 truncate" title="{{ comp.name }}">{{ comp.name }}</span>
                    <span class="text-xs text-slate-500" title="{{ comp.size }} ideas, {{ comp.draft_count }} drafts">{{ comp.size }}i / {{ comp.draft_count }}d</span>
                </div>
                <!-- Maturity bar -->
                <div class="maturity-bar mb-2">
                    <div class="maturity-fill {% if comp.maturity >= 4 %}bg-green-500{% elif comp.maturity >= 3 %}bg-yellow-500{% else %}bg-red-500{% endif %}"
                         style="width: {{ (comp.maturity / 5 * 100)|int }}%"></div>
                </div>
                <!-- Source dots -->
                <div class="flex items-center gap-1">
                    {% for src, cnt in comp.sources.items() %}
                    <span class="source-dot source-{{ src }}" title="{{ src|upper }}: {{ cnt }}"></span>
                    {% endfor %}
                    {% if comp.type_breakdown %}
                    <span class="text-xs text-slate-600 ml-auto">
                        {{ comp.type_breakdown.keys() | list | first }}
                    </span>
                    {% endif %}
                </div>
            </div>
            {% endfor %}

            <!-- Gaps in this layer -->
            {% for gap in arch.gaps if gap.layer == layer.id %}
            <div class="gap-marker rounded-lg p-3 cursor-pointer" data-gap-id="{{ gap.id }}" onclick="selectGap({{ gap.id }})">
                <div class="flex items-center gap-1.5 mb-1">
                    <svg class="w-3.5 h-3.5 severity-{{ gap.severity }}" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4.5c-.77-.833-2.694-.833-3.464 0L3.34 16.5c-.77.833.192 2.5 1.732 2.5z"/>
                    </svg>
                    <span class="text-xs font-semibold severity-{{ gap.severity }}">GAP</span>
                    <span class="text-xs text-slate-600">{{ gap.severity }}</span>
                </div>
                <div class="text-xs text-slate-300">{{ gap.topic }}</div>
                <div class="text-xs text-slate-500 mt-1 line-clamp-2">{{ gap.description[:120] }}</div>
            </div>
            {% endfor %}
        </div>
    </div>
    {% endfor %}
</div>

<!-- Detail Panel (sticky sidebar, shown on component click) -->
<div id="detailPanel" class="detail-panel rounded-xl border border-slate-700/50 p-5 hidden w-[420px] shrink-0 sticky top-4 self-start max-h-[calc(100vh-2rem)] overflow-y-auto">
    <div class="flex items-center justify-between mb-3">
        <h3 class="text-sm font-semibold text-white" id="detailTitle"></h3>
        <button onclick="closeDetail()" class="text-slate-500 hover:text-slate-300 text-xs">Close</button>
    </div>
    <div id="detailContent"></div>
</div>
</div><!-- end stackView flex -->

{% endblock %}

{% block extra_scripts %}
<script src="/static/js/plotly.min.js"></script>
<script>
const COMPONENTS = {{ arch.components | tojson }};
const DEPENDENCIES = {{ arch.dependencies | tojson }};
const LAYERS = {{ arch.layers | tojson }};
const GAPS = {{ arch.gaps | tojson }};

const LAYER_COLORS = {
    transport: '#6366f1', identity: '#f59e0b', discovery: '#10b981',
    communication: '#3b82f6', coordination: '#8b5cf6', intelligence: '#ec4899',
    safety: '#ef4444', application: '#06b6d4'
};

const SOURCE_COLORS = {
    ietf: '#3b82f6', w3c: '#f59e0b', etsi: '#f97316',
    itu: '#ec4899', iso: '#a855f7', nist: '#06b6d4'
};

function renderCoverageChart() {
    const sources = ['ietf', 'w3c', 'etsi', 'itu', 'iso', 'nist'];
    const sourceLabels = { ietf: 'IETF', w3c: 'W3C', etsi: 'ETSI', itu: 'ITU-T', iso: 'ISO/IEC', nist: 'NIST' };
    // Sort layers top-down (highest order first)
    const sortedLayers = [...LAYERS].sort((a, b) => b.order - a.order);
    const labels = sortedLayers.map(l => l.label);

    const traces = sources.map(src => ({
        y: labels,
        x: sortedLayers.map(l => (l.coverage[src] || 0)),
        name: sourceLabels[src],
        type: 'bar',
        orientation: 'h',
        marker: { color: SOURCE_COLORS[src], opacity: 0.85 },
        hovertemplate: `%{y}<br>${sourceLabels[src]}: %{x} drafts<extra></extra>`,
    }));

    // Gap markers as annotations
    const gapAnnotations = [];
    sortedLayers.forEach(l => {
        const layerGaps = GAPS.filter(g => g.layer === l.id);
        if (layerGaps.length > 0) {
            const total = sources.reduce((s, src) => s + (l.coverage[src] || 0), 0);
            gapAnnotations.push({
                x: total + 8,
                y: l.label,
                text: `${layerGaps.length} gap${layerGaps.length > 1 ? 's' : ''}`,
                showarrow: false,
                font: { size: 10, color: '#f87171' },
                xanchor: 'left',
            });
        }
    });

    Plotly.newPlot('coverageChart', traces, {
        paper_bgcolor: 'rgba(0,0,0,0)',
        plot_bgcolor: 'rgba(0,0,0,0)',
        barmode: 'stack',
        margin: { l: 180, r: 60, t: 10, b: 30 },
        xaxis: {
            title: { text: 'Documents', font: { size: 11, color: '#64748b' } },
            gridcolor: 'rgba(51,65,85,0.3)',
            tickfont: { size: 10, color: '#94a3b8' },
        },
        yaxis: {
            tickfont: { size: 11, color: '#cbd5e1' },
            automargin: true,
        },
        annotations: gapAnnotations,
        height: 320,
        showlegend: false,
    }, { responsive: true, displayModeBar: false });
}

function selectComponent(compId) {
    const comp = COMPONENTS[compId];
    if (!comp) return;

    document.getElementById('detailPanel').classList.remove('hidden');
    document.getElementById('detailTitle').textContent = comp.name;

    // Find connected components
    const connected = DEPENDENCIES.filter(d => d.source === compId || d.target === compId)
        .map(d => {
            const otherId = d.source === compId ? d.target : d.source;
            return { ...COMPONENTS[otherId], sim: d.similarity, idea_a: d.idea_a, idea_b: d.idea_b };
        })
        .sort((a, b) => b.sim - a.sim);

    // Find gaps in same layer
    const layerGaps = GAPS.filter(g => g.layer === comp.layer);

    let html = `
        <div>
                <div class="text-xs text-slate-500 mb-2">Layer: <span class="text-slate-300">${comp.layer}</span> &middot; Ideas: <span class="text-slate-300">${comp.size}</span> &middot; Maturity: <span class="text-slate-300">${comp.maturity}/5</span></div>

                <div class="text-xs font-semibold text-slate-400 mb-1.5 mt-3">Source Coverage</div>
                <div class="flex flex-wrap gap-2 mb-3">
                    ${Object.entries(comp.sources).map(([s, n]) =>
                        `<span class="text-xs px-2 py-0.5 rounded-full" style="background:${SOURCE_COLORS[s]}22; color:${SOURCE_COLORS[s]}">${s.toUpperCase()}: ${n}</span>`
                    ).join('')}
                </div>

                <div class="text-xs font-semibold text-slate-400 mb-1.5">Idea Types</div>
                <div class="flex flex-wrap gap-1.5 mb-3">
                    ${Object.entries(comp.type_breakdown).map(([t, n]) =>
                        `<span class="text-xs px-2 py-0.5 rounded-full bg-slate-700 text-slate-300">${t} (${n})</span>`
                    ).join('')}
                </div>

                <div class="text-xs font-semibold text-slate-400 mb-1.5">Top Ideas</div>
                <div class="space-y-1 mb-3">
                    ${comp.top_ideas.map(i =>
                        `<div class="text-xs">&bull; ${i.draft_name ? `<a href="/drafts/${i.draft_name}" class="text-blue-400 hover:text-blue-300">${i.title}</a>` : `<span class="text-slate-300">${i.title}</span>`} <span class="text-slate-600">(${i.type})</span></div>`
                    ).join('')}
                </div>

                <div class="text-xs font-semibold text-slate-400 mb-1.5">Drafts (${comp.draft_count})</div>
                <div class="space-y-1 mb-3 max-h-36 overflow-y-auto">
                    ${(comp.drafts || []).map(d =>
                        `<div class="text-xs"><a href="/drafts/${d.name}" class="text-blue-400 hover:text-blue-300">${d.title}</a> <span class="source-dot source-${d.source} ml-1" title="${d.source.toUpperCase()}"></span></div>`
                    ).join('')}
                    ${comp.draft_count > 20 ? `<div class="text-xs text-slate-600 italic">+ ${comp.draft_count - 20} more</div>` : ''}
                </div>

                <div class="text-xs font-semibold text-slate-400 mb-1.5">Connected Components (${connected.length})</div>
                <div class="space-y-1.5 max-h-48 overflow-y-auto mb-3">
                    ${connected.length > 0 ? connected.map(c =>
                        `<div class="text-xs p-2 rounded bg-slate-800/60 border border-slate-700/30">
                            <span class="text-slate-200">${c.name}</span>
                            <span class="text-slate-500 ml-1">(${c.layer})</span>
                            <span class="text-blue-400 ml-1 font-mono">${c.sim.toFixed(3)}</span>
                            <div class="text-slate-600 mt-0.5">${c.idea_a} ↔ ${c.idea_b}</div>
                        </div>`
                    ).join('') : '<div class="text-xs text-slate-600 italic">No connections</div>'}
                </div>

                ${layerGaps.length > 0 ? `
                <div class="text-xs font-semibold text-red-400 mb-1.5">Gaps in Layer (${layerGaps.length})</div>
                <div class="space-y-1.5">
                    ${layerGaps.map(g =>
                        `<div class="text-xs p-2 rounded gap-marker">
                            <span class="severity-${g.severity} font-semibold">${g.severity.toUpperCase()}</span>
                            <span class="text-slate-300 ml-1">${g.topic}</span>
                        </div>`
                    ).join('')}
                </div>` : ''}
        </div>
    `;
    document.getElementById('detailContent').innerHTML = html;

    // Highlight in stack view
    document.querySelectorAll('.comp-node').forEach(n => n.classList.remove('selected'));
    const node = document.querySelector(`[data-comp-id="${compId}"]`);
    if (node) { node.classList.add('selected'); node.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); }
}

function selectGap(gapId) {
    const gap = GAPS.find(g => g.id === gapId);
    if (!gap) return;

    document.getElementById('detailPanel').classList.remove('hidden');
    document.getElementById('detailTitle').innerHTML =
        `<span class="severity-${escapeHtml(gap.severity)}">GAP:</span> ${escapeHtml(gap.topic)}`;

    // Components in same layer (what exists nearby)
    const nearby = COMPONENTS.filter(c => c.layer === gap.layer);
    // Components in adjacent layers
    const layerOrder = {};
    LAYERS.forEach(l => { layerOrder[l.id] = l.order; });
    const gapOrder = layerOrder[gap.layer] || 0;
    const adjacent = COMPONENTS.filter(c => {
        const co = layerOrder[c.layer] || 0;
        return Math.abs(co - gapOrder) === 1;
    });

    const sevLabel = { critical: 'Immediate standardization needed', high: 'Should be addressed soon',
                       medium: 'Worth exploring', low: 'Nice to have' };

    let html = `
        <div>
            <div class="flex items-center gap-2 mb-3">
                <span class="text-xs px-2 py-0.5 rounded-full severity-${gap.severity}"
                      style="background: ${gap.severity === 'critical' ? 'rgba(239,68,68,0.15)' : gap.severity === 'high' ? 'rgba(245,158,11,0.15)' : 'rgba(59,130,246,0.15)'}">
                    ${gap.severity.toUpperCase()}
                </span>
                <span class="text-xs text-slate-500">${gap.category}</span>
                <span class="text-xs text-slate-600">Layer: ${gap.layer}</span>
            </div>

            <div class="text-xs font-semibold text-slate-400 mb-1">What's Missing</div>
            <div class="text-xs text-slate-300 leading-relaxed mb-3">${escapeHtml(gap.description)}</div>

            <div class="text-xs font-semibold text-slate-400 mb-1">Evidence</div>
            <div class="text-xs text-slate-400 leading-relaxed mb-3 p-2 rounded bg-slate-800/60 border border-slate-700/30">${escapeHtml(gap.evidence || 'No evidence recorded')}</div>

            <div class="text-xs font-semibold text-slate-400 mb-1">Priority</div>
            <div class="text-xs text-slate-300 mb-3">${sevLabel[gap.severity] || gap.severity}</div>

            ${nearby.length > 0 ? `
            <div class="text-xs font-semibold text-slate-400 mb-1">Existing Work in Same Layer (${nearby.length})</div>
            <div class="space-y-1 mb-3 max-h-32 overflow-y-auto">
                ${nearby.map(c =>
                    `<div class="text-xs p-2 rounded bg-slate-800/60 border border-slate-700/30 cursor-pointer hover:border-slate-600" onclick="selectComponent(${c.id})">
                        <span class="text-slate-200">${c.name}</span>
                        <span class="text-slate-600 ml-1">${c.size} ideas</span>
                    </div>`
                ).join('')}
            </div>` : `
            <div class="text-xs font-semibold text-red-400 mb-1">No Existing Components in Layer</div>
            <div class="text-xs text-slate-500 mb-3">This layer has no standardization components yet — a greenfield gap.</div>`}

            ${adjacent.length > 0 ? `
            <div class="text-xs font-semibold text-slate-400 mb-1">Adjacent Layer Components (${adjacent.length})</div>
            <div class="space-y-1 max-h-32 overflow-y-auto">
                ${adjacent.map(c =>
                    `<div class="text-xs p-2 rounded bg-slate-800/60 border border-slate-700/30 cursor-pointer hover:border-slate-600" onclick="selectComponent(${c.id})">
                        <span class="text-slate-200">${c.name}</span>
                        <span class="text-slate-500 ml-1">(${c.layer})</span>
                        <span class="text-slate-600 ml-1">${c.size} ideas</span>
                    </div>`
                ).join('')}
            </div>` : ''}
        </div>
    `;
    document.getElementById('detailContent').innerHTML = html;

    // Highlight gap card
    document.querySelectorAll('.comp-node').forEach(n => n.classList.remove('selected'));
    document.querySelectorAll('.gap-marker').forEach(n => n.classList.remove('selected'));
    const card = document.querySelector(`[data-gap-id="${gapId}"]`);
    if (card) { card.classList.add('selected'); }
}

function closeDetail() {
    document.getElementById('detailPanel').classList.add('hidden');
    document.querySelectorAll('.comp-node').forEach(n => n.classList.remove('selected'));
    document.querySelectorAll('.gap-marker').forEach(n => n.classList.remove('selected'));
}

document.addEventListener('DOMContentLoaded', () => {
    renderCoverageChart();
});
</script>
{% endblock %}
