const test = require('node:test')
const assert = require('node:assert')
const {
  preprocessBilditTemplate,
  canonicalizeDoubleParenAsCastTemplates,
} = require('../src/lib/preprocessBilditTemplate')

test('preprocess leaves v2 banner TSX unchanged (no full-file template transform)', () => {
  const code = `// @template v2

export default function X() {
  const label = ('build' as String)
  return <div>{label}</div>
}
`
  assert.strictEqual(preprocessBilditTemplate(code, 'tsx'), code)
})

test('preprocess leaves v2 TSX unchanged when version banner precedes // @template v2', () => {
  const code = `// Hero:v1.0 legacy=false
// @template v2

export default function X() {
  const label = ('build' as String)
  return <div>{label}</div>
}
`
  assert.strictEqual(preprocessBilditTemplate(code, 'tsx'), code)
})

test('preprocess leaves plain TSX without $(…) unchanged', () => {
  const code = `export default function Home() {
  const firstId = 'build'
  return <span>{firstId}</span>
}
`
  assert.strictEqual(preprocessBilditTemplate(code, 'tsx'), code)
})

test('preprocess still rewrites legacy $(…) when there is no v2 banner', () => {
  const code = "const t = $(title:String='hello');"
  const out = preprocessBilditTemplate(code, 'jsx')
  assert.match(out, /hello/)
  assert.ok(!out.includes('$(title:String'))
})

test('preprocess substitutes RichText (quoted default) with object so .text is valid at runtime', () => {
  const code = 'const hero = $(hero:RichText="Hi");'
  const out = preprocessBilditTemplate(code, 'jsx')
  assert.ok(!out.includes('$(hero:RichText'))
  assert.match(out, /\{\s*text:\s*["']Hi["']\s*\}/, 'replaced with { text: … } object, not a bare string')
})

test('preprocess does not corrupt $(…) when TypeScript "as" confuses template-parser', () => {
  const code = "const divLinkHrefValue = $(divLinkHrefValue as String) = '/pricing/');\n"
  const out = preprocessBilditTemplate(code, 'tsx')
  assert.strictEqual(out, code)
  assert.ok(!out.includes('null('), 'must not splice null into a partial $() match')
})

test('canonicalize $((id as Type) = default) to $(id:Type=default)', () => {
  const src =
    "const divLinkText = $((divLinkText as RichText) = 'Default Div Link Text');\n" +
    'const richObj = $((richObj as RichText) = { text: "Hello", color: "#fff" });\n' +
    "const divLinkHrefValue = $((divLinkHrefValue as String) = '/pricing/');\n" +
    'const divLinkRoundedCornersToggle = $((divLinkRoundedCornersToggle as Boolean) = true);\n' +
    'const n = $((n as Number) = 42);\n' +
    'const empty = $((empty as String));\n'
  const out = canonicalizeDoubleParenAsCastTemplates(src, 'tsx')
  assert.ok(out.includes('$(divLinkText:RichText={ text: "Default Div Link Text" })'))
  assert.ok(out.includes('$(richObj:RichText={ text: "Hello", color: "#fff" })'))
  assert.ok(out.includes("$(divLinkHrefValue:String='/pricing/')"))
  assert.ok(out.includes('$(divLinkRoundedCornersToggle:Boolean=true)'))
  assert.ok(out.includes('$(n:Number=42)'))
  assert.ok(out.includes('$(empty:String)'))
  assert.ok(!out.includes('$(('))
})

test('preprocess replaces canonicalized $(…) defaults for transpile', () => {
  const code =
    "const t = $((t as RichText) = 'Hello');\nexport default function F() { return null }\n"
  const out = preprocessBilditTemplate(code, 'tsx')
  assert.ok(!out.includes('$(('))
  assert.ok(!out.includes('$(t:RichText'))
  assert.match(out, /Hello/)
})
