/**
 * Composable de migration des données architecture
 * Convertit le format v1 (items/splines) vers le format v2 (nodes/edges Vue Flow)
 */
import { MarkerType } from '@vue-flow/core'

const KNOWN_PREFIXES = ['world', 'home', 'computer', 'network', 'room', 'vm', 'service']

/**
 * Détecte le format des données
 */
export function detectFormat(data) {
  if (!data) return 'empty'
  if (data.version === 2 || data.nodes) return 'v2'
  if (data.items) return 'v1'
  return 'empty'
}

/**
 * Extrait le type de noeud depuis l'instanceId (ex: "computer-1766718222451-7tyo" → "computer")
 */
function extractNodeType(item) {
  const prefix = (item.instanceId || '').split('-')[0]
  if (KNOWN_PREFIXES.includes(prefix)) return prefix

  // Fallback par type sémantique
  if (item.type === 'container') {
    if (item.id === 'internet' || item.id === 'world') return 'world'
    if (item.id === 'room') return 'room'
    return 'home'
  }
  if (item.type === 'device') return 'computer'
  if (item.type === 'network') return 'network'
  if (item.type === 'vm') return 'vm'
  if (item.type === 'service') return 'service'
  return 'computer'
}

/**
 * Applique l'opacité sur une couleur hex/rgb
 */
export function applyFillOpacity(color, opacity) {
  if (!color || color === 'transparent') return 'transparent'
  const alpha = typeof opacity === 'number' ? opacity : 1
  if (color.startsWith('#')) {
    let hex = color.slice(1)
    if (hex.length === 3) hex = hex.split('').map(c => c + c).join('')
    hex = hex.padEnd(6, '0')
    const r = parseInt(hex.slice(0, 2), 16)
    const g = parseInt(hex.slice(2, 4), 16)
    const b = parseInt(hex.slice(4, 6), 16)
    return `rgba(${r}, ${g}, ${b}, ${alpha})`
  }
  if (color.startsWith('rgb(')) {
    const match = color.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/)
    if (match) return `rgba(${match[1]}, ${match[2]}, ${match[3]}, ${alpha})`
  }
  return color
}

/**
 * Convertit un dash style en strokeDasharray CSS
 */
export function dashToStrokeDasharray(dash) {
  if (dash === 'dashed') return '6 4'
  if (dash === 'dotted') return '2 4'
  return '0'
}

/**
 * Convertit un cap (startCap/endCap) en marker Vue Flow
 */
function capToMarker(cap, color) {
  if (cap === 'arrow') return { type: MarkerType.ArrowClosed, color: color || '#56A7FF' }
  return undefined
}

/**
 * Convertit un item legacy en noeud Vue Flow
 */
export function itemToNode(item) {
  return {
    id: item.instanceId,
    type: 'arch-node',
    position: { x: item.x || 0, y: item.y || 0 },
    style: {
      width: `${item.width || 120}px`,
      height: `${item.height || 44}px`,
    },
    zIndex: item.zIndex || 1,
    draggable: !item.locked,
    data: {
      // Type de la palette
      nodeType: extractNodeType(item),
      // Identité
      instanceId: item.instanceId,
      id: item.id || '',
      name: item.name || '',
      label: item.label || '',
      type: item.type || '',
      icon: item.icon || '',
      iconSize: item.iconSize || 16,
      // Couleurs
      borderColor: item.borderColor || '#B5B5B5',
      fillColor: item.fillColor || 'transparent',
      color: item.color || '#E6E6E6',
      opacity: typeof item.opacity === 'number' ? item.opacity : 1,
      borderWidth: item.borderWidth || 2,
      borderStyle: item.borderStyle || 'solid',
      fontColor: item.fontColor || '#E6E6E6',
      fontSize: item.fontSize || 14,
      // Connecteurs (interfaces réseau)
      connectTop: item.connectTop || 0,
      connectBottom: item.connectBottom || 0,
      connectLeft: item.connectLeft || 0,
      connectRight: item.connectRight || 0,
      connectorColor: item.connectorColor || '#B5B5B5',
      connectorSize: item.connectorSize || 12,
      connectorStrokeColor: item.connectorStrokeColor || '#1E1F1C',
      // IP et réseau
      ipAddress: item.ipAddress || '',
      ipData: item.ipData || null,
      online: item.online || false,
      // Relations
      parentId: item.parentId || '',
      childrenIds: item.childrenIds || [],
      parent: item.parent || '',
      room: item.room || '',
      // État
      locked: item.locked || false,
    }
  }
}

/**
 * Convertit une spline legacy en edge Vue Flow
 */
export function splineToEdge(spline) {
  const color = spline.style?.color || '#56A7FF'
  const width = spline.style?.width || 2
  const dash = spline.style?.dash || 'solid'

  const style = {
    stroke: color,
    strokeWidth: width,
  }
  if (dash !== 'solid') {
    style.strokeDasharray = dashToStrokeDasharray(dash)
  }

  return {
    id: spline.id,
    source: spline.from?.nodeId,
    target: spline.to?.nodeId,
    sourceHandle: `${spline.from?.side || 'right'}-${spline.from?.index || 0}`,
    targetHandle: `${spline.to?.side || 'left'}-${spline.to?.index || 0}`,
    type: 'default',
    style,
    markerStart: capToMarker(spline.style?.startCap, color),
    markerEnd: capToMarker(spline.style?.endCap, color),
    data: {
      color,
      width,
      dash,
      startCap: spline.style?.startCap || 'none',
      endCap: spline.style?.endCap || 'none',
    }
  }
}

/**
 * Convertit un noeud Vue Flow en format de sauvegarde
 */
export function nodeToSaveFormat(node) {
  const result = {
    id: node.id,
    type: node.type,
    position: { ...node.position },
    style: node.style ? { ...node.style } : {},
    zIndex: node.zIndex || 1,
    draggable: node.draggable !== false,
    data: { ...node.data },
  }
  // Nesting : sauvegarder les propriétés parentNode/extent
  if (node.parentNode) {
    result.parentNode = node.parentNode
    result.extent = 'parent'
    result.expandParent = true
  }
  return result
}

/**
 * Convertit un edge Vue Flow en format de sauvegarde
 */
export function edgeToSaveFormat(edge) {
  return {
    id: edge.id,
    source: edge.source,
    target: edge.target,
    sourceHandle: edge.sourceHandle,
    targetHandle: edge.targetHandle,
    type: edge.type || 'default',
    style: edge.style ? { ...edge.style } : {},
    markerStart: edge.markerStart,
    markerEnd: edge.markerEnd,
    data: edge.data ? { ...edge.data } : {},
  }
}

/**
 * Point d'entrée : charge et migre les données si nécessaire
 */
export function migrateData(rawData) {
  const format = detectFormat(rawData)

  if (format === 'empty') {
    return { nodes: [], edges: [], version: 2 }
  }

  if (format === 'v2') {
    return {
      nodes: rawData.nodes || [],
      edges: rawData.edges || [],
      version: 2,
    }
  }

  // Format v1 → convertir
  const nodes = (rawData.items || []).map(itemToNode)
  const edges = (rawData.splines || []).map(splineToEdge)

  // Restaurer les relations parentNode depuis parentId
  const nodeIds = new Set(nodes.map(n => n.id))
  for (const node of nodes) {
    if (node.data.parentId && nodeIds.has(node.data.parentId)) {
      node.parentNode = node.data.parentId
      node.extent = 'parent'
      node.expandParent = true
    }
  }

  console.log(`[Architecture] Migration v1→v2 : ${nodes.length} nodes, ${edges.length} edges`)

  return { nodes, edges, version: 2 }
}
