import { describe, it, expect } from 'vitest'
import { foldTypography, findRange } from './SuggestionHighlight'
import { Schema, type Node as PMNode } from '@tiptap/pm/model'

// A minimal doc/paragraph/text schema, enough to exercise findRange's textblock
// walk without pulling in the full editor.
const schema = new Schema({
  nodes: {
    doc: { content: 'block+' },
    paragraph: { group: 'block', content: 'inline*', toDOM: () => ['p', 0] },
    text: { group: 'inline' },
  },
})

// Build a single-paragraph doc with the given plaintext.
const para = (text: string): PMNode => schema.node('doc', null, [schema.node('paragraph', null, text ? [schema.text(text)] : [])])

describe('foldTypography', () => {
  it('folds curly quotes back to straight ASCII', () => {
    expect(foldTypography('“He’s here,” she said').folded).toBe('"He\'s here," she said')
  })

  it('folds dashes and ellipsis, keeping a source-index map across length changes', () => {
    const { folded, map } = foldTypography('wait—really...')
    expect(folded).toBe('wait—really…')
    // The em dash is already one glyph; the `...` collapsed 3 source chars to 1,
    // so the trailing sentinel still points just past the last source char.
    expect(map[map.length - 1]).toBe('wait—really...'.length)
  })

  it('treats `--` and `...` typed-but-unconverted as their canonical glyphs', () => {
    expect(foldTypography('a--b...c').folded).toBe('a—b…c')
  })
})

describe('findRange typographic anchoring', () => {
  it('anchors a model echo with straight quotes onto curly-quote document text', () => {
    const doc = para('She said “hello” to me')
    const range = findRange(doc, '“hello”'.replace(/[“”]/g, '"')) // model echoed "hello"
    expect(range).not.toBeNull()
    // The matched span must cover the curly-quoted region in the real document.
    expect(doc.textBetween(range!.from - 1, range!.to - 1)).toContain('hello')
  })

  it('anchors an ASCII `--` echo onto an em-dash in the document', () => {
    const doc = para('I waited—forever')
    const range = findRange(doc, 'waited--forever')
    expect(range).not.toBeNull()
  })

  it('still returns null when the text genuinely is not present', () => {
    expect(findRange(para('nothing to see'), 'absent phrase')).toBeNull()
  })
})
