<template>
  <!-- Graphe de DÉPENDANCES (Vue Flow) — lecture OU constructeur (editable) : ajouter des boîtes, les relier (depends_on),
       cliquer pour lier une ACTION (kind), supprimer, glisser pour ranger. Mappe le Flow Template (steps). -->
  <div class="tdg">
    <div class="tdg-bar">
      <div class="tdg-legend">
        <span class="tdg-lg"><span class="tdg-dot" style="background:#ea580c"></span>🚚 Déplacement (terrain)</span>
        <span class="tdg-lg"><span class="tdg-dot" style="background:#2563eb"></span>🏢 À distance (bureau)</span>
        <span class="tdg-lg"><span class="tdg-arrow">→</span> dépend de</span>
      </div>
      <q-space />
      <q-btn v-if="editable" dense unelevated no-caps color="primary" icon="add" label="Ajouter une étape" size="sm" @click="emit('add')" />
    </div>
    <div class="tdg-canvas">
      <VueFlow :nodes="nodes" :edges="edges" :min-zoom="0.3" :max-zoom="2" fit-view-on-init :nodes-draggable="true"
        :nodes-connectable="editable" @connect="onConnect" @node-click="onNodeClick" @node-drag-stop="onDragStop">
        <Background pattern-color="#d6deea" :gap="18" />
        <Controls />
        <template #node-task="{ id, data }">
          <Handle type="target" :position="Position.Left" />
          <div class="tdg-node" :class="{ dispatch: data.dispatch, editable }">
            <button v-if="editable" class="tdg-del" title="Supprimer" @click.stop="emit('delete', id)">✕</button>
            <div class="tdg-node-top">
              <span class="tdg-ic">{{ data.dispatch ? '🚚' : '🏢' }}</span>
              <span class="tdg-st" :style="{ background: data.statusColor }">{{ data.status }}</span>
            </div>
            <div class="tdg-node-title">{{ data.subject }}</div>
            <div class="tdg-node-meta">{{ data.assignee || '—' }}<span v-if="data.when"> · {{ data.when }}</span></div>
          </div>
          <Handle type="source" :position="Position.Right" />
        </template>
      </VueFlow>
    </div>
    <div v-if="editable" class="tdg-hint">Tirez d'un point à l'autre pour relier · clic = éditer l'action · ✕ = supprimer · glissez pour ranger</div>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue'
import { VueFlow, Handle, Position } from '@vue-flow/core'
import { Background } from '@vue-flow/background'
import { Controls } from '@vue-flow/controls'
import '@vue-flow/core/dist/style.css'
import '@vue-flow/core/dist/theme-default.css'
import '@vue-flow/controls/dist/style.css'

// tasks: [{ id, subject, dependsOn:[ids], requiresDispatch, assignee, status, when, pos? }]
const props = defineProps({ tasks: { type: Array, default: () => [] }, editable: { type: Boolean, default: false } })
const emit = defineEmits(['add', 'connect', 'edit', 'delete', 'move'])

const STATUS_COLOR = { Open: '#64748b', Working: '#2563eb', 'Pending Review': '#d97706', Completed: '#16a34a', Cancelled: '#dc2626', Overdue: '#dc2626' }

const nodes = ref([])
const edges = ref([])

function rebuild () {
  const tasks = props.tasks || []
  const byId = {}; for (const t of tasks) byId[t.id] = t
  const memo = {}
  const depth = (id, seen = new Set()) => {
    if (memo[id] != null) return memo[id]
    if (seen.has(id)) return 0
    seen.add(id)
    const deps = (byId[id]?.dependsOn || []).filter(d => byId[d])
    const d = deps.length ? 1 + Math.max(...deps.map(x => depth(x, seen))) : 0
    memo[id] = d; return d
  }
  const perDepth = {}; const n = []
  for (const t of tasks) {
    const d = depth(t.id); perDepth[d] = perDepth[d] || 0
    const pos = (t.pos && typeof t.pos.x === 'number') ? { x: t.pos.x, y: t.pos.y } : { x: d * 280, y: perDepth[d] * 130 }
    n.push({ id: String(t.id), type: 'task', position: pos, data: { subject: t.subject, dispatch: !!t.requiresDispatch, assignee: t.assignee, status: t.status || 'Open', statusColor: STATUS_COLOR[t.status] || '#64748b', when: t.when } })
    perDepth[d]++
  }
  const e = []
  for (const t of tasks) for (const dep of (t.dependsOn || [])) { if (byId[dep]) e.push({ id: `e-${dep}-${t.id}`, source: String(dep), target: String(t.id), animated: !!t.requiresDispatch, style: { stroke: t.requiresDispatch ? '#ea580c' : '#94a3b8', strokeWidth: 2 } }) }
  nodes.value = n; edges.value = e
}
watch(() => props.tasks, rebuild, { immediate: true, deep: true })

function onNodeClick (e) { if (props.editable && e && e.node) emit('edit', e.node.id) }
function onConnect (params) { if (params && params.source && params.target) emit('connect', { source: params.source, target: params.target }) }
function onDragStop (e) { const node = (e && e.node) || (e && e.nodes && e.nodes[0]); if (node) emit('move', { id: node.id, position: { x: node.position.x, y: node.position.y } }) }
</script>

<style scoped>
.tdg { display: flex; flex-direction: column; gap: 8px; }
.tdg-bar { display: flex; align-items: center; }
.tdg-legend { display: flex; flex-wrap: wrap; gap: 16px; font-size: 12px; color: #475569; padding: 0 4px; }
.tdg-lg { display: inline-flex; align-items: center; gap: 5px; }
.tdg-dot { width: 11px; height: 11px; border-radius: 3px; display: inline-block; }
.tdg-arrow { color: #94a3b8; font-weight: 700; }
.tdg-canvas { height: 560px; border: 1px solid #e2e8f0; border-radius: 10px; background: #fafbfc; overflow: hidden; }
.tdg-node { position: relative; background: #fff; border: 2px solid #2563eb; border-radius: 10px; padding: 8px 11px; min-width: 180px; max-width: 240px; box-shadow: 0 1px 5px rgba(15,23,42,.08); }
.tdg-node.dispatch { border-color: #ea580c; background: #fff7ed; }
.tdg-node.editable { cursor: pointer; }
.tdg-node-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 3px; }
.tdg-ic { font-size: 15px; }
.tdg-st { font-size: 9px; font-weight: 700; color: #fff; padding: 1px 6px; border-radius: 8px; text-transform: uppercase; }
.tdg-node-title { font-size: 13px; font-weight: 600; color: #1e293b; line-height: 1.25; }
.tdg-node-meta { font-size: 11px; color: #64748b; margin-top: 3px; }
.tdg-del { position: absolute; top: -8px; right: -8px; width: 18px; height: 18px; border-radius: 50%; border: none; background: #ef4444; color: #fff; font-size: 11px; line-height: 1; cursor: pointer; display: none; }
.tdg-node:hover .tdg-del { display: block; }
.tdg-hint { font-size: 11px; color: #94a3b8; padding: 0 4px; }
</style>
