<template>
    <div>
        <div
            v-if="showDropdownHeader"
            id="cart-dropdown-head"
            class="row flex align-items-center pt-4 cart-header cart-toggle"
            :class="[isExpanded ? 'expanded' : '']"
            @click="toggleIsExpanded">
            <a
                aria-label="expand cart details"
                href="javascript:void(0)"
                class="col d-flex justify-content-between py-0">
                <span class="color-black">{{ amountDueLabel }}</span>
                <span class="color-green">{{ getDisplayed(amountDue) }}</span>
            </a>
        </div>
        <div
            v-else
            id="cart-dropdown-head"
            class="expanded cart-header">
        </div>
        <div
            id="cart-table"
            class="cart-table">
            <div
                id="cart-line-items"
                class="color-darker-gray">
                <div
                    id="cart-deductible-or-base-price"
                    class="cart-item cart-gray">
                    <div
                        v-if="showDeductibleCartItem"
                        id="cart-deductible"
                        class="d-flex justify-content-between align-items-center py-2">
                        <span id="deductible-label">{{ deductibleLabel }}</span>
                        <span id="deductible-value">{{ getDisplayed(deductible) }}</span>
                    </div>
                    <div
                        v-else
                        id="cart-base-price"
                        class="d-flex justify-content-between align-items-center">
                        <span id="base-price-label">{{ basePriceLabel }}</span>
                        <span id="base-price-value">{{ getDisplayed(servicePrice) }}</span>
                    </div>
                </div>

                <!-- Packaged Cart Items -->
                <div
                    id="cart-service-package"
                    class="px-5">
                    <div
                        id="service-package-name"
                        class="py-2 d-flex justify-content-between align-items-center">
                        <textBlock
                            :cmsWidgetName="servicePackageLabelWidget"
                            class="force-no-top-margin" />
                        <span id="service-package-price">{{ formatAmountInDollars(packagePrice) }}</span>
                    </div>
                    <div
                        id="service-items"
                        class="ps-4">
                        <div
                            v-for="(item, i) in servicePackageCartItems"
                            :key="i">
                            <div class="py-2 d-flex justify-content-between align-items-center">
                                <span>{{ item?.name ?? '' }}</span>
                                <textLink
                                    v-if="!readOnly"
                                    linkType="text"
                                    text="Remove"
                                    href="javascript:void(0)"
                                    @clickEvent="removeVap(item.partType)">
                                    <template #after-text>
                                        <span class="sr-only">{{ item?.name ?? '' }}</span>
                                    </template>
                                </textLink>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- NonPackaged Cart Items -->
                <div id="non-packaged-cart-items">
                    <div
                        v-for="(item, i) in nonServicePackageCartItems"
                        :key="i"
                        class="px-5 py-2 non-packaged-cart-item">
                        <div class="d-flex justify-content-between align-items-center">
                            <span
                                v-if="item.cartItemType === cartItemType.RECYCLE_FEE"
                                id="recycle-fee-label">
                                <textLink
                                   linkType="text"
                                   :text="item?.name ?? ''"
                                   href="javascript:void(0)"
                                   @clickEvent="openModal(recyclingModalCmsWidgetName)" />
                            </span>
                            <span v-else>{{ item?.name ?? '' }}</span>
                            <span>{{ formatAmountInDollars(item?.subTotal ?? 0) }}</span>
                        </div>
                        <textLink
                            v-if="item.cartItemType === cartItemType.VAP
                                && !readOnly"
                            linkType="text"
                            text="Remove"
                            href="javascript:void(0)"
                            @clickEvent="removeVap(item.partType)">
                            <template #after-text>
                                <span class="sr-only">{{ item?.name ?? '' }}</span>
                            </template>
                        </textLink>
                    </div>
                </div>
                <div
                    id="cart-footer"
                    class="cart-footer pb-5">
                    <div
                        id="cart-subtotal-and-tax"
                        class="subtotal-and-tax">
                        <div
                            id="cart-subtotal"
                            class="py-2 col d-flex justify-content-between">
                            <span id="subtotal-label">{{ subtotalLabel }}</span>
                            <span id="subtotal-value">{{ getDisplayed(subTotal) }}</span>
                        </div>
                        <div
                            id="cart-sales-tax"
                            class="py-2 col d-flex justify-content-between">
                            <span id="sales-tax-label">{{ salesTaxLabel }}</span>
                            <span id="sales-tax-value">{{ formatAmountInDollars(salesTax) }}</span>
                        </div>
                        <div
                            v-if="showAsPaid"
                            id="cart-amount-paid"
                            class="py-2 col d-flex justify-content-between">
                            <span id="amount-paid-label">{{ amountPaidLabel }}</span>
                            <span if="amount-paid-value">{{ getDisplayed(amountPaid) }}</span>
                        </div>
                    </div>
                    <div
                        id="bottom-amount-due"
                        class="bottom-amount-due col d-flex justify-content-between">
                        <span id="bottom-amount-due-label">{{ amountDueLabel }}</span>
                        <span id="bottom-amount-due-value">{{ getDisplayed(amountDue) }}</span>
                    </div>
                </div>
            </div>
            <contentGroupModal
                ref="RecycleModal"
                :cmsWidgetName="recyclingModalCmsWidgetName">
                <textBlock cmsWidgetName="RecycleTextBlock" />
            </contentGroupModal>
        </div>
    </div>
