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

import { requireAuth } from '../../../server/utils/auth.js'
import { getHelcimCustomer, listHelcimCustomerTransactions } from '../../../server/utils/helcim.js'
import paymentHistoryHandler from '../../../server/api/helcim/payment-history.get.js'
import { createMockEvent } from '../helpers/createMockEvent.js'

vi.mock('../../../server/utils/auth.js', () => ({ requireAuth: vi.fn() }))
vi.mock('../../../server/utils/helcim.js', () => ({
  getHelcimCustomer: vi.fn(),
  listHelcimCustomerTransactions: vi.fn()
}))

describe('helcim payment-history endpoint', () => {
  beforeEach(() => {
    vi.clearAllMocks()
  })

  it('returns 401 when unauthenticated', async () => {
    requireAuth.mockRejectedValue(
      createError({ statusCode: 401, statusMessage: 'Unauthorized' })
    )

    const event = createMockEvent({
      method: 'GET',
      path: '/api/helcim/payment-history'
    })

    await expect(paymentHistoryHandler(event)).rejects.toMatchObject({
      statusCode: 401
    })

    expect(getHelcimCustomer).not.toHaveBeenCalled()
    expect(listHelcimCustomerTransactions).not.toHaveBeenCalled()
  })

  it('returns empty transactions when member has no helcimCustomerId', async () => {
    requireAuth.mockResolvedValue({ helcimCustomerId: null })

    const event = createMockEvent({
      method: 'GET',
      path: '/api/helcim/payment-history'
    })

    const result = await paymentHistoryHandler(event)

    expect(result).toEqual({ transactions: [] })
    expect(getHelcimCustomer).not.toHaveBeenCalled()
    expect(listHelcimCustomerTransactions).not.toHaveBeenCalled()
  })

  it('returns normalized transactions for authenticated member with helcimCustomerId', async () => {
    requireAuth.mockResolvedValue({ helcimCustomerId: 9876 })
    getHelcimCustomer.mockResolvedValue({ id: 9876, customerCode: 'CST1044' })

    const transactions = [
      { id: 't1', date: '2026-04-18T00:00:00Z', amount: 15, status: 'paid', currency: 'CAD' },
      { id: 't2', date: '2026-03-18T00:00:00Z', amount: 15, status: 'paid', currency: 'CAD' }
    ]
    listHelcimCustomerTransactions.mockResolvedValue(transactions)

    const event = createMockEvent({
      method: 'GET',
      path: '/api/helcim/payment-history'
    })

    const result = await paymentHistoryHandler(event)

    expect(result).toEqual({ transactions })
    expect(getHelcimCustomer).toHaveBeenCalledWith(9876)
    expect(listHelcimCustomerTransactions).toHaveBeenCalledWith('CST1044')
  })

  it('returns { transactions: [], error: "unavailable" } when listHelcimCustomerTransactions throws', async () => {
    requireAuth.mockResolvedValue({ helcimCustomerId: 9876 })
    getHelcimCustomer.mockResolvedValue({ id: 9876, customerCode: 'CST1044' })
    listHelcimCustomerTransactions.mockRejectedValue(new Error('Transaction lookup failed'))

    const event = createMockEvent({
      method: 'GET',
      path: '/api/helcim/payment-history'
    })

    const result = await paymentHistoryHandler(event)

    expect(result).toEqual({ transactions: [], error: 'unavailable' })
  })

  it('returns { transactions: [], error: "unavailable" } when getHelcimCustomer throws', async () => {
    requireAuth.mockResolvedValue({ helcimCustomerId: 9876 })
    getHelcimCustomer.mockRejectedValue(new Error('Customer lookup failed'))

    const event = createMockEvent({
      method: 'GET',
      path: '/api/helcim/payment-history'
    })

    const result = await paymentHistoryHandler(event)

    expect(result).toEqual({ transactions: [], error: 'unavailable' })
    expect(listHelcimCustomerTransactions).not.toHaveBeenCalled()
  })

  it('returns unavailable when customerCode is missing from Helcim response', async () => {
    requireAuth.mockResolvedValue({ helcimCustomerId: 9876 })
    getHelcimCustomer.mockResolvedValue({ id: 9876 })

    const event = createMockEvent({
      method: 'GET',
      path: '/api/helcim/payment-history'
    })

    const result = await paymentHistoryHandler(event)

    expect(result).toEqual({ transactions: [], error: 'unavailable' })
    expect(listHelcimCustomerTransactions).not.toHaveBeenCalled()
  })
})
