import { cleanup, render, screen } from '@testing-library/react';
import { afterEach, describe, expect, it, vi } from 'vitest';

import DashboardPage from '../../src/app/(app)/dashboard/page';

const { mockUseQuery } = vi.hoisted(() => ({
  mockUseQuery: vi.fn(),
}));

vi.mock('convex/react', () => ({
  useConvexAuth: () => ({ isAuthenticated: false }),
  useMutation: vi.fn(),
  useQuery: mockUseQuery,
}));

vi.mock('next/navigation', () => ({
  useParams: vi.fn(),
  useRouter: () => ({ push: vi.fn(), replace: vi.fn() }),
  useSearchParams: () => new URLSearchParams(),
}));

describe('dashboard loading vs empty state', () => {
  afterEach(() => {
    cleanup();
    mockUseQuery.mockReset();
  });

  it('shows skeletons while queries are loading (undefined)', () => {
    mockUseQuery.mockReturnValue(undefined);

    render(<DashboardPage />);

    expect(screen.getAllByTestId('list-skeleton').length).toBeGreaterThan(0);
    expect(screen.queryByText('No Spoons yet')).not.toBeInTheDocument();
  });

  it('shows empty states once loaded with no data ([])', () => {
    mockUseQuery.mockReturnValue([]);

    render(<DashboardPage />);

    expect(screen.queryByTestId('list-skeleton')).not.toBeInTheDocument();
    expect(screen.getByText('No Spoons yet')).toBeInTheDocument();
  });

  it('renders data once loaded with items', () => {
    mockUseQuery.mockImplementation((_query, args) => {
      // spoons list has an empty args object ({}); recent syncRuns/threads pass limits.
      if (args && 'limit' in args) return [];
      return [
        {
          _id: 'spoon-1',
          name: 'useSend',
          upstreamOwner: 'acme',
          upstreamRepo: 'app',
          status: 'active',
          syncCadence: 'daily',
          effectiveUpstreamAheadBy: 0,
          rawUpstreamAheadBy: 0,
          forkAheadBy: 0,
          ignoredUpstreamCount: 0,
        },
      ];
    });

    render(<DashboardPage />);

    expect(screen.getByText('useSend')).toBeInTheDocument();
    expect(screen.queryByTestId('list-skeleton')).not.toBeInTheDocument();
    expect(screen.queryByText('No Spoons yet')).not.toBeInTheDocument();
  });
});
