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

jest.mock('next/link', () => ({__esModule: true, default: ({children, href, ...rest}: {children: React.ReactNode; href: string}) => <a href={href} {...rest}>{children}</a>}));
jest.mock('@/i18n', () => jest.fn().mockResolvedValue({messages: {SubdivisionPage: {region: 'Région', departement: 'Département', all_events_of: 'Tous les événements : {nom}', no_upcoming_events: 'Aucun événement à venir', pagination_prev: 'Communes précédentes', pagination_next: 'Communes suivantes', page_of: 'Page {page} sur {total}'}}}));
jest.mock('@/services/subdivisionService', () => ({
  getSubdivision: jest.fn(),
  getCommunesDeSubdivision: jest.fn(),
  getEvenementsDeSubdivision: jest.fn().mockResolvedValue([]),
}));
jest.mock('@/components/global/CarteLeafletSingleClient', () => ({__esModule: true, default: ({position}: {position: number[]}) => <div data-testid="carte" data-position={position.join(',')} />}));
jest.mock('@/components/Evenements/EvenementCardBootstrap/EventCardBootstrap', () => ({__esModule: true, default: ({eveId}: {eveId: number}) => <div data-testid="event-card" data-eve={eveId} />}));

import Page, {generateMetadata} from '../page';
import {getSubdivision, getCommunesDeSubdivision, getEvenementsDeSubdivision} from '@/services/subdivisionService';

const mockedGetSubdivision = getSubdivision as jest.Mock;
const mockedGetCommunes = getCommunesDeSubdivision as jest.Mock;
const mockedGetEvenements = getEvenementsDeSubdivision as jest.Mock;

const bretagne = {subId: 12, subNom: 'Bretagne', subNiveau: 1, subGeoX: 48.2, subGeoY: -2.9, subGeoZoom: 7, subPay: {payNom: 'France', payCode: 'FR'}, subMere: null,
  subdivisions: [{subId: 56, subNom: 'Morbihan', subNiveau: 2}, {subId: 29, subNom: 'Finistère', subNiveau: 2}]};
const finistere = {subId: 29, subNom: 'Finistère', subNiveau: 2, subGeoX: 48.2, subGeoY: -4.1, subGeoZoom: 9, subPay: {payNom: 'France', payCode: 'FR'}, subMere: {subId: 12, subNom: 'Bretagne'}, subdivisions: []};
const props = (subId: string, page?: string) => ({params: Promise.resolve({locale: 'fr', subId}), searchParams: Promise.resolve(page ? {page} : {})});

describe('Page région / département (spec L156)', () => {
  beforeEach(() => {
    jest.clearAllMocks();
    mockedGetEvenements.mockResolvedValue([]);
    mockedGetCommunes.mockResolvedValue({communes: [], total: 0, page: 1, itemsPerPage: 60});
  });

  it('shouldListTheDepartmentsOfARegionAndLinkToItsAgenda', async () => {
    mockedGetSubdivision.mockResolvedValue(bretagne);

    render(await (Page as any)(props('12')));

    expect(screen.getByRole('heading', {level: 1})).toHaveTextContent('Bretagne');
    expect(screen.getByText('Région')).toBeInTheDocument();
    expect(screen.getByRole('link', {name: /Finistère/})).toHaveAttribute('href', '/fr/departement/29/finistere');
    expect(screen.getByRole('link', {name: /Morbihan/})).toHaveAttribute('href', '/fr/departement/56/morbihan');
    expect(screen.getByRole('link', {name: /Tous les événements : Bretagne/})).toHaveAttribute('href', '/fr/evenements?sub1=12');
    expect(screen.getByText('Aucun événement à venir')).toBeInTheDocument();
    expect(screen.getByTestId('carte')).toHaveAttribute('data-position', '48.2,-2.9');
    expect(mockedGetCommunes).not.toHaveBeenCalled();
  });

  it('shouldListThePaginatedCommunesOfADepartmentWithItsRegionAndEvents', async () => {
    mockedGetSubdivision.mockResolvedValue(finistere);
    mockedGetCommunes.mockResolvedValue({communes: [{vilId: 1, vilNom: 'Brest', vilCodepostal: '29200'}, {vilId: 2, vilNom: 'Quimper', vilCodepostal: '29000'}], total: 150, page: 2, itemsPerPage: 60});
    mockedGetEvenements.mockResolvedValue([{eveId: 12, eveDate: '2026-10-01', eveTev: {tevLibelle: 'Fest-noz'}, aenParticipants: []}]);

    render(await (Page as any)(props('29', '2')));

    expect(mockedGetCommunes).toHaveBeenCalledWith(finistere, 2);
    expect(screen.getByText('Département')).toBeInTheDocument();
    expect(screen.getByRole('link', {name: 'Bretagne'})).toHaveAttribute('href', '/fr/region/12/bretagne');
    expect(screen.getByRole('link', {name: /Brest/})).toHaveAttribute('href', '/fr/ville/1/brest');
    expect(screen.getByText('Page 2 sur 3')).toBeInTheDocument();
    expect(screen.getByRole('link', {name: /Communes précédentes/})).toHaveAttribute('href', '/fr/departement/29/finistere?page=1');
    expect(screen.getByRole('link', {name: /Communes suivantes/})).toHaveAttribute('href', '/fr/departement/29/finistere?page=3');
    expect(screen.getByTestId('event-card')).toHaveAttribute('data-eve', '12');
    expect(screen.getByRole('link', {name: /Tous les événements : Finistère/})).toHaveAttribute('href', '/fr/evenements?sub2=29');
  });

  it('shouldShowA404WhenTheSubdivisionIsUnknown', async () => {
    mockedGetSubdivision.mockRejectedValue(new Error('Subdivision not found for ID: 999'));

    render(await (Page as any)(props('999')));

    expect(screen.getByText(/not found/)).toBeInTheDocument();
  });

  it('shouldTitleTheDocumentAfterTheSubdivision', async () => {
    mockedGetSubdivision.mockResolvedValue(finistere);

    expect(await generateMetadata(props('29'))).toEqual({title: 'Finistère - Tamm-Kreiz'});
  });
});
