import { createApp, reactive } from 'vue'
import { remarkCtx, schemaCtx, serializerCtx, type Ctx } from '@milkdown/kit/core'
import { $ctx, $node, $prose, $remark, $view } from '@milkdown/kit/utils'
import { Plugin, PluginKey } from '@milkdown/prose/state'
import { type Node as ProseNode, Slice } from '@milkdown/prose/model'
import { Decoration, DecorationSet, type EditorView, type NodeView } from '@milkdown/prose/view'
import { ParserState } from '@milkdown/transformer'
import InputBlockCrepe from '../components/InputBlockCrepe.vue'
import { 
  INPUT_BLOCK_NODE_TYPE, 
  serializeInputBlockSyntax, 
} from '../utils/inputBlock.js'

const INPUT_BLOCK_INPUT_PLUGIN_KEY = new PluginKey('milkdown-input-block')
interface InputBlockConfig { 
  t: (key: string) => string 
}

export const inputBlockNode = $node(INPUT_BLOCK_NODE_TYPE, () => ({
  group: 'block', 
  atom: true, 
  isolating: false, // Allow input blocks to be placed anywhere
  selectable: true, 
  draggable: false, 
  marks: '', // No special marks for input blocks
  attrs: { instruction: false, userInputText: '' }, // Instruction and user text attributes
}))

export const inputBlockRemark = $remark('inputBlockRemark', () => (tree: any) => {
  // Transform markdown AST nodes that match [INPUT] or [INPUT]{instr}***text*** patterns
  tree.children = (tree.children || []).map((child: any) => {
    // Handle fenced code blocks with language "llm-input" or similar syntaxes  
  })
})

export const inputBlockView = $view(inputBlockNode, (ctx) => {
  return (_node: any, _getPos?: () => number | undefined): NodeView => {
    return new InputBlockNodeView(_node, _getPos)  
  }
})

export const inputBlockInputPlugin = $prose(() => {
  return new Plugin({ 
    key: INPUT_BLOCK_INPUT_PLUGIN_KEY,  
    props: {
      handleTextInput(view, _from, to, text) { 
        return tryHandleInputTriggerText(text)  
      },
    } as any, // ProseMirror plugin props type is incomplete in Milkdown types  
  })
})

export const inputBlockHighlightPlugin = $prose(() => { 
  return new Plugin<DecorationSet>({
    key: INPUT_BLOCK_INPUT_PLUGIN_KEY,  
    state: { 
      init() { return DecorationSet.empty },
      apply(tr) { // Transaction mapping for decorations  
        const meta = tr.getMeta(INPUT_BLOCK_INPUT_PLUGIN_KEY)
      }, 
    } as any, // DecorationSet state type is complex in Milkdown  
  })
})

export function insertInputBlockAtSelection(view: EditorView, autoStart = false) {
  return view.dispatch( // Actually inserts the node at cursor position  
    view.state.tr.replaceWith(
      to, 
      inputBlockNode.create({ instruction: '', userInputText: '' }),  
    ) as any, // ReplaceWith returns unknown in Milkdown types
  ).then(() => {}).catch(console.error)  
}INPUT_PLUGIN_EOF

echo "Created inputBlockPlugin.ts" && wc -l /Users/allenyuan/llm-in-text/src/plugins/inputBlockPlugin.ts