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

vi.mock('server-only', () => ({}))

const { mockSendPushToUser } = vi.hoisted(() => ({
  mockSendPushToUser: vi.fn(),
}))

vi.mock('@/lib/push-server', () => ({
  sendPushToUser: mockSendPushToUser,
  enabled: true,
}))

vi.hoisted(() => {
  process.env.INTERNAL_PUSH_SECRET = 'a-valid-secret-that-is-at-least-32-chars'
})

import { POST } from '@/app/api/internal/push/send/route'

const VALID_BODY = {
  userId: 'user-1',
  payload: { title: 'Hello', body: 'World', url: '/dashboard' },
}
const SECRET = 'a-valid-secret-that-is-at-least-32-chars'

function makeRequest(body: unknown, bearer?: string) {
  return new Request('http://localhost/api/internal/push/send', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      ...(bearer !== undefined ? { Authorization: bearer } : {}),
    },
    body: JSON.stringify(body),
  })
}

beforeEach(() => {
  vi.clearAllMocks()
  mockSendPushToUser.mockResolvedValue(undefined)
})

describe('POST /api/internal/push/send', () => {
  it('returns 401 without authorization header', async () => {
    const res = await POST(makeRequest(VALID_BODY))
    expect(res.status).toBe(401)
    expect(mockSendPushToUser).not.toHaveBeenCalled()
  })

  it('returns 401 with wrong bearer secret', async () => {
    const res = await POST(makeRequest(VALID_BODY, 'Bearer wrong-secret'))
    expect(res.status).toBe(401)
  })

  it('returns 422 with invalid body', async () => {
    const res = await POST(makeRequest({ userId: '', payload: {} }, `Bearer ${SECRET}`))
    expect(res.status).toBe(422)
    expect(mockSendPushToUser).not.toHaveBeenCalled()
  })

  it('returns 204 and calls sendPushToUser on success', async () => {
    const res = await POST(makeRequest(VALID_BODY, `Bearer ${SECRET}`))
    expect(res.status).toBe(204)
    expect(mockSendPushToUser).toHaveBeenCalledWith('user-1', VALID_BODY.payload)
  })

  it('returns 400 for invalid JSON', async () => {
    const req = new Request('http://localhost/api/internal/push/send', {
      method: 'POST',
      headers: { Authorization: `Bearer ${SECRET}`, 'Content-Type': 'application/json' },
      body: 'not-json',
    })
    const res = await POST(req)
    expect(res.status).toBe(400)
  })
})
