import { describe, expect, it, vi } from 'vitest'
import { MailProviderError } from '@platform-modules/mail'
import { createEmailChannel } from './email.js'
import type { RenderedMessage } from './index.js'

describe('createEmailChannel', () => {
  it('calls fake mail.send with the mapped MailMessage', async () => {
    /** @type {import('@platform-modules/mail').MailMessage | undefined} */
    let captured
    const mail = {
      send: vi.fn(async (msg) => {
        captured = structuredClone(msg)
        return { id: 'mail-1', provider: 'fake' }
      }),
    }

    const channel = createEmailChannel(mail)
    const rendered: RenderedMessage = {
      subject: 'Hello Dana',
      body: 'Your order shipped',
      html: '<p>Your order shipped</p>',
    }
    const result = await channel.send(rendered, {
      to: 'user@example.com',
      from: 'noreply@example.com',
      idempotencyKey: 'evt-1:email',
    })

    expect(result).toEqual({ ok: true, id: 'mail-1' })
    expect(captured).toEqual({
      from: 'noreply@example.com',
      to: 'user@example.com',
      subject: 'Hello Dana',
      text: 'Your order shipped',
      html: '<p>Your order shipped</p>',
      idempotencyKey: 'evt-1:email',
    })
  })

  it('surfaces mail failure as channel Result (retryable)', async () => {
    const mail = {
      send: vi.fn(async () => {
        throw new MailProviderError('provider 503', 'fake', true)
      }),
    }

    const channel = createEmailChannel(mail)
    const result = await channel.send(
      { body: 'hi' },
      { to: 'u@example.com', from: 'noreply@example.com' },
    )

    expect(result).toEqual({
      ok: false,
      error: {
        message: 'provider 503',
        retryable: true,
        code: 'MailProviderError',
      },
    })
  })
})
