// @vitest-environment jsdom
import { renderHook } from '@testing-library/react';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';

import { useAxon } from './useAxon';

// Mock window.axon
const mockAxon = vi.fn();

// Setup global window mock
Object.defineProperty(window, 'axon', {
  value: mockAxon,
  writable: true,
  configurable: true,
});

describe('useAxon', () => {
  beforeEach(() => {
    mockAxon.mockClear();
  });

  afterEach(() => {
    // Reset window.axon if window exists
    if (typeof window !== 'undefined') {
      window.axon = mockAxon;
    }
  });

  it('should publish signup event with correct parameters when axon is available', () => {
    const { result } = renderHook(() => useAxon());

    result.current.publishSignupEvent('test-user-123');

    expect(mockAxon).toHaveBeenCalledTimes(1);
    expect(mockAxon).toHaveBeenCalledWith('track', 'sign_up', {
      method: 'web',
      user_id: 'test-user-123',
    });
  });

  it('should publish subscription event with correct parameters', () => {
    const { result } = renderHook(() => useAxon());

    result.current.publishSubscriptionEvent({
      currency: 'USD',
      value: 9.99,
      user_id: 'test-user-456',
    });

    expect(mockAxon).toHaveBeenCalledTimes(1);
    expect(mockAxon).toHaveBeenCalledWith('track', 'subscribe', {
      currency: 'USD',
      value: 9.99,
      user_id: 'test-user-456',
    });
  });

  it('should always use web as method for signup events', () => {
    const { result } = renderHook(() => useAxon());

    result.current.publishSignupEvent('test-user-789');

    expect(mockAxon).toHaveBeenCalledTimes(1);
    expect(mockAxon).toHaveBeenCalledWith('track', 'sign_up', {
      method: 'web',
      user_id: 'test-user-789',
    });
  });

  it('should not call window.axon when axon is not available', () => {
    // Remove window.axon
    delete (window as any).axon;

    const { result } = renderHook(() => useAxon());
    result.current.publishSignupEvent('test-user');

    expect(mockAxon).not.toHaveBeenCalled();
  });

  it('should handle gracefully when axon throws an error', () => {
    // Mock axon to throw an error
    const errorAxon = vi.fn().mockImplementation(() => {
      throw new Error('Axon error');
    });
    window.axon = errorAxon;

    const { result } = renderHook(() => useAxon());

    expect(() => {
      result.current.publishSignupEvent('test-user');
    }).not.toThrow();

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