import { isSystemMetaKey } from './orderAdjustmentAdapter';

interface OrderItemLike {
    is_free_item?: boolean;
    quantity: number;
    amount: number;
}

interface DiscountLike {
    amount: number;
}

interface MetaLike {
    key: string;
    amount?: number;
}

export interface OrderTotals {
    subTotal: number;
    discountTotal: number;
    metaTotal: number;
    pointTotal: number;
    extraDiscountTotal: number;
    birthdayExtraTotal: number;
    totalPrice: number;
}

const toAmount = (value: unknown): number => Number(value) || 0;

export const calculateOrderTotals = (
    items: OrderItemLike[],
    shippingPrice: number,
    discounts: DiscountLike[],
    meta: MetaLike[]
): OrderTotals => {
    const subTotal = items.reduce((total, item) => {
        if (item.is_free_item) return total;
        return total + item.quantity * toAmount(item.amount);
    }, 0);

    const discountTotal = discounts.reduce((total, discount) => total + toAmount(discount.amount), 0);

    const pointTotal = meta.reduce((total, item) => {
        if (item.key === 'point') return total + toAmount(item.amount);
        return total;
    }, 0);

    const extraDiscountTotal = meta.reduce((total, item) => {
        if (item.key === 'extra_discount') return total + toAmount(item.amount);
        return total;
    }, 0);

    const birthdayExtraTotal = meta.reduce((total, item) => {
        if (item.key === 'birthday_extra') return total + toAmount(item.amount);
        return total;
    }, 0);

    const metaTotal = meta.reduce((total, item) => {
        if (
            item.key !== 'point' &&
            item.key !== 'extra_discount' &&
            item.key !== 'birthday_extra' &&
            !isSystemMetaKey(item.key)
        ) {
            return total + toAmount(item.amount);
        }
        return total;
    }, 0);

    const totalPrice =
        subTotal + toAmount(shippingPrice) + metaTotal - discountTotal - pointTotal - extraDiscountTotal - birthdayExtraTotal;

    return {
        subTotal,
        discountTotal,
        metaTotal,
        pointTotal,
        extraDiscountTotal,
        birthdayExtraTotal,
        totalPrice,
    };
};
