/**
 * Tests for DealerResourceCenter component
 * Covers: loading state, error handling, empty state, category tabs, guide links
 */

import React from 'react';
import { render, screen, waitFor, fireEvent } from '@testing-library/react';
import DealerResourceCenter from '../DealerResourceCenter';

// Mock next/link
jest.mock('next/link', () => {
  return function MockLink({ children, href }: { children: React.ReactNode; href: string }) {
    return <a href={href}>{children}</a>;
  };
});

// Mock fetch
const mockFetch = jest.fn();
global.fetch = mockFetch;

describe('DealerResourceCenter', () => {
  const mockCategories = [
    {
      id: 'cat-1',
      name: 'Getting Started',
      slug: 'getting-started',
      guides: [
        { id: 'guide-1', slug: 'setup-guide', title: 'Setup Guide', publishedAt: '2024-01-15' },
        { id: 'guide-2', slug: 'first-steps', title: 'First Steps', publishedAt: '2024-01-20' },
      ],
    },
    {
      id: 'cat-2',
      name: 'Marketing',
      slug: 'marketing',
      guides: [
        {
          id: 'guide-3',
          slug: 'social-media-tips',
          title: 'Social Media Tips',
          publishedAt: '2024-02-01',
        },
      ],
    },
  ];

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

  it('should show loading state initially', () => {
    mockFetch.mockImplementation(() => new Promise(() => {})); // Never resolves

    render(<DealerResourceCenter />);

    expect(screen.getByText('Loading resources...')).toBeInTheDocument();
  });

  it('should show error state on fetch failure', async () => {
    mockFetch.mockResolvedValueOnce({
      ok: false,
      status: 500,
    });

    render(<DealerResourceCenter />);

    await waitFor(() => {
      expect(screen.getByText('Failed to fetch resources')).toBeInTheDocument();
    });
  });

  it('should show custom error message on network error', async () => {
    mockFetch.mockRejectedValueOnce(new Error('Network error'));

    render(<DealerResourceCenter />);

    await waitFor(() => {
      expect(screen.getByText('Network error')).toBeInTheDocument();
    });
  });

  it('should show empty state when no categories', async () => {
    mockFetch.mockResolvedValueOnce({
      ok: true,
      json: async () => ({ categories: [] }),
    });

    render(<DealerResourceCenter />);

    await waitFor(() => {
      expect(screen.getByText(/No resource guides available/)).toBeInTheDocument();
    });
  });

  it('should render category tabs', async () => {
    mockFetch.mockResolvedValueOnce({
      ok: true,
      json: async () => ({ categories: mockCategories }),
    });

    render(<DealerResourceCenter />);

    await waitFor(() => {
      expect(screen.getByRole('button', { name: 'Getting Started' })).toBeInTheDocument();
      expect(screen.getByRole('button', { name: 'Marketing' })).toBeInTheDocument();
    });
  });

  it('should select first category by default', async () => {
    mockFetch.mockResolvedValueOnce({
      ok: true,
      json: async () => ({ categories: mockCategories }),
    });

    render(<DealerResourceCenter />);

    await waitFor(() => {
      // First category should be active (has active class)
      const firstTab = screen.getByRole('button', { name: 'Getting Started' });
      expect(firstTab.className).toContain('Active');
    });
  });

  it('should display guides for active category', async () => {
    mockFetch.mockResolvedValueOnce({
      ok: true,
      json: async () => ({ categories: mockCategories }),
    });

    render(<DealerResourceCenter />);

    await waitFor(() => {
      expect(screen.getByText('Setup Guide')).toBeInTheDocument();
      expect(screen.getByText('First Steps')).toBeInTheDocument();
    });
  });

  it('should switch category on tab click', async () => {
    mockFetch.mockResolvedValueOnce({
      ok: true,
      json: async () => ({ categories: mockCategories }),
    });

    render(<DealerResourceCenter />);

    await waitFor(() => {
      expect(screen.getByText('Setup Guide')).toBeInTheDocument();
    });

    // Click on Marketing tab
    fireEvent.click(screen.getByRole('button', { name: 'Marketing' }));

    await waitFor(() => {
      expect(screen.getByText('Social Media Tips')).toBeInTheDocument();
      expect(screen.queryByText('Setup Guide')).not.toBeInTheDocument();
    });
  });

  it('should render guide links with correct href', async () => {
    mockFetch.mockResolvedValueOnce({
      ok: true,
      json: async () => ({ categories: mockCategories }),
    });

    render(<DealerResourceCenter />);

    await waitFor(() => {
      const setupGuideLink = screen.getByRole('link', { name: 'Setup Guide' });
      expect(setupGuideLink).toHaveAttribute('href', '/resources/setup-guide');
    });
  });

  it('should fetch from /api/resources endpoint', async () => {
    mockFetch.mockResolvedValueOnce({
      ok: true,
      json: async () => ({ categories: [] }),
    });

    render(<DealerResourceCenter />);

    await waitFor(() => {
      expect(mockFetch).toHaveBeenCalledWith('/api/resources');
    });
  });

  it('should handle category with many guides', async () => {
    const manyGuides = Array.from({ length: 10 }, (_, i) => ({
      id: `guide-${i}`,
      slug: `guide-${i}`,
      title: `Guide ${i + 1}`,
      publishedAt: '2024-01-15',
    }));

    mockFetch.mockResolvedValueOnce({
      ok: true,
      json: async () => ({
        categories: [{ id: 'cat-1', name: 'Large Category', slug: 'large', guides: manyGuides }],
      }),
    });

    render(<DealerResourceCenter />);

    await waitFor(() => {
      for (let i = 1; i <= 10; i++) {
        expect(screen.getByText(`Guide ${i}`)).toBeInTheDocument();
      }
    });
  });

  it('should update tab styles on selection', async () => {
    mockFetch.mockResolvedValueOnce({
      ok: true,
      json: async () => ({ categories: mockCategories }),
    });

    render(<DealerResourceCenter />);

    await waitFor(() => {
      const gettingStartedTab = screen.getByRole('button', { name: 'Getting Started' });
      expect(gettingStartedTab.className).toContain('Active');
    });

    // Click on Marketing tab
    fireEvent.click(screen.getByRole('button', { name: 'Marketing' }));

    await waitFor(() => {
      const marketingTab = screen.getByRole('button', { name: 'Marketing' });
      const gettingStartedTab = screen.getByRole('button', { name: 'Getting Started' });
      expect(marketingTab.className).toContain('Active');
      expect(gettingStartedTab.className).not.toContain('Active');
    });
  });
});
