import { describe, it, expect } from 'vitest'
import { usePreviewCommit } from '../src/composables/usePreviewCommit.js'

// Canonical sync preview→commit flow for maintenance tiles (DRY pattern sweep,
// #753) — the primitive TagMaintenanceCard + PostMaintenanceCard's 6 flows route
// through.

describe('usePreviewCommit', () => {
  it('runPreview loads the projection and toggles previewing', async () => {
    const pc = usePreviewCommit({
      preview: async () => ({ count: 3 }),
      commit: async () => ({ deleted: 3 }),
    })
    expect(pc.previewData.value).toBe(null)
    const p = pc.runPreview()
    expect(pc.previewing.value).toBe(true)
    await p
    expect(pc.previewing.value).toBe(false)
    expect(pc.previewData.value).toEqual({ count: 3 })
  })

  it('runCommit stores the result and collapses to a static emptyPreview', async () => {
    const pc = usePreviewCommit({
      preview: async () => ({ count: 3 }),
      commit: async () => ({ deleted: 3 }),
      emptyPreview: { count: 0, sample_names: [] },
    })
    await pc.runPreview()
    await pc.runCommit()
    expect(pc.result.value).toEqual({ deleted: 3 })
    expect(pc.previewData.value).toEqual({ count: 0, sample_names: [] })
  })

  it('emptyPreview as a function derives the collapsed shape from the result', async () => {
    const pc = usePreviewCommit({
      preview: async () => ({ count: 2 }),
      commit: async () => ({ sample_names: ['a', 'b'] }),
      emptyPreview: (r) => ({ count: 0, sample_names: r.sample_names }),
    })
    await pc.runCommit()
    expect(pc.previewData.value).toEqual({ count: 0, sample_names: ['a', 'b'] })
  })

  it('without emptyPreview the projection stays (dispatch-on-commit variant)', async () => {
    const pc = usePreviewCommit({
      preview: async () => ({ total_changes: 5 }),
      commit: async () => ({ status: 'queued' }),
    })
    await pc.runPreview()
    await pc.runCommit()
    expect(pc.result.value).toEqual({ status: 'queued' })
    expect(pc.previewData.value).toEqual({ total_changes: 5 })  // unchanged
  })

  it('runPreview clears a prior apply result (re-preview hides the badge)', async () => {
    const pc = usePreviewCommit({
      preview: async () => ({ count: 1 }),
      commit: async () => ({ deleted: 1 }),
      emptyPreview: { count: 0 },
    })
    await pc.runCommit()
    expect(pc.result.value).toEqual({ deleted: 1 })
    await pc.runPreview()
    expect(pc.result.value).toBe(null)
  })
})
