{% extends "base.html" %}

{% block title %}Knowledge Graph - Memory MCP Dashboard{% endblock %}

{% block content %}
<div class="space-y-6">
    <!-- Page Header -->
    <div>
        <h1 class="text-2xl font-bold text-white">Knowledge Graph</h1>
        <p class="text-gray-400 mt-1">Memory relationships and connections</p>
    </div>

    <!-- Stats -->
    <div class="grid grid-cols-2 md:grid-cols-4 gap-4">
        <div class="bg-dark-900 rounded-lg border border-gray-800 p-4">
            <p class="text-xs text-gray-400">Total Relationships</p>
            <p class="text-2xl font-bold text-white">{{ stats.get('total_relationships', 0) }}</p>
        </div>
        <div class="bg-dark-900 rounded-lg border border-gray-800 p-4">
            <p class="text-xs text-gray-400">Connected Memories</p>
            <p class="text-2xl font-bold text-white">{{ stats.get('connected_memories', 0) }}</p>
        </div>
        {% for rel_type, count in stats.get('by_type', {}).items() %}
        <div class="bg-dark-900 rounded-lg border border-gray-800 p-4">
            <p class="text-xs text-gray-400">{{ rel_type }}</p>
            <p class="text-2xl font-bold text-purple-400">{{ count }}</p>
        </div>
        {% endfor %}
    </div>

    <!-- Graph Visualization -->
    <div class="bg-dark-900 rounded-lg border border-gray-800 p-6">
        <div id="graph-container" class="h-96 relative">
            <div id="graph-loading" class="absolute inset-0 flex items-center justify-center text-gray-500">
                Loading graph...
            </div>
            <svg id="graph-svg" class="w-full h-full hidden"></svg>
        </div>
        <div class="mt-4 flex flex-wrap gap-4 text-sm">
            <div class="flex items-center gap-2">
                <span class="w-3 h-3 rounded-full bg-blue-500"></span>
                <span class="text-gray-400">project</span>
            </div>
            <div class="flex items-center gap-2">
                <span class="w-3 h-3 rounded-full bg-purple-500"></span>
                <span class="text-gray-400">pattern</span>
            </div>
            <div class="flex items-center gap-2">
                <span class="w-3 h-3 rounded-full bg-green-500"></span>
                <span class="text-gray-400">reference</span>
            </div>
        </div>
    </div>

    <!-- Relationship List -->
    <div class="bg-dark-900 rounded-lg border border-gray-800 overflow-hidden">
        <div class="px-4 py-3 border-b border-gray-800">
            <h2 class="text-lg font-semibold text-white">Recent Relationships</h2>
        </div>
        <div id="relationship-list" class="divide-y divide-gray-800">
        </div>
    </div>
</div>

<script>
(async function() {
    const resp = await fetch('/api/graph');
    const data = await resp.json();
    const loading = document.getElementById('graph-loading');
    const svg = document.getElementById('graph-svg');
    const list = document.getElementById('relationship-list');

    if (!data.nodes || data.nodes.length === 0) {
        loading.textContent = 'No relationships yet';
        return;
    }

    loading.classList.add('hidden');
    svg.classList.remove('hidden');

    // Simple force-directed layout
    const width = svg.clientWidth || 800;
    const height = svg.clientHeight || 400;
    const nodeMap = new Map();

    // Position nodes randomly
    data.nodes.forEach((node, i) => {
        node.x = width * 0.2 + Math.random() * width * 0.6;
        node.y = height * 0.2 + Math.random() * height * 0.6;
        nodeMap.set(node.id, node);
    });

    // Simple force iterations
    for (let iter = 0; iter < 50; iter++) {
        // Repulsion between nodes
        data.nodes.forEach((a) => {
            data.nodes.forEach((b) => {
                if (a.id !== b.id) {
                    const dx = b.x - a.x;
                    const dy = b.y - a.y;
                    const dist = Math.max(Math.sqrt(dx*dx + dy*dy), 1);
                    const force = 1000 / (dist * dist);
                    a.x -= dx / dist * force;
                    a.y -= dy / dist * force;
                }
            });
        });

        // Attraction along edges
        data.edges.forEach((edge) => {
            const a = nodeMap.get(edge.from);
            const b = nodeMap.get(edge.to);
            if (a && b) {
                const dx = b.x - a.x;
                const dy = b.y - a.y;
                const dist = Math.sqrt(dx*dx + dy*dy);
                const force = dist * 0.01;
                a.x += dx * force;
                a.y += dy * force;
                b.x -= dx * force;
                b.y -= dy * force;
            }
        });

        // Center gravity
        data.nodes.forEach((node) => {
            node.x += (width/2 - node.x) * 0.01;
            node.y += (height/2 - node.y) * 0.01;
            node.x = Math.max(30, Math.min(width - 30, node.x));
            node.y = Math.max(30, Math.min(height - 30, node.y));
        });
    }

    // Draw edges
    data.edges.forEach((edge) => {
        const a = nodeMap.get(edge.from);
        const b = nodeMap.get(edge.to);
        if (a && b) {
            const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
            line.setAttribute('x1', a.x);
            line.setAttribute('y1', a.y);
            line.setAttribute('x2', b.x);
            line.setAttribute('y2', b.y);
            line.setAttribute('stroke', '#4b5563');
            line.setAttribute('stroke-width', '1');
            svg.appendChild(line);
        }
    });

    // Draw nodes
    const colors = {project: '#3b82f6', pattern: '#a855f7', reference: '#22c55e', conversation: '#eab308', episodic: '#6b7280'};
    data.nodes.forEach((node) => {
        const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
        circle.setAttribute('cx', node.x);
        circle.setAttribute('cy', node.y);
        circle.setAttribute('r', '8');
        circle.setAttribute('fill', colors[node.type] || '#6b7280');
        const title = document.createElementNS('http://www.w3.org/2000/svg', 'title');
        title.textContent = node.label;
        circle.appendChild(title);
        svg.appendChild(circle);
    });

    // Populate relationship list
    data.edges.slice(0, 20).forEach((edge) => {
        const from = nodeMap.get(edge.from);
        const to = nodeMap.get(edge.to);
        if (from && to) {
            const row = document.createElement('div');
            row.className = 'p-4 flex items-center gap-4 text-sm';
            const fromSpan = document.createElement('span');
            fromSpan.className = 'text-gray-200 truncate flex-1';
            fromSpan.textContent = from.label;
            const typeSpan = document.createElement('span');
            typeSpan.className = 'px-2 py-0.5 text-xs rounded bg-purple-500/20 text-purple-400 border border-purple-500/30';
            typeSpan.textContent = edge.type;
            const toSpan = document.createElement('span');
            toSpan.className = 'text-gray-200 truncate flex-1';
            toSpan.textContent = to.label;
            row.appendChild(fromSpan);
            row.appendChild(typeSpan);
            row.appendChild(toSpan);
            list.appendChild(row);
        }
    });

    if (data.edges.length === 0) {
        const empty = document.createElement('div');
        empty.className = 'p-8 text-center text-gray-500';
        empty.textContent = 'No relationships found';
        list.appendChild(empty);
    }
})();
</script>
{% endblock %}
