/**
 * OurImpact Component Tests
 * 
 * 測試目標：
 * 1. 元件能正確渲染
 * 2. 元件能正確呼叫廠商 ourImpact.js
 * 3. 元件卸載時能正確 cleanup
 */

import React from 'react';
import { render, waitFor, cleanup as rtlCleanup } from '@testing-library/react';
import OurImpact from '@/components/aia/our-impact';
import * as vendorOurImpact from '@vendor-web/js/components/ourImpact.js';

// Mock 廠商 ourImpact.js
jest.mock('@vendor-web/js/components/ourImpact.js', () => ({
  OurImpact: jest.fn(),
}));

describe('OurImpact Component', () => {
  let mockCleanup: jest.Mock;

  beforeEach(() => {
    mockCleanup = jest.fn();
    (vendorOurImpact.OurImpact as jest.Mock).mockReturnValue(mockCleanup);
  });

  afterEach(() => {
    rtlCleanup();
    jest.clearAllMocks();
  });

  it('應該渲染 ourImpact 結構', () => {
    const { container } = render(<OurImpact />);

    expect(container.querySelector('.ourImpact')).toBeInTheDocument();
    expect(container.querySelector('.ourImpact-heading')).toBeInTheDocument();
    expect(container.querySelector('.ourImpact-container')).toBeInTheDocument();
  });

  it('應該呼叫廠商 OurImpact 初始化函式', async () => {
    render(<OurImpact />);

    await waitFor(() => {
      expect(vendorOurImpact.OurImpact).toHaveBeenCalledTimes(1);
      expect(vendorOurImpact.OurImpact).toHaveBeenCalledWith(
        expect.any(HTMLElement)
      );
    });
  });

  it('應該在元件卸載時呼叫 cleanup 函式', async () => {
    const { unmount } = render(<OurImpact />);

    await waitFor(() => {
      expect(vendorOurImpact.OurImpact).toHaveBeenCalled();
    });

    unmount();

    expect(mockCleanup).toHaveBeenCalledTimes(1);
  });

  it('應該能處理廠商 JS 未返回 cleanup 的情況', async () => {
    // Suppress console.warn for this test
    const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation();
    (vendorOurImpact.OurImpact as jest.Mock).mockReturnValue(undefined);

    const { unmount } = render(<OurImpact />);

    // 不應該拋出錯誤
    expect(() => unmount()).not.toThrow();
    
    // Should log warning
    expect(consoleWarnSpy).toHaveBeenCalledWith(
      '[OurImpact] No cleanup function provided by vendor JS'
    );

    consoleWarnSpy.mockRestore();
  });

  it('應該根據 dataEnd prop 設定不同 class', () => {
    const { container: container1 } = render(<OurImpact />);
    expect(container1.querySelector('.ourImpact')).toHaveAttribute('data-end', 'false');

    rtlCleanup();

    const { container: container2 } = render(<OurImpact dataEnd={true} />);
    expect(container2.querySelector('.ourImpact')).toHaveAttribute('data-end', 'true');
  });
});
