/**
 * Resend sendEmail — idempotency-key regression tests
 *
 * Guards the Idempotency-Key header plumbing added as part of the
 * cache-as-contract-leak fix. Platform-internal retries (TypeError /
 * ReferenceError reclassified as platform_internal) must be safe for write
 * tools — Resend dedupes server-side when the same Idempotency-Key arrives.
 */

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
import { sendEmail } from './index'
import type { ResendCredentials, SendEmailParams } from '../utils/types'

const credentials: ResendCredentials = { apiKey: 're_test_123' }
const baseParams: SendEmailParams = {
  from: 'Test <test@elevasis.io>',
  to: 'recipient@example.com',
  subject: 'Hello',
  html: '<p>Hi</p>'
}

function mockResendOk(): ReturnType<typeof vi.fn> {
  const fetchMock = vi.fn(async () =>
    Promise.resolve(
      new Response(JSON.stringify({ id: 'email_abc' }), {
        status: 200,
        headers: { 'Content-Type': 'application/json' }
      })
    )
  )
  ;(globalThis as unknown as { fetch: typeof fetch }).fetch = fetchMock as unknown as typeof fetch
  return fetchMock
}

describe('Resend sendEmail — idempotency key', () => {
  let originalFetch: typeof fetch

  beforeEach(() => {
    originalFetch = globalThis.fetch
  })

  afterEach(() => {
    globalThis.fetch = originalFetch
  })

  it('omits the Idempotency-Key header when idempotencyKey is not provided', async () => {
    const fetchMock = mockResendOk()

    await sendEmail(credentials, baseParams)

    expect(fetchMock).toHaveBeenCalledOnce()
    const init = fetchMock.mock.calls[0][1] as RequestInit
    const headers = init.headers as Record<string, string>
    expect(headers['Idempotency-Key']).toBeUndefined()
    // Sanity check: required headers are still present
    expect(headers.Authorization).toBe('Bearer re_test_123')
    expect(headers['Content-Type']).toBe('application/json')
  })

  it('passes idempotencyKey through as the Idempotency-Key header', async () => {
    const fetchMock = mockResendOk()

    await sendEmail(credentials, { ...baseParams, idempotencyKey: 'wf-exec-001-step-send-approval' })

    const init = fetchMock.mock.calls[0][1] as RequestInit
    const headers = init.headers as Record<string, string>
    expect(headers['Idempotency-Key']).toBe('wf-exec-001-step-send-approval')
  })

  it('sends the same Idempotency-Key on caller-driven retries (regression: platform_internal retries must dedupe)', async () => {
    const fetchMock = mockResendOk()

    const params: SendEmailParams = { ...baseParams, idempotencyKey: 'stable-key-xyz' }

    // Simulate two calls with identical params (e.g. caller retries after a
    // platform_internal failure). Both must carry the same Idempotency-Key
    // so Resend collapses them into a single send.
    await sendEmail(credentials, params)
    await sendEmail(credentials, params)

    expect(fetchMock).toHaveBeenCalledTimes(2)

    const firstHeaders = (fetchMock.mock.calls[0][1] as RequestInit).headers as Record<string, string>
    const secondHeaders = (fetchMock.mock.calls[1][1] as RequestInit).headers as Record<string, string>
    expect(firstHeaders['Idempotency-Key']).toBe('stable-key-xyz')
    expect(secondHeaders['Idempotency-Key']).toBe('stable-key-xyz')
  })
})
