import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { render, screen, fireEvent } from '@testing-library/react'
import { MemoryRouter } from 'react-router-dom'
import { describe, it, expect, vi, beforeEach } from 'vitest'
import * as api from '@/entities/cart/api/cart-api'
import * as notifications from '@/shared/model/notification'
import { ToggleCartIcon } from '../ToggleCartIcon'

vi.mock('@/entities/cart/api/cart-api', () => ({
  addToCart: vi.fn(() => Promise.resolve()),
  fetchMyCart: vi.fn(() => Promise.resolve({ items: [] })),
  removeCartItem: vi.fn(() => Promise.resolve()),
}))

vi.mock('effector-react', async () => {
  const actual = await vi.importActual('effector-react')
  return { ...actual, useUnit: () => ({ id: '1', email: 'test@test.com' }) }
})

describe('ToggleCartIcon', () => {
  const qc = new QueryClient({ defaultOptions: { queries: { retry: false } } })

  beforeEach(() => {
    vi.clearAllMocks()
    qc.clear()
  })

  it('calls addNotification after successful add', async () => {
    const spy = vi.spyOn(notifications, 'addNotification')
    render(
      <QueryClientProvider client={qc}>
        <MemoryRouter>
          <ToggleCartIcon productId="test-product" />
        </MemoryRouter>
      </QueryClientProvider>,
    )

    fireEvent.click(screen.getByRole('button', { name: /в корзину/i }))

    await vi.waitFor(() => {
      expect(spy).toHaveBeenCalledWith({
        type: 'success',
        message: 'Товар добавлен в корзину',
        actionLabel: 'Перейти в корзину',
        actionPath: '/cart',
      })
    })
  })

  it('does not call addNotification on remove', async () => {
    vi.mocked(api.fetchMyCart).mockResolvedValueOnce({
      items: [{ id: 'cart-1', qty: 1, product: { id: 'test-product' } as never }],
    })
    const spy = vi.spyOn(notifications, 'addNotification')

    render(
      <QueryClientProvider client={qc}>
        <MemoryRouter>
          <ToggleCartIcon productId="test-product" />
        </MemoryRouter>
      </QueryClientProvider>,
    )

    await vi.waitFor(() => {
      expect(screen.getByRole('button', { name: /убрать из корзины/i })).toBeInTheDocument()
    })

    fireEvent.click(screen.getByRole('button', { name: /убрать из корзины/i }))

    await vi.waitFor(() => {
      expect(spy).not.toHaveBeenCalled()
    })
  })
})
