// tests/token-exports-parse.test.ts
import { describe, it, expect } from 'vitest'
import { readFileSync } from 'node:fs'
import { fileURLToPath } from 'node:url'
import { dirname, join } from 'node:path'
import { parseCss } from '../figma-sync/generate-token-exports.mjs'

const REAL_CSS = readFileSync(
  join(dirname(fileURLToPath(import.meta.url)), '../src/tokens/variables.css'),
  'utf8'
)

const CSS = `
/* ===== Neutrals ===== */
:root {
  --color-grey-8: #595959;
  --input-line-border: var(--color-grey-8);
}
@font-face { font-family: 'X'; src: url('x.woff'); }
/* ── Spacing ── */
:root { --sp-m: 16px; }
[data-theme="light"] { --color-grey-8: #595959; --bg-layer1: #ffffff; }
`

describe('parseCss', () => {
  it('extracts name/value/scope/section and skips @font-face', () => {
    const toks = parseCss(CSS)
    const grey = toks.find(t => t.name === 'color-grey-8' && t.scope === 'dark')
    expect(grey).toEqual({ name: 'color-grey-8', value: '#595959', scope: 'dark', section: 'Neutrals' })
    const sp = toks.find(t => t.name === 'sp-m')
    expect(sp.section).toBe('Spacing')
    expect(sp.value).toBe('16px')
    const light = toks.find(t => t.name === 'bg-layer1' && t.scope === 'light')
    expect(light.value).toBe('#ffffff')
    // no @font-face internals leaked as tokens
    expect(toks.some(t => t.name === 'font-family' || t.value.includes('url('))).toBe(false)
  })

  it('accumulates multi-line values until the ; terminator, normalized to single spaces', () => {
    const CSS_MULTILINE = `
/* ===== Typography ===== */
:root {
  --font-family-en: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
    'Droid Sans', sans-serif;
  --shadow-l1:
    0 5px 12px 4px #00000017,
    0 3px 6px 0 #0000001f,
    0 1px 2px -2px #00000029;
  --sp-after: 8px;
}
`
    const toks = parseCss(CSS_MULTILINE)
    // shape 1: value begins on the name line, continues to next line
    const font = toks.find(t => t.name === 'font-family-en')
    expect(font.value).toBe(
      "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Droid Sans', sans-serif"
    )
    // shape 2: value entirely on the following lines
    const shadow = toks.find(t => t.name === 'shadow-l1')
    expect(shadow.value).toBe(
      '0 5px 12px 4px #00000017, 0 3px 6px 0 #0000001f, 0 1px 2px -2px #00000029'
    )
    // a plain single-line token after a multi-line one is still captured
    const sp = toks.find(t => t.name === 'sp-after')
    expect(sp.value).toBe('8px')
  })

  it('only decorated comments act as section headers; parenthetical preserved', () => {
    const CSS_SECTIONS = `
/* ===== Neutrals (grey scale) ===== */
:root {
  --color-a: #111;
  /* plain prose aside — must NOT become the section */
  --color-b: #222;
}
`
    const toks = parseCss(CSS_SECTIONS)
    const a = toks.find(t => t.name === 'color-a')
    const b = toks.find(t => t.name === 'color-b')
    // parenthetical qualifier is preserved (not stripped)
    expect(a.section).toBe('Neutrals (grey scale)')
    // prose comment between header and token does NOT clobber section
    expect(b.section).toBe('Neutrals (grey scale)')
  })

  it('matches the real variables.css section contract', () => {
    const toks = parseCss(REAL_CSS)
    const grey = toks.find(t => t.name === 'color-grey-8' && t.scope === 'dark')
    expect(grey.section).toBe('Neutrals (grey scale, light → dark)')
    const font = toks.find(t => t.name === 'font-family-en')
    // Typography header, NOT the prose comment that follows it
    expect(font.section).toBe('Typography')
    const shadow = toks.find(t => t.name === 'shadow-l1')
    expect(shadow.section).toContain('Effect')
  })
})
