import { render, screen, waitFor, fireEvent } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { vi, describe, it, expect, beforeEach } from 'vitest';
import { useRouter } from 'next/navigation';
import { CartClient } from '../cart-client';

vi.mock('next/navigation', () => ({
  useRouter: vi.fn(),
}));

const getMock = vi.fn();
const removeMock = vi.fn();
vi.mock('@/lib/api', () => ({
  api: {
    cart: {
      get: (...a: unknown[]) => getMock(...a),
      removeItem: (...a: unknown[]) => removeMock(...a),
    },
  },
}));

function wrap(node: React.ReactNode) {
  const qc = new QueryClient({ defaultOptions: { queries: { retry: false } } });
  return <QueryClientProvider client={qc}>{node}</QueryClientProvider>;
}

const fullCart = {
  data: {
    item_count: 2,
    subtotal: 5000,
    shipping_total: 800,
    total: 5800,
    stores: [
      {
        store: { id: 's1', name: 'Revive', logo_image: null },
        subtotal: 5000,
        shipping: 800,
        free_shipping_threshold: 10000,
        items: [
          {
            id: 'ci1',
            added_at: '2026-05-01T00:00:00Z',
            item: {
              id: 'item-1',
              title: 'Vintage Tee',
              price: 2500,
              image_url: null,
              condition: 'EUC',
              is_available: true,
            },
          },
          {
            id: 'ci2',
            added_at: '2026-05-01T00:00:00Z',
            item: {
              id: 'item-2',
              title: 'Denim Jacket',
              price: 2500,
              image_url: null,
              condition: 'GUC',
              is_available: true,
            },
          },
        ],
      },
    ],
  },
};

describe('CartClient', () => {
  const push = vi.fn();

  beforeEach(() => {
    push.mockClear();
    getMock.mockReset();
    removeMock.mockReset();
    vi.mocked(useRouter).mockReturnValue({
      push,
      back: vi.fn(),
      forward: vi.fn(),
      refresh: vi.fn(),
      replace: vi.fn(),
      prefetch: vi.fn(),
    } as unknown as ReturnType<typeof useRouter>);
  });

  it('renders empty state with browse CTA when cart is empty', async () => {
    getMock.mockResolvedValue({
      data: { item_count: 0, subtotal: 0, shipping_total: 0, total: 0, stores: [] },
    });
    render(wrap(<CartClient />));
    await waitFor(() =>
      expect(screen.getByText('Your cart is empty')).toBeInTheDocument(),
    );
    expect(screen.getByRole('link', { name: /Browse Items/ })).toHaveAttribute(
      'href',
      '/items',
    );
  });

  it('renders store group, items, and totals', async () => {
    getMock.mockResolvedValue(fullCart);
    render(wrap(<CartClient />));
    await waitFor(() => expect(screen.getByText('Revive')).toBeInTheDocument());
    expect(screen.getByText('Vintage Tee')).toBeInTheDocument();
    expect(screen.getByText('Denim Jacket')).toBeInTheDocument();
    expect(screen.getByText('(2 items)')).toBeInTheDocument();
    expect(screen.getByText('$58.00')).toBeInTheDocument();
  });

  it('removing an item calls api.cart.removeItem with the item id', async () => {
    getMock.mockResolvedValue(fullCart);
    removeMock.mockResolvedValue(undefined);
    render(wrap(<CartClient />));
    await waitFor(() => expect(screen.getByText('Vintage Tee')).toBeInTheDocument());
    const removeButtons = screen.getAllByRole('button', { name: /Remove/ });
    fireEvent.click(removeButtons[0]);
    await waitFor(() => expect(removeMock).toHaveBeenCalledWith('item-1'));
  });

  it('proceed to checkout navigates to /checkout', async () => {
    getMock.mockResolvedValue(fullCart);
    render(wrap(<CartClient />));
    await waitFor(() =>
      expect(
        screen.getByRole('button', { name: /Proceed to Checkout/ }),
      ).toBeInTheDocument(),
    );
    fireEvent.click(screen.getByRole('button', { name: /Proceed to Checkout/ }));
    expect(push).toHaveBeenCalledWith('/checkout');
  });
});
