import { HttpResponse, delay } from 'msw'

/** Small, opinionated wrappers over MSW's response helpers used across handlers + tests. */

export function jsonResponse<T>(body: T, init?: ResponseInit) {
  return HttpResponse.json(body as object, init)
}

export function errorResponse(status: number, message: string) {
  return HttpResponse.json({ error: message, status }, { status })
}

export function noContent() {
  return new HttpResponse(null, { status: 204 })
}

export function paginate<T>(items: T[], page = 1, pageSize = items.length) {
  const start = (page - 1) * pageSize
  const slice = items.slice(start, start + pageSize)
  return { items: slice, totalCount: items.length, page, pageSize }
}

/** Inject latency into a handler. Use as: `await latency(50)` inside the resolver. */
export function latency(ms: number) {
  return delay(ms)
}

/** Build a Server-Sent-Events (SSE) `text/event-stream` body from a sequence of payloads. */
export function sse(events: Array<{ event?: string; data: unknown; id?: string }>) {
  const encoder = new TextEncoder()
  const stream = new ReadableStream({
    start(controller) {
      for (const e of events) {
        const lines: string[] = []
        if (e.id !== undefined) lines.push(`id: ${e.id}`)
        if (e.event !== undefined) lines.push(`event: ${e.event}`)
        const payload = typeof e.data === 'string' ? e.data : JSON.stringify(e.data)
        for (const line of payload.split('\n')) lines.push(`data: ${line}`)
        lines.push('', '')
        controller.enqueue(encoder.encode(lines.join('\n')))
      }
      controller.close()
    },
  })
  return new HttpResponse(stream, {
    headers: {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      Connection: 'keep-alive',
    },
  })
}

/** Drop the connection mid-flight (used by resilience tests). */
export function dropResponse() {
  return HttpResponse.error()
}
