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

jest.mock('@/i18n', () => jest.fn().mockResolvedValue({messages: {ArticlesPage: {category_empty: 'Aucun article dans cette rubrique', pagination_prev: 'Plus récents', pagination_next: 'Plus anciens', page_of: 'Page {page} sur {total}', back_to_mag: 'Retour au Mag'}}}));
jest.mock('@/services/articleService', () => ({
  getArticleCategorieBySlug: jest.fn(),
  getArticlesByCategorie: jest.fn(),
}));
jest.mock('@/components/Articles/ArticleCard', () => ({__esModule: true, default: ({article}: {article: {id: number}}) => <div data-testid="card" data-id={article.id} />}));
jest.mock('next/link', () => ({
  __esModule: true,
  default: ({children, href, ...rest}: {children: React.ReactNode; href: string}) => <a href={href} {...rest}>{children}</a>,
}));
jest.mock('next/navigation', () => ({
  notFound: jest.fn(() => {
    throw new Error('NEXT_NOT_FOUND');
  }),
}));

import Page, {generateMetadata} from '../page';
import {getArticleCategorieBySlug, getArticlesByCategorie} from '@/services/articleService';

const mockedCategorie = getArticleCategorieBySlug as jest.Mock;
const mockedArticles = getArticlesByCategorie as jest.Mock;
const portraits = {id: 2, nom: 'Portraits', slug: 'portraits', description: 'Des gens qui font la culture bretonne', ordre: 2};
const article = (id: number) => ({id, title: `Article ${id}`, slug: `article-${id}`, body: '<p>x</p>', createdAt: '2026-09-01', updatedAt: null});
const props = (page?: string) => ({params: Promise.resolve({locale: 'fr', slug: 'portraits'}), searchParams: Promise.resolve(page ? {page} : {})});

describe('Page rubrique du Mag (spec L70)', () => {
  beforeEach(() => {
    jest.clearAllMocks();
    mockedCategorie.mockResolvedValue(portraits);
  });

  it('shouldListTheArticlesOfTheCategoryAndPaginate', async () => {
    mockedArticles.mockResolvedValue({articles: [article(1), article(2)], total: 30, page: 2, itemsPerPage: 12});

    render(await Page(props('2')));

    expect(mockedArticles).toHaveBeenCalledWith(2, 2);
    expect(screen.getByRole('heading', {level: 1})).toHaveTextContent('Portraits');
    expect(screen.getByText('Des gens qui font la culture bretonne')).toBeInTheDocument();
    expect(screen.getAllByTestId('card')).toHaveLength(2);
    expect(screen.getByText('Page 2 sur 3')).toBeInTheDocument();
    expect(screen.getByRole('link', {name: /Plus récents/})).toHaveAttribute('href', '/fr/articles/categorie/portraits?page=1');
    expect(screen.getByRole('link', {name: /Plus anciens/})).toHaveAttribute('href', '/fr/articles/categorie/portraits?page=3');
  });

  it('shouldHideThePaginationLinksAtTheEdges', async () => {
    mockedArticles.mockResolvedValue({articles: [article(1)], total: 5, page: 1, itemsPerPage: 12});

    render(await Page(props()));

    expect(mockedArticles).toHaveBeenCalledWith(2, 1);
    expect(screen.queryByRole('link', {name: /Plus récents/})).not.toBeInTheDocument();
    expect(screen.queryByRole('link', {name: /Plus anciens/})).not.toBeInTheDocument();
  });

  it('shouldSayWhenTheCategoryHasNoArticle', async () => {
    mockedArticles.mockResolvedValue({articles: [], total: 0, page: 1, itemsPerPage: 12});

    render(await Page(props()));

    expect(screen.getByText('Aucun article dans cette rubrique')).toBeInTheDocument();
    expect(screen.getByRole('link', {name: /Retour au Mag/})).toHaveAttribute('href', '/fr/articles');
  });

  it('shouldAnswer404ForAnUnknownCategory', async () => {
    mockedCategorie.mockResolvedValue(null);

    await expect(Page(props())).rejects.toThrow('NEXT_NOT_FOUND');
  });

  it('shouldTitleTheDocumentAfterTheCategory', async () => {
    expect((await generateMetadata(props())).title).toContain('Portraits');
  });
});
