import { describe, expect, it, vi } from 'vitest'
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

import { TestPacksManager } from '@/components/TestPacksManager'

vi.mock('@/api/packs', () => {
  return {
    packsApi: {
      getPacks: vi.fn(),
    },
  }
})

import { packsApi } from '@/api/packs'

function renderWithQuery(ui: React.ReactElement) {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: {
        retry: false,
      },
    },
  })

  return render(
    <QueryClientProvider client={queryClient}>{ui}</QueryClientProvider>,
  )
}

describe('TestPacksManager', () => {
  it('loads packs and emits add/remove IDs on toggle', async () => {
    const onPacksChange = vi.fn()

    vi.mocked(packsApi.getPacks).mockResolvedValue({
      items: [
        {
          id: 'pack-1',
          title: 'Pack One',
          cards: 10,
          enabled: true,
          order: 0,
        },
        {
          id: 'pack-2',
          title: 'Pack Two',
          cards: 5,
          enabled: true,
          order: 1,
        },
      ],
      total: 2,
      page: 1,
      limit: 100,
      totalPages: 1,
    })

    renderWithQuery(
      <TestPacksManager
        currentPackIds={['pack-1']}
        onPacksChange={onPacksChange}
      />,
    )

    await waitFor(() => {
      expect(screen.getByText('Pack One')).toBeInTheDocument()
      expect(screen.getByText('Pack Two')).toBeInTheDocument()
    })

    // Select pack-2 -> should be add
    fireEvent.click(screen.getByText('Pack Two'))

    await waitFor(() => {
      expect(onPacksChange).toHaveBeenCalled()
    })

    const lastCall1 = onPacksChange.mock.calls.at(-1)
    expect(lastCall1?.[0]).toEqual(['pack-2'])
    expect(lastCall1?.[1]).toEqual([])

    // Deselect pack-1 (already linked) -> should be remove
    fireEvent.click(screen.getByText('Pack One'))

    await waitFor(() => {
      const lastCall2 = onPacksChange.mock.calls.at(-1)
      expect(lastCall2?.[1]).toEqual(['pack-1'])
    })
  })
})
