/**
 * Rehype plugin to render ABC musical notation using abcjs
 * 
 * This plugin processes code blocks with `language-abc` and replaces them
 * with rendered musical notation using the abcjs library.
 */

import { visit } from 'unist-util-visit'
import type { Root, Element } from 'hast'
import type { Plugin } from 'unified'
import { MAX_CODE_LENGTH, createErrorElement } from '~/lib/security-constants'
import { logger } from '~/lib/logger'

interface AbcOptions {
  // Options for abcjs rendering
  responsive?: 'resize'
  staffwidth?: number
  scale?: number
}

const rehypeAbc: Plugin<[AbcOptions?], Root> = (options = {}) => { // eslint-disable-line @typescript-eslint/no-unused-vars
  return (tree: Root) => {
const nodesToReplace: Array<{ parent: Root | Element; node: Element; index: number; abcCode: string }> = []

    visit(tree, 'element', (node: Element, index: number | undefined, parent: Root | Element | undefined) => {
      // Look for <pre><code class="language-abc">...</code></pre> patterns
      if (
        node.tagName === 'pre' &&
        node.children &&
        node.children.length === 1 &&
        node.children[0].type === 'element' &&
        node.children[0].tagName === 'code'
      ) {
        const codeElement = node.children[0] as Element
        
        // Check if it has the abc language class
        const className = codeElement.properties?.className as string[] | undefined
        if (className && className.includes('language-abc')) {
          // Extract ABC notation code
          const textNode = codeElement.children?.[0]
          if (textNode && textNode.type === 'text') {
            const abcCode = textNode.value as string
            const trimmedCode = abcCode.trim()
            
            // Skip empty blocks
            if (!trimmedCode || !parent || index === undefined) return
            
            // Validate code length
            if (trimmedCode.length > MAX_CODE_LENGTH) {
              (parent.children[index] as Element) = createErrorElement(
                'ABC notation code exceeds maximum allowed length.',
                'abc-notation-error'
              )
              return
            }
            
            if (parent && index !== undefined) {
              nodesToReplace.push({
                parent,
                node,
                index,
                abcCode: abcCode.trim()
              })
            }
          }
        }
      }
    })

    // Replace ABC code blocks with rendered notation
    nodesToReplace.forEach(({ parent, node, index, abcCode }) => { // eslint-disable-line @typescript-eslint/no-unused-vars
      try {
        // Generate a unique ID for this ABC notation
        const id = `abc-notation-${Math.random().toString(36).substr(2, 9)}`
        
        // Use abcjs to render the notation to SVG
        // const renderOptions = {
        //   responsive: options.responsive || 'resize',
        //   staffwidth: options.staffwidth || 740,
        //   scale: options.scale || 1.0,
        //   add_classes: true,
        // }

        // abcjs.renderAbc returns an array of rendered notations
        // We'll create a temporary container to capture the SVG
        //const tempDiv = { innerHTML: '' }
        
        // For server-side rendering, we need to use renderAbc differently
        // Let's create the HTML structure that will be enhanced client-side
        const wrapper: Element = {
          type: 'element',
          tagName: 'div',
          properties: {
            className: ['abc-notation-wrapper', 'my-6', 'p-4', 'bg-gray-50', 'dark:bg-gray-800', 'rounded-lg', 'border', 'border-gray-200', 'dark:border-gray-700'],
            dataAbcNotation: abcCode,
            dataAbcId: id
          },
          children: [
            {
              type: 'element',
              tagName: 'div',
              properties: {
                id,
                className: ['abc-notation-container']
              },
              children: []
            },
            // Keep the original code as a fallback
            {
              type: 'element',
              tagName: 'details',
              properties: {
                className: ['abc-notation-source', 'mt-4']
              },
              children: [
                {
                  type: 'element',
                  tagName: 'summary',
                  properties: {
                    className: ['text-sm', 'text-gray-600', 'dark:text-gray-400', 'cursor-pointer']
                  },
                  children: [
                    {
                      type: 'text',
                      value: 'Show ABC notation source'
                    }
                  ]
                },
                {
                  type: 'element',
                  tagName: 'pre',
                  properties: {
                    className: ['mt-2', 'p-2', 'rounded', 'text-sm', 'overflow-auto']
                  },
                  children: [
                    {
                      type: 'element',
                      tagName: 'code',
                      properties: {},
                      children: [
                        {
                          type: 'text',
                          value: abcCode
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        }

        // Replace the original pre/code block with our wrapper
        parent.children[index] = wrapper
      } catch (error) {
        logger.error({ error }, 'Error processing ABC notation:')
        parent.children[index] = createErrorElement(
          'Failed to render ABC notation. Please check your syntax.',
          'abc-notation-error'
        )
      }
    })
  }
}

export default rehypeAbc