import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { ShareLinkDisplay } from './ShareLinkDisplay';
import { useToast } from '@/hooks/useToast';
import type { TrackShare } from '../services/trackShareService';

// Mock dependencies
vi.mock('@/hooks/useToast');

describe('ShareLinkDisplay', () => {
  const mockToast = {
    success: vi.fn(),
    error: vi.fn(),
    warning: vi.fn(),
    info: vi.fn(),
    toast: vi.fn(),
  };

  const mockShare: TrackShare = {
    id: 1,
    track_id: 123,
    user_id: 456,
    share_token: 'test-token-123',
    permissions: 'read,download',
    access_count: 5,
    created_at: '2024-01-01T00:00:00Z',
    updated_at: '2024-01-01T00:00:00Z',
  };

  beforeEach(() => {
    vi.clearAllMocks();
    vi.mocked(useToast).mockReturnValue(mockToast);

    // Mock navigator.clipboard
    Object.assign(navigator, {
      clipboard: {
        writeText: vi.fn().mockResolvedValue(undefined),
      },
    });
  });

  it('should display share link', () => {
    render(<ShareLinkDisplay share={mockShare} />);

    expect(screen.getByText(/Lien de partage/i)).toBeInTheDocument();
    expect(
      screen.getByText(/tracks\/shared\/test-token-123/i),
    ).toBeInTheDocument();
  });

  it('should display permissions', () => {
    render(<ShareLinkDisplay share={mockShare} />);

    expect(screen.getByText(/Permissions/i)).toBeInTheDocument();
    expect(screen.getByText(/Lecture/i)).toBeInTheDocument();
    expect(screen.getByText(/Téléchargement/i)).toBeInTheDocument();
  });

  it('should display statistics', () => {
    render(<ShareLinkDisplay share={mockShare} />);

    expect(screen.getByText(/Statistiques/i)).toBeInTheDocument();
    expect(screen.getByText(/Nombre d'accès: 5/i)).toBeInTheDocument();
  });

  it('should display expiration date if provided', () => {
    const shareWithExpiration: TrackShare = {
      ...mockShare,
      expires_at: '2024-12-31T23:59:59Z',
    };

    render(<ShareLinkDisplay share={shareWithExpiration} />);

    expect(screen.getByText(/Expire le/i)).toBeInTheDocument();
  });

  it('should copy link to clipboard when copy button is clicked', async () => {
    render(<ShareLinkDisplay share={mockShare} />);

    const copyButton = screen.getByTitle(/Copier le lien/i);
    await userEvent.click(copyButton);

    await waitFor(() => {
      expect(navigator.clipboard.writeText).toHaveBeenCalledWith(
        expect.stringContaining('tracks/shared/test-token-123'),
      );
      expect(mockToast.success).toHaveBeenCalledWith(
        expect.stringContaining('copié'),
      );
    });
  });

  it('should open link in new tab when open button is clicked', async () => {
    const mockOpen = vi.fn();
    window.open = mockOpen;

    render(<ShareLinkDisplay share={mockShare} />);

    const openButton = screen.getByTitle(/Ouvrir le lien/i);
    await userEvent.click(openButton);

    expect(mockOpen).toHaveBeenCalledWith(
      expect.stringContaining('tracks/shared/test-token-123'),
      '_blank',
    );
  });

  it('should handle copy error gracefully', async () => {
    const mockError = new Error('Clipboard error');
    Object.assign(navigator, {
      clipboard: {
        writeText: vi.fn().mockRejectedValue(mockError),
      },
    });

    render(<ShareLinkDisplay share={mockShare} />);

    const copyButton = screen.getByTitle(/Copier le lien/i);
    await userEvent.click(copyButton);

    await waitFor(() => {
      expect(mockToast.error).toHaveBeenCalledWith(
        expect.stringContaining('Impossible de copier'),
      );
    });
  });
});
