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

jest.mock('next/link', () => ({
  __esModule: true,
  default: ({children, href}: {children: React.ReactNode; href: string}) => <a href={href}>{children}</a>,
}));
jest.mock('@/i18n', () => jest.fn().mockResolvedValue({messages: {EpciDetailsPage: {}}}));
jest.mock('@/services/epciService', () => ({
  getEpci: jest.fn(),
  getEpciStats: jest.fn(),
  getEpciEvents: jest.fn().mockResolvedValue([]),
  getEpciActeurs: jest.fn().mockResolvedValue({total: 0, page: 1, itemsPerPage: 12, items: []}),
  getEpciActeursCarte: jest.fn().mockResolvedValue({suaId: 3, centre: null, acteurs: []}),
}));
jest.mock('@/components/Ville/ActeursVille', () => ({
  __esModule: true,
  default: ({cible, initial}: {cible: {type: string; id: string}; initial: {total: number}}) => (
    <div data-testid="acteurs" data-cible={`${cible.type}:${cible.id}`} data-total={initial.total} />
  ),
}));
jest.mock('@/components/Epci/EpciActeursMap', () => ({
  __esModule: true,
  default: ({carte}: {carte: {acteurs: unknown[]}}) => <div data-testid="acteurs-map" data-count={carte.acteurs.length} />,
}));
jest.mock('@/components/Evenements/EvenementCardBootstrap/EventCardBootstrap', () => ({
  __esModule: true,
  default: ({eveId}: {eveId: number}) => <div data-testid="event-card" data-eve={eveId} />,
}));
jest.mock('@/components/Epci/EpciLogoDisplay', () => ({
  __esModule: true,
  default: () => <div data-testid="epci-logo" />,
}));
jest.mock('@/components/shared/VisitCounter/VisitCounter', () => ({
  __esModule: true,
  default: ({tableCible, cibleId}: {tableCible: string; cibleId: number}) => (
    <div data-testid="visit-counter" data-table={tableCible} data-cible={cibleId} />
  ),
}));

import Page, {generateMetadata} from '../page';
import {getEpci, getEpciStats, getEpciEvents, getEpciActeurs, getEpciActeursCarte} from '@/services/epciService';

const mockedGetEpci = getEpci as jest.Mock;
const mockedGetEpciStats = getEpciStats as jest.Mock;
const mockedGetEpciEvents = getEpciEvents as jest.Mock;
const mockedGetEpciActeurs = getEpciActeurs as jest.Mock;
const mockedGetEpciActeursCarte = getEpciActeursCarte as jest.Mock;

const props = {params: Promise.resolve({locale: 'fr', epciId: '3'})};

const qbo = {suaId: 3, suaNom: 'Quimper Bretagne Occidentale', suaLogoPartenaire: 1, villes: []};
const stats = {communes: 0, acteurs: 0, evenements: 0, evenementsN1: 0, lieux: 0};

describe('Page EPCI — balise title et compteur de visites', () => {
  beforeEach(() => {
    jest.clearAllMocks();
    mockedGetEpci.mockResolvedValue(qbo);
    mockedGetEpciStats.mockResolvedValue(stats);
  });

  it('shouldBuildTheDocumentTitleFromTheEpciName', async () => {
    expect(await generateMetadata(props)).toEqual({title: 'Quimper Bretagne Occidentale - Tamm-Kreiz'});
  });

  it('shouldFallBackToTheSiteNameWhenTheEpciCannotBeLoaded', async () => {
    mockedGetEpci.mockRejectedValue(new Error('HTTP 404'));

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

  it('shouldCountTheVisitsOfTheEpci', async () => {
    render(await (Page as any)(props));

    expect(screen.getByRole('heading', {level: 1})).toHaveTextContent('Quimper Bretagne Occidentale');
    const counter = screen.getByTestId('visit-counter');
    expect(counter).toHaveAttribute('data-table', 'geolocale_subdivision_autre');
    expect(counter).toHaveAttribute('data-cible', '3');
  });
});

describe('Page EPCI — agenda, acteurs et carte (spec L171-L173)', () => {
  const acteur = {aenId: 1, aenLibelle: 'Bagad', actif: true, photoUrl: null, type: 'groupe', cibleId: 9, listes: []};

  beforeEach(() => {
    jest.clearAllMocks();
    mockedGetEpci.mockResolvedValue(qbo);
    mockedGetEpciStats.mockResolvedValue(stats);
    mockedGetEpciEvents.mockResolvedValue([]);
    mockedGetEpciActeurs.mockResolvedValue({total: 0, page: 1, itemsPerPage: 12, items: []});
    mockedGetEpciActeursCarte.mockResolvedValue({suaId: 3, centre: null, acteurs: []});
  });

  it('shouldShowTheUpcomingEventsAndLinkToTheEpciAgenda', async () => {
    mockedGetEpciEvents.mockResolvedValue([
      {eveId: 11, eveDate: '2026-10-01', eveTev: {tevLibelle: 'Fest-noz'}, aenParticipants: []},
      {eveId: 12, eveDate: '2026-10-02', eveTev: {tevLibelle: 'Concert'}, aenParticipants: []},
    ]);

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

    expect(mockedGetEpciEvents).toHaveBeenCalledWith('3');
    expect(screen.getAllByTestId('event-card').map((c) => c.getAttribute('data-eve'))).toEqual(['11', '12']);
    expect(screen.queryByText('Aucun événement à venir')).not.toBeInTheDocument();
    expect(screen.getByRole('link', {name: /Tous les événements de Quimper Bretagne Occidentale/})).toHaveAttribute('href', '/fr/evenements?epci=3');
  });

  it('shouldSayWhenNoEventIsComingAndStillLinkToTheAgenda', async () => {
    render(await (Page as any)(props));

    expect(screen.getByText('Aucun événement à venir')).toBeInTheDocument();
    expect(screen.getByRole('link', {name: /Tous les événements de Quimper Bretagne Occidentale/})).toHaveAttribute('href', '/fr/evenements?epci=3');
  });

  it('shouldListTheActorsOfTheEpciCitiesAndMapTheActiveOnes', async () => {
    mockedGetEpciActeurs.mockResolvedValue({total: 30, page: 1, itemsPerPage: 12, items: [acteur]});
    mockedGetEpciActeursCarte.mockResolvedValue({suaId: 3, centre: {geoX: 48, geoY: -4, zoom: 10}, acteurs: [
      {aenId: 1, aenLibelle: 'Bagad', type: 'groupe', cibleId: 9, geoX: 48, geoY: -4, vilNom: 'Quimper'},
      {aenId: 2, aenLibelle: 'Anna', type: 'artiste', cibleId: 2, geoX: 48.1, geoY: -4.1, vilNom: 'Plogonnec'},
    ]});

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

    expect(mockedGetEpciActeurs).toHaveBeenCalledWith('3');
    const acteurs = screen.getByTestId('acteurs');
    expect(acteurs).toHaveAttribute('data-cible', 'epci:3');
    expect(acteurs).toHaveAttribute('data-total', '30');
    expect(screen.getByTestId('acteurs-map')).toHaveAttribute('data-count', '2');
  });

  it('shouldHideTheActorsBlockWithoutActor', async () => {
    render(await (Page as any)(props));

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