import {
    getPriceOfLineItem,
    getPriceOfLineItems,
    getTaxOfLineItems
} from '@/helpers/price-calculator.js';

describe('price-calculator', () => {
    describe('getPriceOfLineItem', () => {
        test('Empty lineItem returns 0', () => {
            // Arrange
            const lineItem = {};

            // Act
            const result = getPriceOfLineItem(lineItem);

            // Assert
            expect(result).toBe(0);
        });

        test('Returns kit, labor, sellingPrice total', () => {
            // Arrange
            const lineItem = {
                kitPrice: 1,
                laborAmount: 2,
                sellingPrice: 3,
                salesTax: 4
            };

            // Act
            const result = getPriceOfLineItem(lineItem);

            // Assert
            expect(result).toBe(6);
        });
    });

    describe('getPriceOfLineItems', () => {
        test('Returns zero when null', () => {
            // Arrange
            const lineItems = null;

            // Act
            const result = getPriceOfLineItems(lineItems);

            // Assert
            expect(result).toBe(0);
        });

        test('Returns zero when no line items', () => {
            // Arrange
            const lineItems = [];

            // Act
            const result = getPriceOfLineItems(lineItems);

            // Assert
            expect(result).toBe(0);
        });
        test('Returns expected when one line item', () => {
            // Arrange
            const lineItems = [
                {
                    kitPrice: 1,
                    laborAmount: 2,
                    sellingPrice: 3
                }
            ];
            const expected = 6;

            // Act
            const result = getPriceOfLineItems(lineItems);

            // Assert
            expect(result).toBe(expected);
        });
        test('Returns expected when multiple line items and child parts', () => {
            // Arrange
            const lineItems = [
                {
                    kitPrice: 1,
                    laborAmount: 2,
                    sellingPrice: 3
                },
                {
                    kitPrice: 1
                },
                {
                    kitPrice: 10,
                    laborAmount: 100,
                    sellingPrice: 1000,
                    childParts: [
                        {
                            kitPrice: 1,
                            laborAmount: 2,
                            sellingPrice: 3,
                            salesTax: 4
                        },
                        {
                            kitPrice: 2,
                            laborAmount: 3,
                            sellingPrice: 4,
                            salesTax: 5
                        }
                    ]
                }
            ];
            const expected = 1132;

            // Act
            const result = getPriceOfLineItems(lineItems);

            // Assert
            expect(result).toBe(expected);
        });
    });

    describe('getTaxOfLineItems', () => {
        test('Returns zero when null line items', () => {
            // Arrange
            const lineItems = null;

            // Act
            const result = getTaxOfLineItems(lineItems);

            // Assert
            expect(result).toBe(0);
        });
        test('Returns zero when no line items', () => {
            // Arrange
            const lineItems = [];

            // Act
            const result = getTaxOfLineItems(lineItems);

            // Assert
            expect(result).toBe(0);
        });
        test('Returns expected when one line item', () => {
            // Arrange
            const lineItems = [
                {
                    kitPrice: 1,
                    laborAmount: 2,
                    sellingPrice: 3,
                    salesTax: 4
                }
            ];
            const expected = 4;

            // Act
            const result = getTaxOfLineItems(lineItems);

            // Assert
            expect(result).toBe(expected);
        });
        test('Returns expected when multiple line items', () => {
            // Arrange
            const lineItems = [
                {
                    kitPrice: 1,
                    laborAmount: 2,
                    sellingPrice: 3,
                    salesTax: 4
                },
                {
                    kitPrice: 1,
                    salesTax: 2
                },
                {
                    kitPrice: 10,
                    laborAmount: 100,
                    sellingPrice: 1000,
                    salesTax: 50
                }
            ];
            const expected = 56;

            // Act
            const result = getTaxOfLineItems(lineItems);

            // Assert
            expect(result).toBe(expected);
        });

        test('Returns expected when multiple line items', () => {
            // Arrange
            const lineItems = [
                {
                    kitPrice: 1,
                    laborAmount: 2,
                    sellingPrice: 3,
                    salesTax: 4
                },
                {
                    kitPrice: 1,
                    salesTax: 2
                },
                {
                    kitPrice: 10,
                    laborAmount: 100,
                    sellingPrice: 1000,
                    salesTax: 50
                }
            ];
            const expected = 56;

            // Act
            const result = getTaxOfLineItems(lineItems);

            // Assert
            expect(result).toBe(expected);
        });

        test('Returns expected with child line items', () => {
            // Arrange
            const lineItems = [
                {
                    kitPrice: 1,
                    laborAmount: 2,
                    sellingPrice: 3,
                    salesTax: 4,
                    childParts: [
                        {
                            kitPrice: 10,
                            laborAmount: 20,
                            sellingPrice: 30,
                            salesTax: 40
                        }
                    ]
                },
                {
                    kitPrice: 1,
                    salesTax: 2
                },
                {
                    kitPrice: 10,
                    laborAmount: 100,
                    sellingPrice: 1000,
                    salesTax: 50
                }
            ];
            const expected = 96;

            // Act
            const result = getTaxOfLineItems(lineItems);

            // Assert
            expect(result).toBe(expected);
        });
    });
});
