/**
 * @jest-environment jsdom
 */
import CfCore from "../../core/CfCore"

import Loyalty from "../Loyalty"
import { ContentBlock } from "../Navigation/typings"
import { MilestoneAction, PromoAction, PromoItemType, PromoType } from "./typings"
import { LoyaltyTypes } from "./typings"

let mockSender
let mockImpressionManager = {}

const device_id = 'asdf'

describe('Loyalty', () => {
    beforeAll(() => {
        mockSender = {
            add() { return false }
        }
    })
    afterEach(() => {
        // to remove the singleton instance
        (CfCore as any).instance = null
    })

    it('Should deliver a "Level" event', () => {
        const senderSpy = jest.spyOn(mockSender, 'add')
        CfCore.createInstance(mockSender as any, mockImpressionManager as any, false, ContentBlock.Core, 'device-id', false)

        const event = {
            prev_level: 5,
            new_level: 7,
        }

        Loyalty.logLevelEvent(event)

        expect(senderSpy).toBeCalledWith(
            expect.anything(),
            expect.anything(),
            expect.objectContaining(
            {
                type: LoyaltyTypes.Level,
                props: event
            }),
            expect.anything())
    })

    it('Should deliver an "Milestone" event', () => {
        const senderSpy = jest.spyOn(mockSender, 'add')
        CfCore.createInstance(mockSender as any, mockImpressionManager as any, false, ContentBlock.Core,'device-id', false)

        const event = {
            id: "milestone_id",
            action: MilestoneAction.Achieved,
        }

        Loyalty.logMilestoneEvent(event)

        expect(senderSpy).toBeCalledWith(
            expect.anything(),
            expect.anything(),
            expect.objectContaining(
            {
                type: LoyaltyTypes.Milestone,
                props: event
            }),
            expect.anything())
    })

    it('Should deliver an "Promo" event', () => {
        const senderSpy = jest.spyOn(mockSender, 'add')
        CfCore.createInstance(mockSender as any, mockImpressionManager as any, false, ContentBlock.Core,'device-id', false)

        const event = {
            id: "milestone_id",
            action: PromoAction.Apply,
            items: [{id: "111", type: PromoItemType.Blood}],
            title: "some fancy title",
            type: PromoType.AddToCart
        }

        Loyalty.logPromoEvent(event)

        expect(senderSpy).toBeCalledWith(
            expect.anything(),
            expect.anything(),
            expect.objectContaining(
            {
                type: LoyaltyTypes.Promo,
                props: event
            }),
            expect.anything())
    })
    

    it('Should throw an error on "Promo" in case of repeated IDs', () => {
        const senderSpy = jest.spyOn(mockSender, 'add')
        CfCore.createInstance(mockSender as any, mockImpressionManager as any, false, ContentBlock.Core,'device-id', false)

        const event = {
            id: "milestone_id",
            action: PromoAction.Apply,
            items: [{id: "111", type: PromoItemType.Blood}, {id: "111", type: PromoItemType.Blood}],
            title: "some fancy title",
            type: PromoType.AddToCart
        }

        expect(async () => Loyalty.logPromoEvent(event)).rejects.toThrowError()
    })

})