import { describe, it, expect } from 'vitest'
import {
  toPersisted,
  fromPersisted,
  persistableItems
} from '../src/renderer/src/store/queuePersist'
import type { DownloadItem } from '../src/renderer/src/store/downloadTypes'

function item(over: Partial<DownloadItem>): DownloadItem {
  return {
    id: 'i1',
    url: 'https://example.com/1',
    title: 'Title',
    kind: 'video',
    quality: '1080p',
    status: 'queued',
    progress: 0,
    ...over
  }
}

describe('queuePersist (M4)', () => {
  it('keeps pending states and drops transient completed/canceled', () => {
    const items = [
      item({ id: 'q', status: 'queued' }),
      item({ id: 'd', status: 'downloading' }),
      item({ id: 'p', status: 'paused' }),
      item({ id: 's', status: 'saved', scheduledFor: 123 }),
      item({ id: 'e', status: 'error', error: 'boom' }),
      item({ id: 'c', status: 'completed' }),
      item({ id: 'x', status: 'canceled' })
    ]
    expect(persistableItems(items).map((i) => i.id)).toEqual(['q', 'd', 'p', 's', 'e'])
  })

  it('drops runtime-only fields when persisting', () => {
    const p = toPersisted(
      item({
        progress: 0.5,
        speedBytesPerSec: 1000,
        etaSeconds: 10,
        sizeLabel: '5 MB',
        finishing: true
      })
    )
    expect(p).not.toHaveProperty('progress')
    expect(p).not.toHaveProperty('speedBytesPerSec')
    expect(p).not.toHaveProperty('etaSeconds')
    expect(p).not.toHaveProperty('sizeLabel')
    expect(p).not.toHaveProperty('finishing')
  })

  it('normalizes a downloading item back to queued with progress 0 on restore', () => {
    const restored = fromPersisted(toPersisted(item({ status: 'downloading', progress: 0.7 })))
    expect(restored.status).toBe('queued')
    expect(restored.progress).toBe(0)
  })

  it('preserves saved + scheduledFor across a round-trip (the core M4 promise)', () => {
    const restored = fromPersisted(toPersisted(item({ status: 'saved', scheduledFor: 999 })))
    expect(restored.status).toBe('saved')
    expect(restored.scheduledFor).toBe(999)
  })

  it('round-trips durable fields (formatId/trim/incognito)', () => {
    const restored = fromPersisted(
      toPersisted(
        item({ formatId: '137', formatHasAudio: false, trim: '1:00-2:00', incognito: true })
      )
    )
    expect(restored.formatId).toBe('137')
    expect(restored.trim).toBe('1:00-2:00')
    expect(restored.incognito).toBe(true)
  })
})
