import React from 'react';
import { render, fireEvent, act } from '@testing-library/react';
import { BackToTop } from '@/src/components/BackToTop';

// Mock window properties
global.scrollTo = jest.fn();
Object.defineProperty(window, 'pageYOffset', {
  writable: true,
  configurable: true,
  value: 0,
});

describe('BackToTop', () => {
  beforeEach(() => {
    jest.clearAllMocks();
    window.pageYOffset = 0;
  });

  it('does not render button when at top of page', () => {
    const { container } = render(<BackToTop />);
    const button = container.querySelector('button');
    expect(button).not.toBeInTheDocument();
  });

  it('renders button when scrolled down', () => {
    const { container } = render(<BackToTop />);
    
    // Simulate scroll down
    act(() => {
      window.pageYOffset = 400;
      fireEvent.scroll(window);
    });
    
    const button = container.querySelector('button');
    expect(button).toBeInTheDocument();
  });

  it('hides button when scrolled back up', () => {
    const { container } = render(<BackToTop />);
    
    // Scroll down first
    act(() => {
      window.pageYOffset = 400;
      fireEvent.scroll(window);
    });
    
    expect(container.querySelector('button')).toBeInTheDocument();
    
    // Scroll back up
    act(() => {
      window.pageYOffset = 100;
      fireEvent.scroll(window);
    });
    
    expect(container.querySelector('button')).not.toBeInTheDocument();
  });

  it('scrolls to top when clicked', () => {
    const { container } = render(<BackToTop />);
    
    // Make button visible
    act(() => {
      window.pageYOffset = 400;
      fireEvent.scroll(window);
    });
    
    const button = container.querySelector('button');
    fireEvent.click(button!);
    
    expect(global.scrollTo).toHaveBeenCalledWith({
      top: 0,
      behavior: 'smooth'
    });
  });

  it('has correct styling when visible', () => {
    const { container } = render(<BackToTop />);
    
    // Make button visible
    act(() => {
      window.pageYOffset = 400;
      fireEvent.scroll(window);
    });
    
    const button = container.querySelector('button');
    
    expect(button).toHaveClass('fixed');
    expect(button).toHaveClass('bottom-8');
    expect(button).toHaveClass('right-8');
    expect(button).toHaveClass('bg-blue-600');
    expect(button).toHaveClass('text-white');
    expect(button).toHaveClass('rounded-full');
    expect(button).toHaveClass('shadow-lg');
  });

  it('has hover effect', () => {
    const { container } = render(<BackToTop />);
    
    // Make button visible
    act(() => {
      window.pageYOffset = 400;
      fireEvent.scroll(window);
    });
    
    const button = container.querySelector('button');
    expect(button).toHaveClass('hover:bg-blue-700');
    expect(button).toHaveClass('hover:scale-110');
  });

  it('contains arrow icon', () => {
    const { container } = render(<BackToTop />);
    
    // Make button visible
    act(() => {
      window.pageYOffset = 400;
      fireEvent.scroll(window);
    });
    
    const svg = container.querySelector('svg');
    
    expect(svg).toBeInTheDocument();
    expect(svg).toHaveClass('w-6');
    expect(svg).toHaveClass('h-6');
  });

  it('has aria-label for accessibility', () => {
    const { container } = render(<BackToTop />);
    
    // Make button visible
    act(() => {
      window.pageYOffset = 400;
      fireEvent.scroll(window);
    });
    
    const button = container.querySelector('button');
    expect(button).toHaveAttribute('aria-label', 'Back to top');
  });

  it('cleans up scroll listener on unmount', () => {
    const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener');
    const { unmount } = render(<BackToTop />);
    
    unmount();
    
    expect(removeEventListenerSpy).toHaveBeenCalledWith('scroll', expect.any(Function));
    removeEventListenerSpy.mockRestore();
  });
});