/**
 * Dashboard Component Tests
 */

import { render, screen } from '@testing-library/react';
import { Dashboard } from '@/components/dashboard/Dashboard';
import { useAuth } from '@/lib/auth/AuthContext';
import { useDashboard } from '@/lib/api/hooks/useDashboard';
import { useProjectEvents } from '@/lib/hooks/useProjectEvents';
import { useProjectEventsFromStore } from '@/lib/stores/eventStore';

// Mock dependencies
jest.mock('@/lib/auth/AuthContext', () => ({
  useAuth: jest.fn(),
}));

jest.mock('@/lib/api/hooks/useDashboard', () => ({
  useDashboard: jest.fn(),
}));

jest.mock('@/lib/hooks/useProjectEvents', () => ({
  useProjectEvents: jest.fn(),
}));

jest.mock('@/lib/stores/eventStore', () => ({
  useProjectEventsFromStore: jest.fn(),
}));

// Mock next-intl navigation
jest.mock('@/lib/i18n/routing', () => ({
  Link: ({ children, href }: { children: React.ReactNode; href: string }) => (
    <a href={href}>{children}</a>
  ),
}));

// Mock sonner
jest.mock('sonner', () => ({
  toast: {
    success: jest.fn(),
    info: jest.fn(),
    error: jest.fn(),
  },
}));

const mockUseAuth = useAuth as jest.MockedFunction<typeof useAuth>;
const mockUseDashboard = useDashboard as jest.MockedFunction<typeof useDashboard>;
const mockUseProjectEvents = useProjectEvents as jest.MockedFunction<typeof useProjectEvents>;
const mockUseProjectEventsFromStore = useProjectEventsFromStore as jest.MockedFunction<
  typeof useProjectEventsFromStore
>;

describe('Dashboard', () => {
  const mockUser = {
    id: '1',
    email: 'test@example.com',
    first_name: 'Test',
    is_active: true,
    is_superuser: false,
    created_at: '',
  };

  const mockDashboardData = {
    stats: {
      activeProjects: 3,
      runningAgents: 8,
      openIssues: 24,
      pendingApprovals: 2,
    },
    recentProjects: [
      {
        id: 'proj-1',
        name: 'Test Project',
        description: 'Test description',
        status: 'active' as const,
        autonomy_level: 'milestone' as const,
        created_at: '2025-01-01T00:00:00Z',
        owner_id: 'user-1',
        progress: 50,
        openIssues: 5,
        activeAgents: 2,
        lastActivity: '5 min ago',
      },
    ],
    pendingApprovals: [
      {
        id: 'approval-1',
        type: 'sprint_boundary' as const,
        title: 'Sprint Review',
        description: 'Review sprint',
        projectId: 'proj-1',
        projectName: 'Test Project',
        requestedBy: 'Agent',
        requestedAt: new Date().toISOString(),
        priority: 'high' as const,
      },
    ],
  };

  beforeEach(() => {
    jest.clearAllMocks();

    mockUseAuth.mockReturnValue({
      user: mockUser,
      isAuthenticated: true,
      isLoading: false,
      error: null,
      login: jest.fn(),
      logout: jest.fn(),
      clearError: jest.fn(),
      checkAuth: jest.fn(),
    });

    mockUseDashboard.mockReturnValue({
      data: mockDashboardData,
      isLoading: false,
      error: null,
      isError: false,
      isPending: false,
      isSuccess: true,
      status: 'success',
    } as ReturnType<typeof useDashboard>);

    mockUseProjectEvents.mockReturnValue({
      connectionState: 'connected',
      events: [],
      isConnected: true,
      error: null,
      retryCount: 0,
      reconnect: jest.fn(),
      disconnect: jest.fn(),
      clearEvents: jest.fn(),
    });

    mockUseProjectEventsFromStore.mockReturnValue([]);
  });

  it('renders welcome header', () => {
    render(<Dashboard />);

    // User first name appears in welcome message
    expect(screen.getByRole('heading', { level: 1 })).toBeInTheDocument();
  });

  it('renders quick stats', () => {
    render(<Dashboard />);

    expect(screen.getByText('Active Projects')).toBeInTheDocument();
    expect(screen.getByText('Running Agents')).toBeInTheDocument();
    expect(screen.getByText('Open Issues')).toBeInTheDocument();
    // "Pending Approvals" appears in both stats and approvals section
    const pendingApprovalsTexts = screen.getAllByText('Pending Approvals');
    expect(pendingApprovalsTexts.length).toBeGreaterThan(0);
  });

  it('renders recent projects section', () => {
    render(<Dashboard />);

    expect(screen.getByText('Recent Projects')).toBeInTheDocument();
    // Use getAllByText since project name appears in multiple places
    const projectNames = screen.getAllByText('Test Project');
    expect(projectNames.length).toBeGreaterThan(0);
  });

  it('renders pending approvals section when approvals exist', () => {
    render(<Dashboard />);

    // Check for pending approvals header
    const approvalHeaders = screen.getAllByText('Pending Approvals');
    expect(approvalHeaders.length).toBeGreaterThan(0);
  });

  it('shows empty state when no projects', () => {
    mockUseDashboard.mockReturnValue({
      data: { ...mockDashboardData, recentProjects: [] },
      isLoading: false,
      error: null,
      isError: false,
      isPending: false,
      isSuccess: true,
      status: 'success',
    } as unknown as ReturnType<typeof useDashboard>);

    render(<Dashboard />);

    expect(screen.getByText(/Welcome to Syndarix/)).toBeInTheDocument();
    expect(screen.getByText(/Create Your First Project/)).toBeInTheDocument();
  });

  it('shows loading state', () => {
    mockUseDashboard.mockReturnValue({
      data: undefined,
      isLoading: true,
      error: null,
      isError: false,
      isPending: true,
      isSuccess: false,
      status: 'pending',
    } as ReturnType<typeof useDashboard>);

    render(<Dashboard />);

    // Should show skeleton loading states
    expect(screen.getByText('Recent Projects')).toBeInTheDocument();
  });

  it('applies custom className', () => {
    const { container } = render(<Dashboard className="custom-class" />);

    expect(container.firstChild).toHaveClass('custom-class');
  });
});
