import { describe, expect, it } from 'vitest'
import { normalizeContentInput, ContentValidationError } from './model.js'

const UUID_A = '11111111-1111-4111-8111-111111111111'
const UUID_B = '22222222-2222-4222-8222-222222222222'

describe('normalizeContentInput', () => {
  it('normalizes a valid create input (no id) and dedupes termIds', () => {
    const out = normalizeContentInput({
      slug: 'hello-world',
      type: 'post',
      title: '  Hello  ',
      body: '# hi',
      termIds: [UUID_A, UUID_A, UUID_B],
    })
    expect(out).toEqual({
      id: null,
      slug: 'hello-world',
      type: 'post',
      title: 'Hello',
      body: '# hi',
      visibility: 'public',
      termIds: [UUID_A, UUID_B],
    })
  })

  it('carries a present id through as an update marker', () => {
    const out = normalizeContentInput({ id: 'abc', slug: 'a', type: 'page', title: 'T', body: '' })
    expect(out.id).toBe('abc')
    expect(out.termIds).toBeUndefined()
  })

  it.each([
    [{ slug: 'Bad Slug', type: 'post', title: 'T', body: '' }, 'slug'],
    [{ slug: 'ok', type: '', title: 'T', body: '' }, 'type'],
    [{ slug: 'ok', type: 'post', title: '   ', body: '' }, 'title'],
  ])('throws ContentValidationError(%j) on the offending field %s', (input, field) => {
    try {
      normalizeContentInput(input as never)
      throw new Error('expected throw')
    } catch (e) {
      expect(e).toBeInstanceOf(ContentValidationError)
      expect((e as ContentValidationError).field).toBe(field)
    }
  })

  it('rejects a non-uuid in termIds without coercing', () => {
    expect(() =>
      normalizeContentInput({ slug: 'ok', type: 'post', title: 'T', body: '', termIds: ['not-a-uuid'] }),
    ).toThrow(ContentValidationError)
  })

  it('defaults visibility to public on create and null on update when absent', () => {
    expect(normalizeContentInput({ slug: 'a', type: 'post', title: 'T', body: '' }).visibility).toBe('public')
    expect(normalizeContentInput({ id: 'x', slug: 'a', type: 'post', title: 'T', body: '' }).visibility).toBeNull()
  })

  it('rejects an invalid visibility literal', () => {
    expect(() =>
      normalizeContentInput({ slug: 'a', type: 'post', title: 'T', body: '', visibility: 'secret' as never }),
    ).toThrow(ContentValidationError)
  })
})
