<template>
    <div ref="cyContainer" class="cy-container"></div>
  </template>
  
  <script setup>
  import { ref, onMounted, nextTick } from 'vue'
  import cytoscape from 'cytoscape'
  
  if (typeof document !== 'undefined') {
    const script = document.createElement('script');
    script.src = '/dist/cy_custom.js';
    script.onload = () => {
      window.igvCustomLoaded = true;
    };
    document.head.appendChild(script);
  }

  let CytoscapeOverlays = null

    if (import.meta.client) {
    const useOverlay = (await import('@/composables/useOverlay')).default
    CytoscapeOverlays = await useOverlay()
    }

  const cyContainer = ref(null)
  
  onMounted(async () => {
    await nextTick()

    cytoscape.use(CytoscapeOverlays.default)
  
    const res = await fetch('/pon00061.xml')
    const xmlText = await res.text()
    const parser = new DOMParser()
    const xmlDoc = parser.parseFromString(xmlText, 'application/xml')
  
    const scale = 3
    const entryMap = new Map()
    const entryDataMap = new Map()
    const parentMap = new Map()
  
    const entries = Array.from(xmlDoc.getElementsByTagName('entry'))
  
    for (const entry of entries) {
      const id = entry.getAttribute('id')
      entryDataMap.set(id, entry)
      if (entry.getAttribute('type') === 'group') {
        const components = entry.getElementsByTagName('component')
        for (const comp of components) {
          parentMap.set(comp.getAttribute('id'), id)
        }
      }
    }
  
    const nodes = entries.map(entry => {
      const id = entry.getAttribute('id')
      const graphics = entry.getElementsByTagName('graphics')[0]
      const x = parseFloat(graphics?.getAttribute('x') || '0') * scale
      const y = parseFloat(graphics?.getAttribute('y') || '0') * scale
      const label = graphics?.getAttribute('name') || id
      const fgColor = graphics?.getAttribute('fgcolor') || '#000000'
      const bgColor = graphics?.getAttribute('bgcolor') || '#ffffff'
      const parent = parentMap.get(id)
  
      const valueA = Math.floor(Math.random() * 50)
      const valueB = 100 - valueA
  
      const node = {
        data: {
          id,
          label,
          link: entry.getAttribute('link') || null,
          reaction: entry.getAttribute('reaction') || null,
          chartData: [valueA, valueB]
        },
        position: { x, y },
        classes: entry.getAttribute('type'),
        style: {
          color: fgColor,
          'background-color': bgColor
        }
      }
  
      if (parent) node.data.parent = parent
      entryMap.set(id, true)
      return node
    })
  
    function resolveToRealNode(id) {
      if (!entryMap.has(id)) return null
      const entry = entryDataMap.get(id)
      if (entry?.getAttribute('type') === 'group') {
        const components = Array.from(entry.getElementsByTagName('component'))
        if (components.length > 0) return components[0].getAttribute('id')
      }
      return id
    }
  
    const edges = []
    const relations = Array.from(xmlDoc.getElementsByTagName('relation'))
    relations.forEach((rel, i) => {
      const source = resolveToRealNode(rel.getAttribute('entry1'))
      const target = resolveToRealNode(rel.getAttribute('entry2'))
      const type = rel.getAttribute('type')
      const subtypes = Array.from(rel.getElementsByTagName('subtype'))
      const compoundSubtype = subtypes.find(s => s.getAttribute('name') === 'compound')

      if (compoundSubtype) {
        const compoundId = compoundSubtype.getAttribute('value')
        if (entryMap.has(source) && entryMap.has(target) && entryMap.has(compoundId)) {
          const sourceConst = source;
          const targetConst = target;
          edges.push(
            {
              data: {
                id: `edge${i}-1`,
                source: sourceConst,
                target: compoundId,
                label: 'via compound'
              }
            },
            {
              data: {
                id: `edge${i}-2`,
                source: compoundId,
                target: targetConst,
                label: 'via compound'
              }
            }
          )
        }
      } else {
        if (entryMap.has(source) && entryMap.has(target)) {
          const sourceConst = source;
          const targetConst = target;
          edges.push({
            data: {
              id: `edge${i}`,
              source: sourceConst,
              target: targetConst,
              label: type
            }
          })
        }
      }
    })
  
    const reactions = Array.from(xmlDoc.getElementsByTagName('reaction'))
    reactions.forEach((reaction, i) => {
      const reactionType = reaction.getAttribute('type')
      const substrates = Array.from(reaction.getElementsByTagName('substrate'))
      const products = Array.from(reaction.getElementsByTagName('product'))
      substrates.forEach(substrate => {
        const sid = resolveToRealNode(substrate.getAttribute('id'))
        products.forEach(product => {
          const pid = resolveToRealNode(product.getAttribute('id'))
          if (entryMap.has(sid) && entryMap.has(pid)) {
            edges.push({
              data: {
                id: `reaction-${i}-${sid}-${pid}`,
                source: sid,
                target: pid,
                label: `${reactionType}`
              }
            })
          }
        })
      })
    })
  
    // 원형(도넛/파이) 차트 overlay 생성 (흰색 라인 없이)
    const pieOverlay = CytoscapeOverlays.renderSymbol({
      symbol: node => {
        const data = node.data('chartData') || [50, 50]
        return {
          draw: (ctx, size) => {
            const total = data[0] + data[1]
            const r = Math.sqrt(size / Math.PI)
            const innerR = r * 0.5
            const startAngle = 0
            const angleA = (data[0] / total) * 2 * Math.PI

            // A 영역
            ctx.beginPath()
            ctx.arc(0, 0, r, startAngle, startAngle + angleA)
            ctx.arc(0, 0, innerR, startAngle + angleA, startAngle, true)
            ctx.closePath()
            ctx.fillStyle = '#36a2eb'
            ctx.fill()

            // B 영역
            ctx.beginPath()
            ctx.arc(0, 0, r, startAngle + angleA, startAngle + 2 * Math.PI)
            ctx.arc(0, 0, innerR, startAngle + 2 * Math.PI, startAngle + angleA, true)
            ctx.closePath()
            ctx.fillStyle = '#ff6384'
            ctx.fill()
          }
        }
      },
      color: '',
      width: 32,
      height: 32,
      borderColor: '#333'
    })

    const cy = cytoscape({
      container: cyContainer.value,
      elements: { nodes, edges },
      style: [
        { selector: 'node', style: {
            label: 'data(label)',
            'background-color': '#eee',
            'text-valign': 'center',
            'text-halign': 'center',
            'border-width': 2,
            'border-color': '#333',
            'font-size': 8,
            'padding': '6px',
            'width': 32,
            'height': 32,
          }
        },
        { selector: 'edge', style: { 'curve-style': 'bezier', 'target-arrow-shape': 'triangle', 'line-color': '#888' } },
      ],
      layout: { name: 'preset', padding: 100 }
    })

    cy.overlays(
      [
        { position: 'right', vis: pieOverlay }
      ],
      {
        updateOn: 'render',
        backgroundColor: 'white'
      }
    )

    applyCustomZoomHandling(cy);

});
  </script>
  
  <style>
  .cy-container {
    width: 100vw !important;
    max-width: 100vw !important;
    min-width: 0 !important;
    height: 800px !important;
    overflow: hidden !important;
    position: relative;
  }
  </style>
  