import React from 'react';
import fs from 'fs';
import path from 'path';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import PublicProfilePage from '../page';
import { getPublicProfile, sendProfileContactMessage } from '@/services/userService';

jest.mock('@/services/userService');
jest.mock('@/contexts/AuthContext', () => ({
  useAuth: () => ({
    isAuthenticated: true,
    loading: false,
    user: { id: '99', username: 'me' },
  }),
}));
jest.mock('next/navigation', () => ({
  useRouter: () => ({ push: jest.fn() }),
  useParams: () => ({ userId: '42' }),
  usePathname: () => '/fr/profil/42',
  useSearchParams: () => new URLSearchParams(),
}));
jest.mock('next/link', () => {
  return ({ children, href, ...props }: { children: React.ReactNode; href: string; [key: string]: unknown }) => (
    <a href={href} {...props}>{children}</a>
  );
});

const mockedGetPublicProfile = getPublicProfile as jest.MockedFunction<typeof getPublicProfile>;
const mockedSendProfileContactMessage = sendProfileContactMessage as jest.MockedFunction<typeof sendProfileContactMessage>;

const mockProfile = {
  id: 42,
  pseudo: 'breizh56',
  prenom: 'Yann',
  patronyme: 'Le Bras',
  avatarUrl: null,
  favoris: [],
  participations: [],
  commentaires: [],
  annonces: [],
  covoiturages: [],
};

describe('PublicProfilePage', () => {
  beforeEach(() => {
    jest.clearAllMocks();
    mockedGetPublicProfile.mockResolvedValue(mockProfile);
    mockedSendProfileContactMessage.mockResolvedValue(undefined);
  });

  it('shouldFallBackToTheDefaultAvatarWhenProfileHasNone', async () => {
    render(<PublicProfilePage />);

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

    const avatar = screen.getByAltText('breizh56');
    expect(avatar).toHaveAttribute('src', '/images/tk-default-avatar.svg');

    const publicDir = path.join(__dirname, '../../../../../../public');
    expect(fs.existsSync(path.join(publicDir, '/images/tk-default-avatar.svg'))).toBe(true);
  });

  it('shouldShowContactButtonOnPublicProfile', async () => {
    render(<PublicProfilePage />);

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

    expect(screen.getByRole('button', { name: /contact_send_message/i })).toBeInTheDocument();
  });

  it('shouldOpenContactModalOnClick', async () => {
    const user = userEvent.setup();
    render(<PublicProfilePage />);

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

    const contactButton = screen.getByRole('button', { name: /contact_send_message/i });
    await user.click(contactButton);

    expect(screen.getByText(/contact_title/i)).toBeInTheDocument();
  });

  it('shouldSendMessageViaProfileContactService', async () => {
    const user = userEvent.setup();
    render(<PublicProfilePage />);

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

    await user.click(screen.getByRole('button', { name: /contact_send_message/i }));

    const textarea = screen.getByRole('textbox');
    await user.type(textarea, 'Bonjour !');

    await user.click(screen.getByRole('button', { name: 'contact_send' }));

    await waitFor(() => {
      expect(mockedSendProfileContactMessage).toHaveBeenCalledWith(42, 'Bonjour !');
    });
  });

  it('shouldShowTheActivityOfTheProfileInItsOwnTab', async () => {
    const user = userEvent.setup();
    mockedGetPublicProfile.mockResolvedValue({
      ...mockProfile,
      commentaires: [{id: 1, texte: 'Super soirée !', date: '2026-09-12', heure: '10:00', evenement: {eveId: 12, libelle: 'Fest-noz de Carhaix', date: '2026-11-07', vilNom: 'Carhaix'}}],
      annonces: [{id: 3, titre: 'Cherche bombarde', texte: null, date: '2026-09-15', typeId: 2}],
      covoiturages: [{id: 5, ville: 'Quimper', nombre: 3, heure: '19:30', propose: 1, evenement: null}],
    });
    render(<PublicProfilePage />);
    await waitFor(() => expect(screen.getByText('breizh56')).toBeInTheDocument());

    await user.click(screen.getByRole('tab', {name: /tab_activity/}));

    expect(screen.getByText('Super soirée !')).toBeInTheDocument();
    expect(screen.getByText('Cherche bombarde')).toBeInTheDocument();
    expect(screen.getByText('carpool_offer')).toBeInTheDocument();
  });
});