</template>

<script>
import { useMainStore } from '@/store';
import contentGroupModal from '@/iss-components/content-group-modal/content-group-modal.vue';
import textBlock from '@/digital-components/text-block/text-block.vue';
import textLink from '@/ux-components/text-link/text-link.vue';
import { formatAmountInDollars } from '@/helpers/text-helper.js';
import { getHighestFullySatisfiedTier, getPackageContents } from '@/helpers/service-package-helper.js';

// Constants
import partTypeStrings from '@/constants/part-type-strings.js';
import cartItemType from '@/constants/cart-item-type.js';
import widgetFields from '@/constants/cms-widget-fields.js';
import {
    getCartTotal,
    getDeductible,
    getLineItems, getMobileFee,
    getRecycleFee, getSalesTax,
    getServiceLineItems, getSubtotal, isOrderITAC, isOrderNoComp,
    isOrderUnverified
} from '@/helpers/cart-helper';
import {getPriceOfLineItems, getTaxOfLineItems} from '@/helpers/price-calculator';

const VERIFYING_COVERAGE = 'Verifying coverage';

export default {
    name: 'cart-dropdown',
    components: {
        contentGroupModal,
        textBlock,
        textLink
    },
    props: {
        showAsPaid: Boolean,
        readOnly: Boolean,
        recyclingModalCmsWidgetName: String,
        showDropdownHeader: Boolean,
        isInitiallyExpanded: Boolean,
        submittedOrder: Object
    },
    data() {
        return {
            isExpanded: this.isInitiallyExpanded,
            availableVaps: this.submittedOrder ? this.submittedOrder.lineItems.vaps : useMainStore().order.availableVaps,
            widget: {
                amountDue: 'AmountDueTextWidget',
                amountPaid: 'AmountPaidTextWidget',
                deductible: 'DeductibleWidget',
                basePrice: 'BasePriceWidget',
                subtotal: 'SubtotalWidget',
                salesTax: 'SalesTaxWidget',
                recycleFee: 'RecycleFeeWidget',
                mobileFee: 'MobileServiceWidget',
                servicePackage: 'ServicePackageTitle',
                vapsItemDescriptions: 'VapsItemDescriptions'
            },
            cartItemType
        };
    },
    computed: {
        cartOrder() {
            return this.submittedOrder ?? useMainStore().order;
        },
        deductible() {
            return getDeductible(this.cartOrder);
        },
        showDeductibleCartItem() {
            return this.isUnverified || (!this.isNoComp && !this.isITAC);
        },
        lineItems() {
            return getLineItems(this.cartOrder);
        },
        recycleFeeLineItem() {
            return getRecycleFee(this.cartOrder);
        },
        servicePrice() {
            return getPriceOfLineItems(getServiceLineItems(this.cartOrder), false) ?? 0;
        },
        isUnverified() {
            return isOrderUnverified(this.cartOrder);
        },
        isITAC() {
            return isOrderITAC(this.cartOrder);
        },
        isNoComp() {
            return isOrderNoComp(this.cartOrder);
        },
        // TODO fix rounding
        subTotal() {
            return getSubtotal(this.cartOrder);
        },
        salesTax() {
            return getSalesTax(this.cartOrder);
        },
        total() {
            return getCartTotal(this.cartOrder);
        },
        amountDue() {
            return this.showAsPaid ? 0 : this.total;
        },
        amountPaid() {
            return !this.showAsPaid ? 0 : this.total;
        },
        availableLineItems() {
            const { supportingItems, glassParts, otherParts, feeItems } = this.lineItems;
            const result = [
                ...(supportingItems ?? []),
                ...(glassParts ?? []),
                ...(otherParts ?? []),
                ...(this.availableVaps ?? []),
                ...(feeItems ?? [])
            ];
            return result;
        },
        vehicleDamage() {
            return this.submittedOrder ? this.submittedOrder.damage : useMainStore().damage;
        },
        servicePackageTier() {
            const { glassToReplace, isRepair } = this.vehicleDamage;
            const { vaps } = this.lineItems;
            return getHighestFullySatisfiedTier(
                glassToReplace ?? [],
                this.availableLineItems,
                isRepair,
                vaps ?? []
            );
        },
        partTypesInServicePackage() {
            const { glassToReplace, isRepair } = this.vehicleDamage;
            return getPackageContents(
                glassToReplace ?? [],
                this.availableLineItems,
                isRepair,
                this.servicePackageTier
            ) ?? [];
        },
        servicePackageCartItems() {
            const items = [];
            if (this.partTypesInServicePackage.includes(partTypeStrings.FRONT_WIPER) ?? this.frontWipersCartItem) {
                items.push(this.frontWipersCartItem);
            }
            if (this.partTypesInServicePackage.includes(partTypeStrings.REAR_WIPER) ?? this.rearWipersCartItem) {
                items.push(this.rearWipersCartItem);
            }
            if (this.partTypesInServicePackage.includes(partTypeStrings.RAIN_DEFENSE) ?? this.rainDefenseCartItem) {
                items.push(this.rainDefenseCartItem);
            }
            return items;
        },
        nonServicePackageCartItems() {
            const vapPartTypesInOrder = Array.from(new Set(this.lineItems.vaps?.map((vap) => vap.partType) ?? []));
            const vapPartTypesInOrderButNotPackage = vapPartTypesInOrder
                .filter((partType) => !this.partTypesInServicePackage.includes(partType))
                ?? [];
            const vapsCartItemsNotInPackage = vapPartTypesInOrderButNotPackage.map((partType) => {
                switch (partType) {
                    case partTypeStrings.FRONT_WIPER:
                        return this.frontWipersCartItem;
                    case partTypeStrings.REAR_WIPER:
                        return this.rearWipersCartItem;
                    case partTypeStrings.RAIN_DEFENSE:
                        return this.rainDefenseCartItem;
                    default:
                        return null;
                }
            });
            const items = vapsCartItemsNotInPackage.filter((item) => item != null);
            if (this.recycleFeeCartItem) {
                items.push(this.recycleFeeCartItem);
            }
            if (this.mobileFeeCartItem) {
                items.push(this.mobileFeeCartItem);
            }
            return items;
        },
        frontWipersCartItem() {
            return this.getCartItemForVapsPart(partTypeStrings.FRONT_WIPER);
        },
        rearWipersCartItem() {
            return this.getCartItemForVapsPart(partTypeStrings.REAR_WIPER);
        },
        rainDefenseCartItem() {
            return this.getCartItemForVapsPart(partTypeStrings.RAIN_DEFENSE);
        },
        allCartItems() {
            return [
                ...this.servicePackageCartItems,
                ...this.nonServicePackageCartItems
            ];
        },
        packagePrice() {
            return this.servicePackageCartItems?.reduce(
                (accumulator, cartItem) => accumulator + (cartItem?.subTotal ?? 0),
                0
            ) ?? 0;
        },
        amountDueLabel() {
            return this.getCmsContent(this.widget.amountDue, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
        },
        amountPaidLabel() {
            return this.getCmsContent(this.widget.amountPaid, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
        },
        deductibleLabel() {
            return this.getCmsContent(this.widget.deductible, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
        },
        basePriceLabel() {
            return this.getCmsContent(this.widget.basePrice, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
        },
        subtotalLabel() {
            return this.getCmsContent(this.widget.subtotal, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
        },
        salesTaxLabel() {
            return this.getCmsContent(this.widget.salesTax, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
        },
        servicePackageNames() {
            return this.getCmsContent(
                this.widget.servicePackage,
                widgetFields.INPUT_QUESTION_WIDGET.ANSWERS
            );
        },
        servicePackageLabelWidget() {
            if (!this.servicePackageNames) {
                return '';
            }
            const currentPackage = this.servicePackageNames
                ?.find((entry) => entry?.Name === this.servicePackageTier);

            return currentPackage?.SubWidgetName ?? '';
        },
        recycleFeeCartItem() {
            return this.recycleFeeLineItem
                ? this.getCartItem(
                    this.getCmsContent(this.widget.recycleFee, widgetFields.TEXT_BLOCK_WIDGET.TEXT),
                    [this.recycleFeeLineItem],
                    cartItemType.RECYCLE_FEE,
                    partTypeStrings.REPLACE_FEE
                )
                : null;
        },
        mobileFeeCartItem() {
            const mobileFeeLineItem = getMobileFee(this.cartOrder);
            return mobileFeeLineItem
                ? this.getCartItem(
                    this.getCmsContent(this.widget.mobileFee, widgetFields.TEXT_BLOCK_WIDGET.TEXT),
                    [mobileFeeLineItem],
                    cartItemType.MOBILE_FEE,
                    partTypeStrings.MOBILE_FEE
                )
                : null;
        }
    },
    methods: {
        openModal(modalName) {
            this.$refs[modalName].openModal();
        },
        toggleIsExpanded() {
            this.isExpanded = !this.isExpanded;
        },
        getDisplayed(amount) {
            return this.isUnverified
                ? VERIFYING_COVERAGE
                : formatAmountInDollars(amount);
        },
        getCartItem(label, lineItems, cartItemTypeString, partType) {
            let cartItem = null;

            if (lineItems && lineItems.length > 0) {
                cartItem = {
                    name: label,
                    cartItemType: cartItemTypeString,
                    partType,
                    subTotal: getPriceOfLineItems(lineItems, false),
                    salesTax: getTaxOfLineItems(lineItems)
                };
            }

            return cartItem;
        },
        getCartItemForVapsPart(partType) {
            const label = this.getCmsContentForVapsType(partType);
            const lineItems = this.lineItems.vaps
                ?.filter((vapsLineItem) => vapsLineItem.partType === partType) ?? [];
            return this.getCartItem(label, lineItems, cartItemType.VAP, partType);
        },
        removeVap(partType) {
            const newVaps = useMainStore().lineItems.vaps?.filter((vap) => vap?.partType !== partType) ?? [];
            useMainStore().updateVaps(newVaps);
        },
        getCmsContentForVapsType(vapsPartType) {
            const vapsItemDescriptions = this.getCmsContent(
                this.widget.vapsItemDescriptions,
                widgetFields.INPUT_QUESTION_WIDGET.ANSWERS
            );

            if (!vapsItemDescriptions) {
                return '';
            }

            const vapsTypeDescription = vapsItemDescriptions?.find((entry) => entry?.Name === vapsPartType);
            return vapsTypeDescription?.Text ?? '';
        },
        formatAmountInDollars
    }
};
</script>

<style lang="scss" scoped>
@import "@/styles/ux-variables-svg-strings.scss";

.force-no-top-margin {
    margin-top: 0 !important;
}

.color-black {
    color: $black;
}

.color-green {
    color: $green;
}

.color-darker-gray {
    color: $darker-gray;
}

.cart-table {
    max-height: 0;
    transition: all 350ms ease-in;
    overflow: hidden;
    visibility: hidden;
    margin-top: 1rem;

    :deep(a) {
        padding-bottom: 0 !important;
        line-height: 1.625 !important;
        text-underline-offset: auto !important;
    }

    .non-packaged-cart-item:nth-child(odd){
        background-color: $gray-100;
    }

    .cart-item {
        padding: 0.25rem 1.5rem;
    }

    .cart-gray {
        background-color: $gray-100;
    }

    .cart-footer {
        border-top: 1px solid $green;
    }

    .subtotal-and-tax {
        background-color: $green-150;
        font-weight: $font-weight-bold;
        color: $black;
        padding: 0.25rem 1.5rem;
    }

    .bottom-amount-due {
        color: $white;
        background-color: $green;
        padding: 0.5rem 1.5rem;
    }
}

:deep(.modal-content a.external-text) {
    text-underline-offset: 0.25rem;
    line-height: 2;
    padding: 0 0 0.25rem 0;
    font-weight: 500;
    max-width: -webkit-fit-content;
    max-width: -moz-fit-content;
    max-width: fit-content;
}

:deep(#RecycleModal h5) {
    text-align: center;
}

.cart-header {
    &.cart-toggle {
        font-weight: $font-weight-bold;

        &:after {
            content: "";
            transition: all 0.5s ease;
            background-image: url($svg-payment-method-review-toggle);
            background-repeat: no-repeat;
            background-position: right center;
            width: 1rem;
            height: 0.5625rem;
            display: inline-flex;
            position: relative;
            right: 0.75rem;
            margin: 0.5rem 0 0.5rem 1rem;
            cursor: pointer;
        }
        &.expanded:after {
            transform: rotate(180deg);
        }
        a {
            text-decoration: none;
        }
    }
    &.expanded + .cart-table {
        max-height: 50rem;
        transition: all 150ms ease-in;
        overflow: hidden;
        visibility: visible;
    }
}

:deep(#recycle-fee-label a){
    line-height: initial;
}
</style>
