/**
 * Tests for AppLayout and related components
 * Verifies layout structure, responsive behavior, and component integration
 */

import { render, screen } from '@testing-library/react';
import { AppLayout, PageContainer, PageHeader } from '@/components/layout/AppLayout';
import { useAuth } from '@/lib/auth/AuthContext';
import { useLogout } from '@/lib/api/hooks/useAuth';
import { mockUsePathname } from 'next-intl/navigation';
import type { User } from '@/lib/stores/authStore';

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

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

jest.mock('@/components/theme', () => ({
  ThemeToggle: () => <div data-testid="theme-toggle">Theme Toggle</div>,
}));

jest.mock('@/components/i18n', () => ({
  LocaleSwitcher: () => <div data-testid="locale-switcher">Locale Switcher</div>,
}));

// Helper to create mock user
function createMockUser(overrides: Partial<User> = {}): User {
  return {
    id: 'user-123',
    email: 'test@example.com',
    first_name: 'Test',
    last_name: 'User',
    phone_number: null,
    is_active: true,
    is_superuser: false,
    created_at: new Date().toISOString(),
    updated_at: null,
    ...overrides,
  };
}

describe('AppLayout', () => {
  beforeEach(() => {
    jest.clearAllMocks();
    mockUsePathname.mockReturnValue('/projects');

    (useAuth as unknown as jest.Mock).mockReturnValue({
      user: createMockUser(),
    });

    (useLogout as jest.Mock).mockReturnValue({
      mutate: jest.fn(),
      isPending: false,
    });
  });

  describe('Rendering', () => {
    it('renders layout container', () => {
      render(
        <AppLayout>
          <div>Content</div>
        </AppLayout>
      );

      expect(screen.getByTestId('app-layout')).toBeInTheDocument();
    });

    it('renders children', () => {
      render(
        <AppLayout>
          <div data-testid="test-content">Test Content</div>
        </AppLayout>
      );

      expect(screen.getByTestId('test-content')).toBeInTheDocument();
    });

    it('renders header', () => {
      render(
        <AppLayout>
          <div>Content</div>
        </AppLayout>
      );

      expect(screen.getByTestId('app-header')).toBeInTheDocument();
    });

    it('renders sidebar', () => {
      render(
        <AppLayout>
          <div>Content</div>
        </AppLayout>
      );

      expect(screen.getByTestId('sidebar')).toBeInTheDocument();
    });

    it('renders breadcrumbs', () => {
      render(
        <AppLayout>
          <div>Content</div>
        </AppLayout>
      );

      expect(screen.getByTestId('breadcrumbs')).toBeInTheDocument();
    });

    it('renders main content area', () => {
      render(
        <AppLayout>
          <div>Content</div>
        </AppLayout>
      );

      const main = screen.getByRole('main');
      expect(main).toBeInTheDocument();
      expect(main).toHaveAttribute('id', 'main-content');
    });
  });

  describe('Configuration Options', () => {
    it('hides sidebar when hideSidebar is true', () => {
      render(
        <AppLayout hideSidebar>
          <div>Content</div>
        </AppLayout>
      );

      expect(screen.queryByTestId('sidebar')).not.toBeInTheDocument();
    });

    it('hides breadcrumbs when hideBreadcrumbs is true', () => {
      render(
        <AppLayout hideBreadcrumbs>
          <div>Content</div>
        </AppLayout>
      );

      expect(screen.queryByTestId('breadcrumbs')).not.toBeInTheDocument();
    });

    it('passes custom breadcrumbs to AppBreadcrumbs', () => {
      const customBreadcrumbs = [
        { label: 'Custom', href: '/custom', current: true },
      ];

      render(
        <AppLayout breadcrumbs={customBreadcrumbs}>
          <div>Content</div>
        </AppLayout>
      );

      expect(screen.getByTestId('breadcrumb-custom')).toBeInTheDocument();
    });

    it('passes project slug to sidebar', () => {
      const currentProject = { id: '1', slug: 'test-project', name: 'Test' };

      render(
        <AppLayout currentProject={currentProject}>
          <div>Content</div>
        </AppLayout>
      );

      // Sidebar should show project-specific navigation
      expect(screen.getByTestId('nav-dashboard')).toBeInTheDocument();
    });
  });

  describe('Custom ClassNames', () => {
    it('applies className to main content', () => {
      render(
        <AppLayout className="custom-main">
          <div>Content</div>
        </AppLayout>
      );

      const main = screen.getByRole('main');
      expect(main).toHaveClass('custom-main');
    });

    it('applies wrapperClassName to outer container', () => {
      render(
        <AppLayout wrapperClassName="custom-wrapper">
          <div>Content</div>
        </AppLayout>
      );

      const layout = screen.getByTestId('app-layout');
      expect(layout).toHaveClass('custom-wrapper');
    });
  });

  describe('Accessibility', () => {
    it('main content has tabIndex for skip link support', () => {
      render(
        <AppLayout>
          <div>Content</div>
        </AppLayout>
      );

      const main = screen.getByRole('main');
      expect(main).toHaveAttribute('tabIndex', '-1');
    });

    it('layout has min-h-screen for full viewport', () => {
      render(
        <AppLayout>
          <div>Content</div>
        </AppLayout>
      );

      const layout = screen.getByTestId('app-layout');
      expect(layout).toHaveClass('min-h-screen');
    });
  });
});

