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 NotificationsPage from '../notifications/page';

const listMock = vi.fn();
const updateMock = vi.fn();
vi.mock('@/lib/api', () => ({
  api: {
    notifications: {
      listPreferences: (...a: unknown[]) => listMock(...a),
      updatePreferences: (...a: unknown[]) => updateMock(...a),
    },
  },
}));

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

describe('NotificationsPage', () => {
  beforeEach(() => {
    listMock.mockReset();
    updateMock.mockReset();
    listMock.mockResolvedValue({
      data: [
        { channel: 'email', category: 'orders', enabled: true, is_transactional: true },
        { channel: 'email', category: 'shipping', enabled: true, is_transactional: true },
        { channel: 'email', category: 'payouts', enabled: true, is_transactional: false },
        { channel: 'email', category: 'account', enabled: true, is_transactional: false },
        { channel: 'email', category: 'promotions', enabled: false, is_transactional: false },
        { channel: 'email', category: 'price_drops', enabled: false, is_transactional: false },
      ],
    });
  });

  it('locks transactional categories and allows toggling non-transactional ones', async () => {
    updateMock.mockResolvedValue({ data: [] });
    render(wrap(<NotificationsPage />));
    await waitFor(() => expect(screen.getByText('Orders')).toBeInTheDocument());

    const boxes = screen.getAllByRole('checkbox');
    // Row order matches ROWS constant: orders, shipping, payouts, account, promotions, price_drops
    const ordersBox = boxes[0];
    expect(ordersBox).toBeDisabled();

    const shippingBox = boxes[1];
    expect(shippingBox).toBeDisabled();

    const promotionsBox = boxes[4];
    expect(promotionsBox).not.toBeDisabled();
    fireEvent.click(promotionsBox);
    await waitFor(() =>
      expect(updateMock).toHaveBeenCalledWith({
        preferences: [{ channel: 'email', category: 'promotions', enabled: true }],
      }),
    );
  });
});
