import { describe, expect, it } from 'vitest'
import { normalizeContentInput, ContentValidationError, type ContentStatus, type FinalContentEntry } 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)
  })
})

describe('final content entry migration contract', () => {
  it('includes review status and completion fields without storing password credentials', () => {
    const status: ContentStatus = 'pending'
    const entry: FinalContentEntry = {
      id: UUID_A,
      slug: 'review-me',
      type: 'post',
      title: 'Review me',
      body: '',
      status,
      visibility: 'public',
      publishedAt: null,
      author: 'author-1',
      terms: [],
      createdAt: new Date('2026-08-01T00:00:00.000Z'),
      updatedAt: new Date('2026-08-01T00:00:00.000Z'),
      parentId: null,
      menuOrder: 0,
      templateKey: null,
      excerpt: '',
      featuredMedia: null,
      commentStatus: 'open',
      pingStatus: 'open',
      passwordProtected: false,
      sticky: false,
      format: null,
      deletedAt: null,
      lastEditedBy: 'author-1',
      typeDefinitionRevision: 1,
      statusDefinitionRevision: 1,
    }

    expect(entry.status).toBe('pending')
    expect(entry.passwordProtected).toBe(false)
    expect('credential' in entry).toBe(false)
  })
})