describe('PageContainer', () => {
  describe('Rendering', () => {
    it('renders container', () => {
      render(
        <PageContainer>
          <div>Content</div>
        </PageContainer>
      );

      expect(screen.getByTestId('page-container')).toBeInTheDocument();
    });

    it('renders children', () => {
      render(
        <PageContainer>
          <div data-testid="test-content">Test Content</div>
        </PageContainer>
      );

      expect(screen.getByTestId('test-content')).toBeInTheDocument();
    });
  });

  describe('Max Width', () => {
    it('defaults to max-w-6xl', () => {
      render(
        <PageContainer>
          <div>Content</div>
        </PageContainer>
      );

      const container = screen.getByTestId('page-container');
      expect(container).toHaveClass('max-w-6xl');
    });

    it('applies custom max width', () => {
      render(
        <PageContainer maxWidth="md">
          <div>Content</div>
        </PageContainer>
      );

      const container = screen.getByTestId('page-container');
      expect(container).toHaveClass('max-w-md');
    });

    it('applies full width', () => {
      render(
        <PageContainer maxWidth="full">
          <div>Content</div>
        </PageContainer>
      );

      const container = screen.getByTestId('page-container');
      expect(container).toHaveClass('max-w-full');
    });
  });

  describe('Styling', () => {
    it('has container and centering classes', () => {
      render(
        <PageContainer>
          <div>Content</div>
        </PageContainer>
      );

      const container = screen.getByTestId('page-container');
      expect(container).toHaveClass('container', 'mx-auto');
    });

    it('has responsive padding', () => {
      render(
        <PageContainer>
          <div>Content</div>
        </PageContainer>
      );

      const container = screen.getByTestId('page-container');
      expect(container).toHaveClass('px-4', 'py-6', 'lg:px-6', 'lg:py-8');
    });

    it('applies custom className', () => {
      render(
        <PageContainer className="custom-class">
          <div>Content</div>
        </PageContainer>
      );

      const container = screen.getByTestId('page-container');
      expect(container).toHaveClass('custom-class');
    });
  });
});

describe('PageHeader', () => {
  describe('Rendering', () => {
    it('renders page header', () => {
      render(<PageHeader title="Test Title" />);

      expect(screen.getByTestId('page-header')).toBeInTheDocument();
    });

    it('renders title', () => {
      render(<PageHeader title="Test Title" />);

      expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent('Test Title');
    });

    it('renders description when provided', () => {
      render(<PageHeader title="Title" description="Test description" />);

      expect(screen.getByText('Test description')).toBeInTheDocument();
    });

    it('does not render description when not provided', () => {
      render(<PageHeader title="Title" />);

      const header = screen.getByTestId('page-header');
      expect(header.querySelectorAll('p')).toHaveLength(0);
    });

    it('renders actions when provided', () => {
      render(
        <PageHeader
          title="Title"
          actions={<button data-testid="action-button">Action</button>}
        />
      );

      expect(screen.getByTestId('action-button')).toBeInTheDocument();
    });
  });

  describe('Styling', () => {
    it('has responsive flex layout', () => {
      render(<PageHeader title="Title" />);

      const header = screen.getByTestId('page-header');
      expect(header).toHaveClass('flex', 'flex-col', 'sm:flex-row');
    });

    it('title has responsive text size', () => {
      render(<PageHeader title="Title" />);

      const title = screen.getByRole('heading', { level: 1 });
      expect(title).toHaveClass('text-2xl', 'sm:text-3xl');
    });

    it('description has muted styling', () => {
      render(<PageHeader title="Title" description="Description" />);

      const description = screen.getByText('Description');
      expect(description).toHaveClass('text-muted-foreground');
    });

    it('applies custom className', () => {
      render(<PageHeader title="Title" className="custom-class" />);

      const header = screen.getByTestId('page-header');
      expect(header).toHaveClass('custom-class');
    });
  });
});
