import { describe, expect, it } from 'vitest'
import { ExecuteAsyncEnvelopeSchema, GetExecutionsQuerySchema } from '../api-schemas'

// ---------------------------------------------------------------------------
// ExecuteAsyncEnvelopeSchema
// ---------------------------------------------------------------------------

describe('ExecuteAsyncEnvelopeSchema', () => {
  it('accepts a minimal payload with only resourceId', () => {
    const result = ExecuteAsyncEnvelopeSchema.safeParse({ resourceId: 'my-workflow' })
    expect(result.success).toBe(true)
  })

  it('accepts resourceId with optional input passthrough', () => {
    const result = ExecuteAsyncEnvelopeSchema.safeParse({
      resourceId: 'my-workflow',
      input: { foo: 'bar', nested: { count: 5 } }
    })
    expect(result.success).toBe(true)
    if (result.success) {
      expect(result.data.resourceId).toBe('my-workflow')
      expect(result.data.input).toEqual({ foo: 'bar', nested: { count: 5 } })
    }
  })

  it('accepts any arbitrary input shape (unknown passthrough)', () => {
    const result = ExecuteAsyncEnvelopeSchema.safeParse({
      resourceId: 'some-resource',
      input: [1, 2, 3]
    })
    expect(result.success).toBe(true)
  })

  it('accepts input as null (unknown type allows null)', () => {
    const result = ExecuteAsyncEnvelopeSchema.safeParse({ resourceId: 'r', input: null })
    expect(result.success).toBe(true)
  })

  it('accepts payload without input field (input is optional)', () => {
    const result = ExecuteAsyncEnvelopeSchema.safeParse({ resourceId: 'r' })
    expect(result.success).toBe(true)
    if (result.success) {
      expect(result.data.input).toBeUndefined()
    }
  })

  it('rejects an empty resourceId (minLength 1)', () => {
    expect(ExecuteAsyncEnvelopeSchema.safeParse({ resourceId: '' }).success).toBe(false)
  })

  it('rejects a missing resourceId', () => {
    expect(ExecuteAsyncEnvelopeSchema.safeParse({}).success).toBe(false)
    expect(ExecuteAsyncEnvelopeSchema.safeParse({ input: { x: 1 } }).success).toBe(false)
  })

  it('rejects resourceId as a non-string type', () => {
    expect(ExecuteAsyncEnvelopeSchema.safeParse({ resourceId: 42 }).success).toBe(false)
    expect(ExecuteAsyncEnvelopeSchema.safeParse({ resourceId: null }).success).toBe(false)
  })
})

// ---------------------------------------------------------------------------
// GetExecutionsQuerySchema
// ---------------------------------------------------------------------------

describe('GetExecutionsQuerySchema', () => {
  it('accepts an empty query and applies default limit of 50', () => {
    const result = GetExecutionsQuerySchema.safeParse({})
    expect(result.success).toBe(true)
    if (result.success) {
      expect(result.data.limit).toBe(50)
    }
  })

  it('coerces limit from string "10" to number 10', () => {
    const result = GetExecutionsQuerySchema.safeParse({ limit: '10' })
    expect(result.success).toBe(true)
    if (result.success) expect(result.data.limit).toBe(10)
  })

  it('coerces limit from string "100" to number 100 (upper boundary)', () => {
    const result = GetExecutionsQuerySchema.safeParse({ limit: '100' })
    expect(result.success).toBe(true)
    if (result.success) expect(result.data.limit).toBe(100)
  })

  it('coerces limit from string "1" to number 1 (lower boundary)', () => {
    const result = GetExecutionsQuerySchema.safeParse({ limit: '1' })
    expect(result.success).toBe(true)
    if (result.success) expect(result.data.limit).toBe(1)
  })

  it('rejects limit of 101 (above max 100)', () => {
    expect(GetExecutionsQuerySchema.safeParse({ limit: '101' }).success).toBe(false)
  })

  it('rejects limit of 0 (below min 1)', () => {
    expect(GetExecutionsQuerySchema.safeParse({ limit: '0' }).success).toBe(false)
  })

  it('rejects a negative limit', () => {
    expect(GetExecutionsQuerySchema.safeParse({ limit: '-1' }).success).toBe(false)
  })

  it('rejects a non-numeric string for limit', () => {
    expect(GetExecutionsQuerySchema.safeParse({ limit: 'abc' }).success).toBe(false)
  })

  it('accepts status as an optional string filter', () => {
    const result = GetExecutionsQuerySchema.safeParse({ status: 'running' })
    expect(result.success).toBe(true)
    if (result.success) expect(result.data.status).toBe('running')
  })

  it('accepts status as undefined (optional field omitted)', () => {
    const result = GetExecutionsQuerySchema.safeParse({})
    expect(result.success).toBe(true)
    if (result.success) expect(result.data.status).toBeUndefined()
  })

  it('note: GetExecutionsQuerySchema does not have an offset field', () => {
    // The schema only defines limit and status -- no offset field exists.
    // Passing offset is neither rejected nor coerced (schema is not strict).
    const result = GetExecutionsQuerySchema.safeParse({ limit: '10', offset: '5' })
    expect(result.success).toBe(true)
  })
})
