import { newSpecPage } from "@stencil/core/testing";
import { BpSdkQuoteRequestBindContainer } from "../bp-sdk-quote-request-bind-container/bp-sdk-quote-request-bind-container";
import { BpSdkQuoteRequestButtonContainer } from "../bp-sdk-quote-request-button-container/bp-sdk-quote-request-button-container";
import { BpSdkQuoteRequestButton } from "../bp-sdk-quote-request-button/bp-sdk-quote-request-button";
import { BpSdkQuoteRequestCoverageItemContainer } from "../bp-sdk-quote-request-coverage-item-container/bp-sdk-quote-request-coverage-item-container";
import { BpSdkQuoteRequestCoverageItem } from "../bp-sdk-quote-request-coverage-item/bp-sdk-quote-request-coverage-item";
import { BpSdkQuoteRequestCoverageList } from "../bp-sdk-quote-request-coverage-list/bp-sdk-quote-request-coverage-list";
import { BpSdkQuoteRequestFees } from "../bp-sdk-quote-request-fees/bp-sdk-quote-request-fees";
import { BpSdkQuoteRequestHeaderContainer } from "../bp-sdk-quote-request-header-container/bp-sdk-quote-request-header-container";
import { BpSdkQuoteRequestHeader } from "../bp-sdk-quote-request-header/bp-sdk-quote-request-header";
import { BpSdkQuoteRequestLogoContainer } from "../bp-sdk-quote-request-logo-container/bp-sdk-quote-request-logo-container";
import { BpSdkQuoteRequestLogo } from "../bp-sdk-quote-request-logo/bp-sdk-quote-request-logo";
import { BpSdkQuoteRequestPremiumContainer } from "../bp-sdk-quote-request-premium-container/bp-sdk-quote-request-premium-container";
import { BpSdkQuoteRequestPremiumMonthly } from "../bp-sdk-quote-request-premium-monthly/bp-sdk-quote-request-premium-monthly";
import { BpSdkQuoteRequestPremiumPayment } from "../bp-sdk-quote-request-premium-payment/bp-sdk-quote-request-premium-payment";
import { BpSdkQuoteRequestPremiumTerm } from "../bp-sdk-quote-request-premium-term/bp-sdk-quote-request-premium-term";
import { BpSdkQuoteRequestPremium } from "../bp-sdk-quote-request-premium/bp-sdk-quote-request-premium";
import { BpSdkQuoteRequestPrice } from "../bp-sdk-quote-request-price/bp-sdk-quote-request-price";
import { BpSdkQuoteRequestProductContainer } from "../bp-sdk-quote-request-product-container/bp-sdk-quote-request-product-container";
import { BpSdkQuoteRequestProductListContainer } from "../bp-sdk-quote-request-product-list-container/bp-sdk-quote-request-product-list-container";
import { BpSdkQuoteRequestProductList } from "../bp-sdk-quote-request-product-list/bp-sdk-quote-request-product-list";
import { BpSdkQuoteRequestProduct } from "../bp-sdk-quote-request-product/bp-sdk-quote-request-product";
import { BpSdkQuoteRequestStatusListContainer } from "../bp-sdk-quote-request-status-list-container/bp-sdk-quote-request-status-list-container";
import { BpSdkQuoteRequestStatusList } from "../bp-sdk-quote-request-status-list/bp-sdk-quote-request-status-list";
import { BpSdkQuoteRequestTaxesAndFeesContainer } from "../bp-sdk-quote-request-taxes-and-fees-container/bp-sdk-quote-request-taxes-and-fees-container";
import { BpSdkQuoteRequestTaxesAndFees } from "../bp-sdk-quote-request-taxes-and-fees/bp-sdk-quote-request-taxes-and-fees";
import { BpSdkQuoteRequestVehicleCoverage } from "../bp-sdk-quote-request-vehicle-coverage/bp-sdk-quote-request-vehicle-coverage";
import { BpSdkQuoteRequest } from "./bp-sdk-quote-request";
describe('bp-sdk-quote-request', () => {
    const setupPage = async () => {
        return await newSpecPage({
            html: '<bp-sdk-quote-request></bp-sdk-quote-request>',
            components: [
                BpSdkQuoteRequest,
                BpSdkQuoteRequestBindContainer,
                BpSdkQuoteRequestButton,
                BpSdkQuoteRequestButtonContainer,
                BpSdkQuoteRequestCoverageItem,
                BpSdkQuoteRequestCoverageItemContainer,
                BpSdkQuoteRequestCoverageList,
                BpSdkQuoteRequestFees,
                BpSdkQuoteRequestHeader,
                BpSdkQuoteRequestHeaderContainer,
                BpSdkQuoteRequestLogo,
                BpSdkQuoteRequestLogoContainer,
                BpSdkQuoteRequestPremium,
                BpSdkQuoteRequestPremiumContainer,
                BpSdkQuoteRequestPremiumMonthly,
                BpSdkQuoteRequestPremiumPayment,
                BpSdkQuoteRequestPremiumTerm,
                BpSdkQuoteRequestPrice,
                BpSdkQuoteRequestProduct,
                BpSdkQuoteRequestProductContainer,
                BpSdkQuoteRequestProductList,
                BpSdkQuoteRequestProductListContainer,
                BpSdkQuoteRequestStatusList,
                BpSdkQuoteRequestStatusListContainer,
                BpSdkQuoteRequestTaxesAndFees,
                BpSdkQuoteRequestTaxesAndFeesContainer,
                BpSdkQuoteRequestVehicleCoverage,
            ],
        });
    };
    const setupInstance = (page) => {
        const instance = page.rootInstance;
        instance.carrier = {};
        instance.quoteInfo = {};
        instance.showLogo = true;
        instance.quoteStatus = {
            recommended: false,
            selected: false,
            consumer_selected: false,
            focused: false,
            expired: false,
        };
        return instance;
    };
    describe('render', () => {
        it('vanilla', async () => {
            const page = await setupPage();
            setupInstance(page);
            await page.waitForChanges();
            expect(page.body.querySelector('.bp-sdk-quote__container')).toBeTruthy();
            expect(page.body.querySelector('.bp-sdk-quote__send-to-exchange')).toBeFalsy();
            expect(page.body.querySelector('bp-sdk-send-to-exchange-container')).toBeFalsy();
        });
        it('quoteStatus', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.quoteStatus = {
                recommended: true,
                selected: true,
                consumer_selected: true,
                focused: true,
                expired: true,
            };
            await page.waitForChanges();
            expect(page.body.querySelectorAll('bp-sdk-chip').length).toBe(5);
        });
        it('logo-url', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.carrier = {
                name: 'carrier name',
                logo_url: 'http://asd.io/',
            };
            instance.bindable = true;
            instance.showCustomLogo = false;
            await page.waitForChanges();
            expect(page.body.querySelector('img.bp-sdk-quote__carrier-logo').src).toEqual(instance.carrier.logo_url);
        });
        it('custom url', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.carrier = {
                name: 'Carrier',
                logo_url: 'asd',
            };
            instance.showCustomLogo = true;
            instance.customLogoBaseUrl = 'http://img.com/';
            instance.bindable = true;
            await page.waitForChanges();
            expect(page.body.querySelector('img.bp-sdk-quote__carrier-logo').src).toEqual(`${instance.customLogoBaseUrl}${instance.carrier.name.toLowerCase()}.png`);
        });
        it('handles no carrier with custom url', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.carrier = undefined;
            instance.showCustomLogo = true;
            instance.customLogoBaseUrl = 'http://img.com/';
            instance.bindable = true;
            await page.waitForChanges();
            expect(page.body.querySelector('img.bp-sdk-quote__carrier-logo').src).toEqual(`${instance.customLogoBaseUrl}undefined.png`);
        });
        it('bindable', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.carrier = {
                name: 'carrier name',
            };
            instance.bindable = true;
            await page.waitForChanges();
            expect(page.body.querySelector('.bp-sdk-quote__bind')).toBeTruthy();
        });
        it('products', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.carrier = {
                name: 'carrier name',
            };
            instance.products = [
                {
                    name: 'some name',
                    coverage: {
                        limit_and_deductible_default: [
                            {
                                description: 'some description',
                                value: 'some value',
                            },
                        ],
                    },
                },
            ];
            await page.waitForChanges();
            expect(page.body.querySelector('.bp-sdk-quote__product')).toBeTruthy();
            expect(page.body.textContent).toContain('some description');
            expect(page.body.textContent).toContain('some value');
        });
        it('products limit and deductible', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.carrier = {
                name: 'carrier name',
            };
            instance.products = [
                {
                    name: 'some name',
                    coverage: {
                        limit_and_deductible: [
                            {
                                description: 'some description',
                                value: 'some value',
                            },
                        ],
                    },
                },
            ];
            await page.waitForChanges();
            expect(page.body.querySelector('.bp-sdk-quote__product')).toBeTruthy();
            expect(page.body.textContent).toContain('some description');
            expect(page.body.textContent).toContain('some value');
        });
        it('annual price', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.carrier = {
                name: 'carrier name',
            };
            instance.quoteInfo = {
                monthly_price: 1,
                downpayment: 2000,
                annual_price: 40000,
                number_of_installments: 6,
            };
            await page.waitForChanges();
            expect(page.body.textContent).toContain('$40,000');
        });
        it('semiannual price', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.carrier = {
                name: 'carrier name',
            };
            instance.quoteInfo = {
                monthly_price: '1',
                downpayment: '2000.00',
                semiannual_price: '30000.0',
                number_of_installments: 6,
                annual_price: null,
                price_details: {},
                quote_number: 'asd',
            };
            await page.waitForChanges();
            expect(page.body.textContent).toContain('$30,000');
        });
        it('new_total_premium price', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.carrier = {
                name: 'carrier name',
            };
            await page.waitForChanges();
            expect(page.body.textContent).not.toContain('$30,000.00');
            instance.quoteInfo = {
                monthly_price: null,
                downpayment: '2000.0',
                annual_price: '30000.0',
                number_of_installments: 6,
                price_details: {
                    new_total_premium: null,
                    disclaimer_html: null,
                    fees: [],
                    taxes: [],
                    term: null,
                },
                semiannual_price: null,
                quote_number: 'asb',
            };
            await page.waitForChanges();
            expect(page.body.textContent).toContain('$30,000.00');
            instance.quoteInfo = {
                monthly_price: 0,
                downpayment: 2000,
                annual_price: 30000,
                number_of_installments: 6,
                price_details: {
                    new_total_premium: '5000',
                    disclaimer_html: null,
                },
            };
            await page.waitForChanges();
            expect(page.body.textContent).toContain('$5,000');
            expect(page.body.textContent).not.toContain('$30,000.00');
            instance.quoteInfo = {
                monthly_price: 0,
                downpayment: 2000,
                annual_price: 30000,
                number_of_installments: 6,
                price_details: {
                    new_total_premium: 5000,
                    disclaimer_html: null,
                },
            };
            await page.waitForChanges();
            expect(page.body.textContent).toContain('$5,000');
        });
        it('fees', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.carrier = {
                name: 'carrier name',
            };
            instance.quoteInfo = {
                monthly_price: 1,
                downpayment: 2000,
                annual_price: 30000,
                number_of_installments: 6,
                price_details: {
                    fees: [{ description: 'misc', amount: '$1,000.02' }],
                    taxes: [{ description: 'misc', amount: '$2,000.01' }],
                    disclaimer_html: 'oh my',
                },
            };
            await page.waitForChanges();
            expect(page.body.textContent).toContain('1,000.02');
            expect(page.body.textContent).toContain('2,000.01');
            expect(page.body.textContent).toContain('oh my');
        });
        it('commercial auto', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.carrier = {
                name: 'carrier name',
            };
            instance.quoteInfo = {
                monthly_price: 1,
                downpayment: 2000,
                semiannual_price: 30000,
                number_of_installments: 6,
            };
            instance.products = [
                {
                    name: 'Commercial Auto',
                    coverage: {
                        limit_and_deductible: [],
                        limit_and_deductible_default: [],
                        vehicles: [
                            {
                                make: 'tesla',
                                model: '3',
                                year: '2020',
                            },
                        ],
                    },
                },
            ];
            await page.waitForChanges();
            expect(page.body.querySelector('.bp-sdk-quote__coverages-vehicle-description')).toBeTruthy();
            expect(page.body.querySelector('.bp-sdk-quote__coverages-disclaimer-text')).toBeTruthy();
        });
        it('renders external component if defined', async () => {
            const whenDefinedMock = jest.spyOn(customElements, 'whenDefined').mockResolvedValueOnce({});
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.carrier = {
                name: 'carrier name',
            };
            await page.waitForChanges();
            expect(page.body.querySelector('.bp-sdk-quote__container')).toBeFalsy();
            whenDefinedMock.mockRestore();
        });
    });
    describe('onCarrierChange', () => {
        it('emits a rate returned event', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.bpAnalyticsTrack = { emit: jest.fn() };
            instance.onCarrierChange({ id: 'newId', name: 'newCarrier' }, { id: 'oldId' });
            expect(instance.bpAnalyticsTrack.emit).toHaveBeenCalledWith({
                eventName: 'Display',
                eventPayload: {
                    label: `newCarrier_RateReturned`,
                    value: 0,
                },
            });
        });
        it('emits an online buy event', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.bpAnalyticsTrack = { emit: jest.fn() };
            instance.quoteInfo = {
                annual_price: 100,
            };
            instance.bindable = true;
            instance.onCarrierChange({ id: 'newId', name: 'newCarrier' }, { id: 'oldId' });
            expect(instance.bpAnalyticsTrack.emit).toHaveBeenCalledWith({
                eventName: 'Display',
                eventPayload: {
                    label: `OnlineBuy`,
                    value: 0,
                    dataValue: 100,
                },
            });
        });
        it('defaults online buy value to zero when annual_price is missing', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.bpAnalyticsTrack = { emit: jest.fn() };
            instance.quoteInfo = {
                annual_price: undefined,
            };
            instance.bindable = true;
            instance.onCarrierChange({ id: 'newId', name: 'newCarrier' }, { id: 'oldId' });
            expect(instance.bpAnalyticsTrack.emit).toHaveBeenCalledWith({
                eventName: 'Display',
                eventPayload: {
                    label: `OnlineBuy`,
                    value: 0,
                    dataValue: 0,
                },
            });
        });
        it('defaults online buy value to zero when quote info is missing', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.bpAnalyticsTrack = { emit: jest.fn() };
            instance.quoteInfo = undefined;
            instance.bindable = true;
            instance.onCarrierChange({ id: 'newId', name: 'newCarrier' }, { id: 'oldId' });
            expect(instance.bpAnalyticsTrack.emit).toHaveBeenCalledWith({
                eventName: 'Display',
                eventPayload: {
                    label: `OnlineBuy`,
                    value: 0,
                    dataValue: 0,
                },
            });
        });
        it('does not emit when useExternal is true', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.bpAnalyticsTrack = { emit: jest.fn() };
            instance.useExternal = true;
            instance.onCarrierChange({ id: 'newId', name: 'newCarrier' }, { id: 'oldId' });
            expect(instance.bpAnalyticsTrack.emit).not.toHaveBeenCalled();
        });
    });
    describe('onQuoteStatusChange', () => {
        it('emits recommended rate when recommended', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.bpAnalyticsTrack = { emit: jest.fn() };
            instance.quoteInfo = {
                annual_price: '100.0',
            };
            instance.price = '200.0';
            instance.bindable = true;
            instance.onQuoteStatusChange({ recommended: true });
            expect(instance.bpAnalyticsTrack.emit).toHaveBeenCalledWith({
                eventName: 'Display',
                eventPayload: {
                    label: `Recommended Rate`,
                    value: '100.0',
                    dataValue: '200.0',
                },
            });
        });
        it('emits recommended carrier when recommended', async () => {
            const page = await setupPage();
            const instance = setupInstance(page);
            instance.bpAnalyticsTrack = { emit: jest.fn() };
            instance.bindable = true;
            instance.carrier = {
                name: 'Test Carrier',
            };
            instance.onQuoteStatusChange({ recommended: true });
            expect(instance.bpAnalyticsTrack.emit).toHaveBeenCalledWith({
                eventName: 'Display',
                eventPayload: {
                    label: `Recommended Carrier`,
                    value: 'Test Carrier',
                },
            });
        });
    });
});
