/**
 * SVG tools — insert SVG diagrams/images into documents via Y.js.
 */
import * as Y from 'yjs'
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { z } from 'zod'
import type { AbracadabraMCPServer } from '../server.ts'
import { sanitizeSvg } from '../utils/sanitizeSvg.ts'

/**
 * Find the insertion index after documentHeader and documentMeta elements.
 */
function findContentStart(fragment: Y.XmlFragment): number {
  let idx = 0
  for (let i = 0; i < fragment.length; i++) {
    const child = fragment.get(i)
    if (child instanceof Y.XmlElement) {
      const name = child.nodeName
      if (name === 'documentHeader' || name === 'documentMeta') {
        idx = i + 1
      } else {
        break
      }
    }
  }
  return idx
}

export function registerSvgTools(mcp: McpServer, server: AbracadabraMCPServer) {
  mcp.tool(
    'write_svg',
    'Insert an SVG diagram or image into a document. Creates an svgEmbed block node containing the SVG markup. Use this for diagrams, charts, flowcharts, illustrations, icons, or any visual content expressed as SVG. The SVG is sanitized server-side before writing.',
    {
      docId: z.string().describe('Document ID to write SVG into.'),
      svg: z.string().describe('Raw SVG markup string (the full <svg>...</svg> element). Will be sanitized.'),
      title: z.string().optional().describe('Optional title/caption displayed above the SVG.'),
      position: z.enum(['append', 'prepend']).optional().describe('Where to insert the SVG block. "append" adds at the end (default), "prepend" adds at the start of content.'),
    },
    async ({ docId, svg, title, position }) => {
      try {
        server.setAutoStatus('writing', docId)
        server.setActiveToolCall({ name: 'write_svg', target: docId })

        const cleanSvg = sanitizeSvg(svg)
        if (!cleanSvg) {
          return {
            content: [{ type: 'text', text: 'Error: SVG markup was empty or entirely stripped by sanitizer.' }],
            isError: true,
          }
        }

        const provider = await server.getChildProvider(docId)
        const doc = provider.document
        const fragment = doc.getXmlFragment('default')

        doc.transact(() => {
          const el = new Y.XmlElement('svgEmbed')
          el.setAttribute('svg', cleanSvg)
          if (title) el.setAttribute('title', title)

          const insertPos = position === 'prepend'
            ? findContentStart(fragment)
            : fragment.length
          fragment.insert(insertPos, [el])
        })

        server.setFocusedDoc(docId)

        return {
          content: [{ type: 'text', text: `SVG inserted into document ${docId}${title ? ` ("${title}")` : ''}` }],
        }
      } catch (error: any) {
        return {
          content: [{ type: 'text', text: `Error writing SVG: ${error.message}` }],
          isError: true,
        }
      }
    }
  )
}
