import { it, expect, vi, beforeEach } from 'vitest'

const sendEmailMock = vi.fn()

vi.mock('postmark', () => ({
  ServerClient: vi.fn().mockImplementation(() => ({
    sendEmail: sendEmailMock,
  })),
}))

import { makePostmarkAdapter } from './postmark.js'
import { MailProviderError } from './index.js'

beforeEach(() => {
  sendEmailMock.mockReset()
})

it('maps MailMessage to Postmark sendEmail fields', async () => {
  sendEmailMock.mockResolvedValue({ MessageID: 'pm-1', ErrorCode: 0 })

  const adapter = makePostmarkAdapter({ serverToken: 'token' })
  await adapter.send({
    from: 'from@example.com',
    to: ['a@example.com', 'b@example.com'],
    replyTo: 'reply@example.com',
    subject: 'Subject',
    html: '<p>Hi</p>',
    text: 'Hi',
  })

  expect(sendEmailMock).toHaveBeenCalledWith({
    From: 'from@example.com',
    To: 'a@example.com,b@example.com',
    Cc: undefined,
    Bcc: undefined,
    Subject: 'Subject',
    HtmlBody: '<p>Hi</p>',
    TextBody: 'Hi',
    ReplyTo: 'reply@example.com',
    Headers: undefined,
  })
})

it('maps provider errors to MailProviderError', async () => {
  const err = Object.assign(new Error('inactive'), { statusCode: 422 })
  sendEmailMock.mockRejectedValue(err)

  const adapter = makePostmarkAdapter({ serverToken: 'token' })
  await expect(
    adapter.send({
      from: 'from@example.com',
      to: 'to@example.com',
      subject: 'Subject',
      text: 'Hi',
    }),
  ).rejects.toBeInstanceOf(MailProviderError)
})

it('returns MailResult on success', async () => {
  sendEmailMock.mockResolvedValue({ MessageID: 'pm-ok', ErrorCode: 0 })

  const adapter = makePostmarkAdapter({ serverToken: 'token' })
  const result = await adapter.send({
    from: 'from@example.com',
    to: 'to@example.com',
    subject: 'Subject',
    text: 'Hi',
  })

  expect(result).toEqual({ id: 'pm-ok', provider: 'postmark' })
})
