import { describe, expect, it } from 'vitest'
import { execFileSync } from 'node:child_process'
import { mkdtempSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join, resolve } from 'node:path'

const script = resolve('scripts/design-kickoff.mjs')

function runCheck(file: string) {
  return execFileSync('node', [script, '--check', file], {
    cwd: resolve('.'),
    encoding: 'utf8',
    stdio: ['ignore', 'pipe', 'pipe'],
  })
}

function basePacket(feedbackRows: string) {
  return `# Design Kickoff Packet - test

## 1. Task Frame

| Field | Value |
|---|---|
| Request / Jira | FB-TEST |
| Target Figma / URL | https://figma.test/file |
| Scenario | US-3 existing-product increment |
| Source version | frame 1 |
| Owner decision needed before start | None |

## 2. Open Questions Gate

| Question | Why it blocks design | Owner answer |
|---|---|---|
| None | N/A | N/A |

## 3. Baseline / Delta Contract

| Field | Items |
|---|---|
| Keep | current feedback list |
| Change | add low-balance state |
| Remove | None |
| Do not touch | existing success state |

## 4. Semantic Pattern Contract

| semanticRole | instances | expectedPattern | exceptions |
|---|---|---|---|
| feedback message | success, failed | Notification inline alert pattern | None |

## 5. Feedback UI Inventory

| feedbackState | semanticClass | component | widthRule | paddingRule | iconRule | titleRule | bodyRule | actionPattern | exception |
|---|---|---|---|---|---|---|---|---|---|
${feedbackRows}

## 6. UX Principle Contract

| Principle | Evidence |
|---|---|
| Consistency | feedback states use one inventory |
| Usability | primary path remains visible |
| Ease of use | no duplicate feedback patterns |
| Accessibility / readability | copy and icon rules are listed |

## 7. Simplicity Contract

| New module / state / note | User task it supports | Reuse / merge decision | Keep? |
|---|---|---|---|
| low-balance state | understand balance issue | reuse feedback pattern | yes |

## 8. Content Contract

| Concept | Approved wording | Forbidden alternatives | Component text targets |
|---|---|---|---|
| low balance | Low balance | insufficient wallet | inline alert title |

## 9. Component / Token / Icon Mapping

| Element / affordance | Source component / token / icon | Evidence |
|---|---|---|
| inline alert | Notification | Figma library |

## 10. Ready Check

- [x] Open questions are answered or explicitly None.
- [x] Keep / Change / Remove / Do not touch are filled.
- [x] Every semanticRole has one expectedPattern.
- [x] Feedback UI inventory is filled or explicitly None.
- [x] New modules pass the Simplicity Contract.
- [x] Content terms are unique and reused.
- [x] Component / token / icon mapping has evidence.
- [x] If this is a later revision, Regression Snapshot is updated.

## 11. Regression Snapshot

Use after design changes or post-design findings.

| Finding / change | Contract section updated | Regression result |
|---|---|---|
| None | N/A | N/A |
`
}

describe('design kickoff feedback UI inventory gate', () => {
  it('accepts an explicit no-feedback packet', () => {
    const dir = mkdtempSync(join(tmpdir(), 'design-kickoff-'))
    const file = join(dir, 'none.md')
    writeFileSync(file, basePacket('| None | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A |'))
    expect(runCheck(file)).toContain('design kickoff packet ready')
  })

  it('rejects inconsistent feedback patterns within one semantic class', () => {
    const dir = mkdtempSync(join(tmpdir(), 'design-kickoff-'))
    const file = join(dir, 'conflict.md')
    writeFileSync(
      file,
      basePacket([
        '| success | inline alert | Notification | 480 | 16 | success icon | title optional | one-line body | no-action | None |',
        '| failed | inline alert | CustomCard | 520 | 24 | error icon | title required | two-line body | one-action | None |',
      ].join('\n')),
    )
    expect(() => runCheck(file)).toThrow(/feedback-pattern-conflict/)
  })
})
