import { describe, it, expect, vi } from 'vitest'
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import { SubmissionsTable } from './SubmissionsTable.js'
import type { SubmissionClient, StoredSubmission } from './seams.js'

function sub(id: string, spam = false): StoredSubmission {
  return { id, formId: 'f1', data: { email: `${id}@x.io` }, createdAt: '2026-01-01T00:00:00.000Z', spam }
}

describe('SubmissionsTable', () => {
  it('renders a row per submission', async () => {
    const client: SubmissionClient = { list: vi.fn(async () => ({ items: [sub('a'), sub('b')] })), get: vi.fn(async () => null), delete: vi.fn(async () => {}) }
    render(<SubmissionsTable client={client} formId="f1" />)
    await waitFor(() => expect(screen.getAllByRole('row').length).toBeGreaterThanOrEqual(2))
  })
  it('labels spam rows textually (not color-only)', async () => {
    const client: SubmissionClient = { list: vi.fn(async () => ({ items: [sub('a', true)] })), get: vi.fn(async () => null), delete: vi.fn(async () => {}) }
    render(<SubmissionsTable client={client} formId="f1" />)
    await waitFor(() => expect(screen.getByText(/spam/i)).toBeTruthy())
  })
  it('toggling the spam filter re-queries with includeSpam', async () => {
    const list = vi.fn(async () => ({ items: [sub('a')] }))
    const client: SubmissionClient = { list, get: vi.fn(async () => null), delete: vi.fn(async () => {}) }
    render(<SubmissionsTable client={client} formId="f1" />)
    await waitFor(() => expect(list).toHaveBeenCalled())
    fireEvent.click(screen.getByLabelText(/show spam|include spam/i))
    await waitFor(() => expect(list).toHaveBeenCalledWith('f1', expect.objectContaining({ includeSpam: true })))
  })
  it('renders dates through a host-supplied formatDate (never a raw ISO string)', async () => {
    const client: SubmissionClient = { list: vi.fn(async () => ({ items: [sub('a')] })), get: vi.fn(async () => null), delete: vi.fn(async () => {}) }
    render(<SubmissionsTable client={client} formId="f1" formatDate={() => '1 January 2026'} />)
    await waitFor(() => expect(screen.getByText('1 January 2026')).toBeTruthy())
    expect(screen.queryByText('2026-01-01T00:00:00.000Z')).toBeNull()
  })
  it('shows "Load more" only with a next cursor and calls loadMore', async () => {
    const list = vi.fn().mockResolvedValueOnce({ items: [sub('a')], nextCursor: 'c1' }).mockResolvedValueOnce({ items: [sub('b')] })
    const client: SubmissionClient = { list, get: vi.fn(async () => null), delete: vi.fn(async () => {}) }
    render(<SubmissionsTable client={client} formId="f1" />)
    const more = await screen.findByRole('button', { name: /load more/i })
    fireEvent.click(more)
    await waitFor(() => expect(screen.queryByRole('button', { name: /load more/i })).toBeNull())
  })
})
