const HEADER_HEIGHT = 60
const FIELD_HEIGHT = 28

function escapeXml(value) {
  return String(value ?? '')
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&apos;')
}

function truncate(value, maxLength) {
  const text = String(value ?? '')
  return text.length > maxLength ? `${text.slice(0, maxLength - 3)}...` : text
}

function badgeOf(field) {
  if (field.primary) {
    return { text: 'PK', fill: '#dbeafe', color: '#1d4ed8' }
  }
  if (field.required) {
    return { text: '*', fill: '#fef3c7', color: '#b45309' }
  }
  return { text: '-', fill: '#ffffff', color: '#cbd5e1' }
}

function renderEdge(edge) {
  return `
    <path class="relation-line${edge.inferred ? '' : ' manual'}" d="${escapeXml(edge.path)}" marker-end="url(#er-arrow)" />
    <text class="relation-label" x="${edge.labelX}" y="${edge.labelY}">${escapeXml(edge.fieldName)}</text>`
}

function renderField(field, index) {
  const y = HEADER_HEIGHT + index * FIELD_HEIGHT + 20
  const badge = badgeOf(field)
  return `
      <rect x="12" y="${y - 14}" width="26" height="18" rx="4" fill="${badge.fill}" />
      <text x="25" y="${y}" class="field-badge" fill="${badge.color}">${escapeXml(badge.text)}</text>
      <text x="48" y="${y}" class="field-name">${escapeXml(truncate(field.name, 18))}</text>
      <text x="152" y="${y}" class="field-comment">${escapeXml(truncate(field.comment, 12))}</text>`
}

function renderNode(node) {
  const fields = node.fields.length
    ? node.fields.map(renderField).join('')
    : '<text x="130" y="92" class="field-empty">No fields</text>'

  return `
    <g transform="translate(${node.x}, ${node.y})">
      <rect class="entity-box" width="${node.width}" height="${node.height}" rx="8" />
      <rect class="entity-head-bg" width="${node.width}" height="${HEADER_HEIGHT}" rx="8" />
      <rect x="0" y="52" width="${node.width}" height="8" fill="#eef5ff" />
      <line x1="0" y1="${HEADER_HEIGHT}" x2="${node.width}" y2="${HEADER_HEIGHT}" class="entity-divider" />
      <text x="14" y="27" class="entity-title">${escapeXml(truncate(node.title, 24))}</text>
      <text x="14" y="47" class="entity-comment">${escapeXml(truncate(node.comment, 26))}</text>
      ${fields}
    </g>`
}

export function buildErExportSvg({ width, height, nodes, edges }) {
  const canvasWidth = Math.max(1, Number(width) || 1)
  const canvasHeight = Math.max(1, Number(height) || 1)
  const exportNodes = Array.isArray(nodes) ? nodes : []
  const exportEdges = Array.isArray(edges) ? edges : []

  return `<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="${canvasWidth}" height="${canvasHeight}" viewBox="0 0 ${canvasWidth} ${canvasHeight}">
  <defs>
    <marker id="er-arrow" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth">
      <path d="M0,0 L0,6 L8,3 z" fill="#8aa0bc" />
    </marker>
    <style>
      .relation-line{fill:none;stroke:#8aa0bc;stroke-width:1.6;stroke-dasharray:6 5}
      .relation-line.manual{stroke:#2563eb;stroke-dasharray:none}
      .relation-label{fill:#64748b;font-family:Arial,sans-serif;font-size:12px;paint-order:stroke;stroke:#f8fafc;stroke-width:4px;text-anchor:middle}
      .entity-box{fill:#fff;stroke:#d6e0ee;stroke-width:1}
      .entity-head-bg{fill:#eef5ff}
      .entity-divider{stroke:#e7edf5;stroke-width:1}
      .entity-title{fill:#0f172a;font-family:Arial,sans-serif;font-size:15px;font-weight:700}
      .entity-comment{fill:#64748b;font-family:Arial,sans-serif;font-size:12px}
      .field-badge{font-family:Arial,sans-serif;font-size:11px;font-weight:700;text-anchor:middle}
      .field-name{fill:#334155;font-family:Arial,sans-serif;font-size:13px}
      .field-comment{fill:#94a3b8;font-family:Arial,sans-serif;font-size:12px}
      .field-empty{fill:#94a3b8;font-family:Arial,sans-serif;font-size:13px;text-anchor:middle}
    </style>
  </defs>
  <rect width="100%" height="100%" fill="#f8fafc" />
  <g>${exportEdges.map(renderEdge).join('')}</g>
  <g>${exportNodes.map(renderNode).join('')}</g>
</svg>`
}
