import { describe, it, expect, vi } from 'vitest'
import { render, screen, waitFor, fireEvent } from '@testing-library/react'
import { NotificationList } from './NotificationList.js'
import type { NotificationClient } from './client.js'
import type { NotificationRecord } from '@platform-modules/notifications/inbox'

function rec(id: string): NotificationRecord {
  return { id, userId: 'me', title: `title-${id}`, createdAt: '2026-01-01T00:00:00.000Z', readAt: null }
}

describe('NotificationList', () => {
  it('renders item titles as accessible content', async () => {
    const client: NotificationClient = { list: vi.fn(async () => ({ items: [rec('a')] })), unreadCount: vi.fn(async () => 1), markRead: vi.fn(async () => {}) }
    render(<NotificationList client={client} />)
    await waitFor(() => expect(screen.getByText('title-a')).toBeTruthy())
  })

  it('shows emptyState when no items', async () => {
    const client: NotificationClient = { list: vi.fn(async () => ({ items: [] })), unreadCount: vi.fn(async () => 0), markRead: vi.fn(async () => {}) }
    render(<NotificationList client={client} emptyState={<div>nothing here</div>} />)
    await waitFor(() => expect(screen.getByText('nothing here')).toBeTruthy())
  })

  it('shows a "Load more" affordance only when a next cursor exists, and loadMore appends', async () => {
    const list = vi.fn()
      .mockResolvedValueOnce({ items: [rec('a')], nextCursor: 'c1' })
      .mockResolvedValueOnce({ items: [rec('b')] })
    const client: NotificationClient = { list, unreadCount: vi.fn(async () => 1), markRead: vi.fn(async () => {}) }
    render(<NotificationList client={client} />)
    const more = await screen.findByRole('button', { name: 'Load more' })
    fireEvent.click(more)
    await waitFor(() => expect(screen.getByText('title-b')).toBeTruthy())
    // last page had no cursor → affordance gone
    expect(screen.queryByRole('button', { name: 'Load more' })).toBeNull()
  })

  it('renders no "Load more" affordance when the first page has no cursor', async () => {
    const client: NotificationClient = { list: vi.fn(async () => ({ items: [rec('a')] })), unreadCount: vi.fn(async () => 1), markRead: vi.fn(async () => {}) }
    render(<NotificationList client={client} />)
    await waitFor(() => expect(screen.getByText('title-a')).toBeTruthy())
    expect(screen.queryByRole('button', { name: 'Load more' })).toBeNull()
  })

  it('has a polite (not assertive) live region', async () => {
    const client: NotificationClient = { list: vi.fn(async () => ({ items: [rec('a')] })), unreadCount: vi.fn(async () => 1), markRead: vi.fn(async () => {}) }
    const { container } = render(<NotificationList client={client} />)
    await waitFor(() => expect(screen.getByText('title-a')).toBeTruthy())
    const live = container.querySelector('[aria-live]')
    expect(live?.getAttribute('aria-live')).toBe('polite')
  })
})
