{% extends "base.html" %}
{% import "macros/ui.html" as m %}
{% block title %}{{ ws_name }} · DAG{% endblock %}
{% block nav_workspaces %}btn-active{% endblock %}
{% block main_class %}p-0{% endblock %}

{% block nav_brand %}
<a href="/ui/" class="btn btn-ghost font-mono text-base-content/40 text-sm">⚙ {{ project_name }}</a>
<span class="text-base-content/20 mx-1">/</span>
<a href="/ui/workspaces" class="btn btn-ghost font-mono text-base-content/50 text-sm">workspaces</a>
<span class="text-base-content/20 mx-1">/</span>
<a href="/ui/workspaces/{{ ws_name }}" class="btn btn-ghost font-mono text-primary text-sm">{{ ws_name }}</a>
<span class="text-base-content/20 mx-1">/</span>
<span class="font-mono text-base-content/70 text-sm">dag</span>
{% endblock %}

{% block head %}
<style>
  #dag-root { display: flex; height: calc(100vh - 64px - 48px); min-height: 400px; }
  #cy-wrap  { flex: 1 1 auto; min-width: 0; position: relative; }
  #cy       { width: 100%; height: 100%; }
  #dag-controls {
    position: absolute; bottom: 14px; right: 14px; z-index: 10;
    display: flex; flex-direction: column; gap: 4px;
  }
  #dag-controls button {
    width: 30px; height: 30px; border-radius: 6px;
    border: 1px solid rgba(255,255,255,0.1); background: rgba(0,0,0,0.6);
    color: #fff; font-size: 16px; cursor: pointer;
  }
  #dag-controls button:hover { background: rgba(80,80,80,0.8); }
  #dag-sidebar {
    width: 260px; flex-shrink: 0; overflow-y: auto;
    background: oklch(var(--b2, 20% 0 0));
    border-left: 1px solid oklch(var(--b3, 15% 0 0));
    padding: 1rem; font-size: 0.75rem;
  }
</style>
{% endblock %}

{% block content %}
<div class="px-4 pt-3 pb-2 flex items-center gap-3 border-b border-base-300">
  {{ m::ws_tabs(ws_name=ws_name, active=ws_active_tab, ws_envs=ws_envs, ws_has_clusters=ws_has_clusters, ws_has_workflows=ws_has_workflows, current_env=current_env) }}
  {% if env_name %}
  <span class="badge badge-ghost badge-sm font-mono ml-auto">env: {{ env_name }}</span>
  {% endif %}
</div>

<div id="dag-root">
  <div id="cy-wrap">
    <div id="cy"></div>
    <div id="dag-controls">
      <button onclick="cy.fit()" title="Fit">⊡</button>
      <button onclick="cy.zoom(cy.zoom()*1.25)" title="Zoom in">+</button>
      <button onclick="cy.zoom(cy.zoom()*0.8)" title="Zoom out">−</button>
      <button onclick="resetLayout()" title="Re-layout">↺</button>
    </div>
  </div>
  <div id="dag-sidebar">
    <p class="text-base-content/40 text-xs mb-3">Click a node to inspect.</p>
    <div id="node-detail"></div>
  </div>
</div>

<script>
const DAG = {{ dag_json | safe }};
let cy = null;

function nodeColor(n) {
  const kind = (n.kind || n.type || '').toLowerCase();
  if (kind === 'formula')   return '#6366f1';
  if (kind === 'component') return '#22c55e';
  if (kind === 'cluster')   return '#f59e0b';
  if (kind === 'task')      return '#3b82f6';
  return '#6b7280';
}

function buildElements() {
  const nodes = (DAG.nodes || []).map(n => ({
    data: {
      id:          n.id,
      label:       n.label || n.id,
      kind:        n.kind || 'node',
      description: n.description || '',
      color:       nodeColor(n),
      health_gate: n.health_gate || false,
    }
  }));
  const edges = (DAG.edges || []).map(e => ({
    data: {
      id:     e.id,
      source: e.source,
      target: e.target,
      kind:   e.kind || '',
    }
  }));
  return [...nodes, ...edges];
}

function initCytoscape() {
  cy = cytoscape({
    container: document.getElementById('cy'),
    elements: buildElements(),
    style: [
      {
        selector: 'node',
        style: {
          'background-color': 'data(color)',
          'label':            'data(label)',
          'color':            '#f1f5f9',
          'font-size':        '8px',
          'font-family':      'ui-monospace, monospace',
          'text-valign':      'center',
          'text-halign':      'center',
          'text-wrap':        'wrap',
          'text-max-width':   '56px',
          'text-overflow-wrap': 'anywhere',
          'width': 72, 'height': 72,
          'border-width': 2,
          'border-color': 'rgba(255,255,255,0.15)',
        }
      },
      {
        selector: 'node[?health_gate]',
        style: { 'border-width': 3, 'border-color': '#a5b4fc', 'border-style': 'double' }
      },
      {
        selector: 'edge',
        style: {
          'width': 1.5,
          'line-color':          'rgba(156,163,175,0.4)',
          'target-arrow-color':  'rgba(156,163,175,0.6)',
          'target-arrow-shape':  'triangle',
          'curve-style':         'bezier',
          'arrow-scale':         0.8,
        }
      },
      {
        selector: 'node:selected',
        style: { 'border-color': '#818cf8', 'border-width': 3 }
      },
    ],
    layout: { name: 'cose', animate: false, nodeRepulsion: 8000, idealEdgeLength: 100, gravity: 0.25 },
  });

  cy.on('tap', 'node', function(evt) {
    const d = evt.target.data();
    document.getElementById('node-detail').innerHTML = `
      <div class="mb-2">
        <span class="badge badge-xs" style="background:${d.color}">${d.kind}</span>
        ${d.health_gate ? '<span class="badge badge-xs badge-info ml-1">health-gate</span>' : ''}
      </div>
      <p class="font-mono font-semibold text-sm mb-1">${d.label}</p>
      <p class="text-base-content/60 text-xs">${d.description}</p>
    `;
  });
  cy.on('tap', function(evt) {
    if (evt.target === cy) document.getElementById('node-detail').innerHTML = '';
  });
}

function resetLayout() {
  if (cy) cy.layout({ name: 'cose', animate: true, nodeRepulsion: 8000, idealEdgeLength: 100 }).run();
}

if (typeof cytoscape !== 'undefined') {
  initCytoscape();
} else {
  const s = document.createElement('script');
  s.src = 'https://cdn.jsdelivr.net/npm/cytoscape@3.30.2/dist/cytoscape.min.js';
  s.onload = initCytoscape;
  document.head.appendChild(s);
}
</script>
{% endblock %}
