/**
 * @jest-environment jsdom
 */

import { trackToABTasty } from '../../trackers/abtasty';
import { EVENT_NAME, COUNTRY_CODE, BUSINESS_UNIT } from '../../constants';
import type { Events, TransactionData } from '../../types';

describe('ABTasty Tracker', () => {
  let originalWindow: Window & typeof globalThis;

  beforeEach(() => {
    originalWindow = { ...window };
    window.abtasty = {
      send: jest.fn(),
    };
  });

  afterEach(() => {
    window = originalWindow;
  });

  it('should not track when abtasty is not an object', () => {
    window.abtasty = undefined;
    const consoleWarnSpy = jest.spyOn(console, 'warn');

    const testEvent: Events = {
      name: EVENT_NAME.FORM_STEP_RENDER,
      data: {
        app_name: 'test-app',
        app_version: '1.0.0',
        country_code: COUNTRY_CODE.CL,
        business_unit: BUSINESS_UNIT.CAR_INSURANCE,
        user_type: 'anonymous',
        quote_id: '12345',
        accordion_index: '1',
        accordion_name: 'personal_info',
      },
    };

    trackToABTasty(testEvent);

    expect(consoleWarnSpy).toHaveBeenCalledWith(
      "abtasty wasn't initialized, failed to track an event push"
    );
    consoleWarnSpy.mockRestore();
  });

  it('should not track when abtasty.send is not a function', () => {
    window.abtasty = {};
    const consoleWarnSpy = jest.spyOn(console, 'warn');

    const testEvent: Events = {
      name: EVENT_NAME.FORM_STEP_RENDER,
      data: {
        app_name: 'test-app',
        app_version: '1.0.0',
        country_code: COUNTRY_CODE.CL,
        business_unit: BUSINESS_UNIT.CAR_INSURANCE,
        user_type: 'anonymous',
        quote_id: '12345',
        accordion_index: '1',
        accordion_name: 'personal_info',
      },
    };

    trackToABTasty(testEvent);

    expect(consoleWarnSpy).toHaveBeenCalledWith(
      "Can't track events to abtasty, failed to track an event push"
    );
    consoleWarnSpy.mockRestore();
  });

  it('should track default events', () => {
    const testEvent: Events = {
      name: EVENT_NAME.OTP_ERROR,
      data: {
        app_name: 'test-app',
        app_version: '1.0.0',
        country_code: COUNTRY_CODE.CL,
        business_unit: BUSINESS_UNIT.CAR_INSURANCE,
        user_type: 'anonymous',
        error_code: 'otp-invalid',
      },
    };

    trackToABTasty(testEvent);

    expect(window.abtasty.send).toHaveBeenCalledWith('event', {
      ec: 'Action Tracking',
      ea: EVENT_NAME.OTP_ERROR,
    });
  });

  it('should track transaction events', () => {
    const transactionEvent: Events = {
      name: EVENT_NAME.TRANSACTION,
      data: {
        orderId: '12345',
        type: 'purchase',
        price: 100,
        tax: 10,
        currency: 'USD',
        couponCode: 'DISCOUNT10',
        paymentMethod: 'credit_card',
        itemCount: 2,
      } as TransactionData,
    };

    trackToABTasty(transactionEvent);

    expect(window.abtasty.send).toHaveBeenCalledWith('transaction', {
      tid: '12345',
      ta: 'purchase',
      tr: 100,
      tt: 10,
      tc: 'USD',
      tcc: 'DISCOUNT10',
      pm: 'credit_card',
      icn: 2,
    });
  });

  it('should use default itemCount if not provided in transaction', () => {
    const transactionEvent: Events = {
      name: EVENT_NAME.TRANSACTION,
      data: {
        orderId: '12345',
        type: 'purchase',
        price: 100,
        tax: 10,
        currency: 'USD',
        couponCode: 'DISCOUNT10',
        paymentMethod: 'credit_card',
      } as TransactionData,
    };

    trackToABTasty(transactionEvent);

    expect(window.abtasty.send).toHaveBeenCalledWith(
      'transaction',
      expect.objectContaining({
        icn: 1,
      })
    );
  });

  it('should track form step render events', () => {
    const formStepEvent: Events = {
      name: EVENT_NAME.FORM_STEP_RENDER,
      data: {
        app_name: 'test-app',
        app_version: '1.0.0',
        country_code: COUNTRY_CODE.CL,
        business_unit: BUSINESS_UNIT.CAR_INSURANCE,
        user_type: 'anonymous',
        quote_id: '12345',
        accordion_index: '1',
        accordion_name: 'personal_info',
      },
    };

    trackToABTasty(formStepEvent);

    expect(window.abtasty.send).toHaveBeenCalledWith('event', {
      ec: 'Action Tracking',
      ea: 'CICL - Render personal_info',
    });
  });

  it('should use custom event name mapping for known events', () => {
    const transactionEvent: Events = {
      name: EVENT_NAME.TRANSACTION,
      data: {
        orderId: '12345',
        type: 'purchase',
        price: 100,
        tax: 10,
        currency: 'USD',
      } as TransactionData,
    };

    trackToABTasty(transactionEvent);

    expect(window.abtasty.send).toHaveBeenCalledWith(
      'transaction',
      expect.any(Object)
    );
  });

  it('should use default event name when no mapping exists', () => {
    const unknownEvent: Events = {
      name: EVENT_NAME.OTP_ERROR,
      data: {
        app_name: 'test-app',
        app_version: '1.0.0',
        country_code: COUNTRY_CODE.CL,
        business_unit: BUSINESS_UNIT.CAR_INSURANCE,
        user_type: 'anonymous',
        error_code: 'otp-invalid',
      },
    };

    trackToABTasty(unknownEvent);

    expect(window.abtasty.send).toHaveBeenCalledWith(
      'event',
      expect.any(Object)
    );
  });
});
