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

const getMock = vi.fn()
const postMock = vi.fn()
const putMock = vi.fn()
const delMock = vi.fn()

vi.mock('@/lib/http/client', () => ({
  get: getMock,
  post: postMock,
  put: putMock,
  del: delMock,
}))

describe('webhooks service', () => {
  beforeEach(() => {
    getMock.mockReset()
    postMock.mockReset()
    putMock.mockReset()
    delMock.mockReset()
  })

  it('normalizes mixed raw event payloads from the API', async () => {
    getMock.mockResolvedValue({
      data: [
        {
          id: 1,
          name: 'String Events',
          url: 'https://example.com/string',
          events: '["user.registered"]',
          status: 1,
          max_retries: 3,
          timeout_sec: 10,
          created_by: 1,
          created_at: '2026-03-27 20:00:00',
          updated_at: '2026-03-27 20:00:00',
        },
        {
          id: 2,
          name: 'Array Events',
          url: 'https://example.com/array',
          events: ['user.login'],
          status: 0,
          max_retries: 3,
          timeout_sec: 10,
          created_by: 2,
          created_at: '2026-03-27 20:05:00',
          updated_at: '2026-03-27 20:05:00',
        },
        {
          id: 3,
          name: 'Invalid Events',
          url: 'https://example.com/invalid',
          events: 'not-json',
          status: 1,
          max_retries: 3,
          timeout_sec: 10,
          created_by: 3,
          created_at: '2026-03-27 20:10:00',
          updated_at: '2026-03-27 20:10:00',
        },
      ],
      total: 3,
      page: 1,
      page_size: 20,
    })

    const { listWebhooks } = await import('./webhooks')
    const result = await listWebhooks({ keyword: 'ignored' })

    expect(getMock).toHaveBeenCalledWith('/webhooks', { keyword: 'ignored' })
    expect(result.data[0].events).toEqual(['user.registered'])
    expect(result.data[1].events).toEqual(['user.login'])
    expect(result.data[2].events).toEqual([])
  })

  it('sends create, update, delete, and delivery requests through the HTTP client', async () => {
    postMock.mockResolvedValue({
      id: 1,
      name: 'Created Hook',
      url: 'https://example.com/created',
      events: '["user.updated"]',
      status: 1,
      max_retries: 3,
      timeout_sec: 10,
      created_by: 1,
      created_at: '2026-03-27 20:15:00',
      updated_at: '2026-03-27 20:15:00',
    })
    getMock.mockResolvedValue([])

    const {
      createWebhook,
      updateWebhook,
      deleteWebhook,
      updateWebhookStatus,
      getWebhookDeliveries,
    } = await import('./webhooks')

    const created = await createWebhook({
      name: 'Created Hook',
      url: 'https://example.com/created',
      secret: 'secret-demo',
      events: ['user.updated'],
    })

    expect(postMock).toHaveBeenCalledWith('/webhooks', {
      name: 'Created Hook',
      url: 'https://example.com/created',
      secret: 'secret-demo',
      events: ['user.updated'],
    })
    expect(created.events).toEqual(['user.updated'])

    await updateWebhook(9, { name: 'Updated Hook' })
    expect(putMock).toHaveBeenCalledWith('/webhooks/9', { name: 'Updated Hook' })

    await updateWebhookStatus(9, 0)
    expect(putMock).toHaveBeenCalledWith('/webhooks/9', { status: 0 })

    await deleteWebhook(9)
    expect(delMock).toHaveBeenCalledWith('/webhooks/9')

    await getWebhookDeliveries(9, { limit: 20 })
    expect(getMock).toHaveBeenCalledWith('/webhooks/9/deliveries', { limit: 20 })
  })
})
