<template>
    <view class="cart" :style="[cartPaddingTop]">
        <tui-skeleton v-if="isRequest" loadingType="2"></tui-skeleton>
        <header-cart
            :systeminfo="systeminfo"
            :navbar-data="nvabarData"
            :headerBtnPosi="headerBtnPosi"
            :page="1"
        ></header-cart>
        <template v-if="!isEmpty">
            <template v-if="!isshowDelbtn">
                <view :class="{ fixed: cartTopFixed }" :style="[cartTop]">
                    <!-- 商品统计 / 批量删除商品 -->
                    <view class="cart-top">
                        <view class="count">共{{ kindCount }}件商品</view>
                        <view class="btn" @click="showDelManager">删除</view>
                    </view>
                    <!-- TODO -->
                    <view class="receive-coupon" v-if="showReceiveCouponButton">
                        <view class="tip-text">{{ couponTipText }}</view>
                        <view class="btn" @click="receiveCoupon">领券</view>
                    </view>
                </view>
            </template>
            <!-- 购物车列表 -->
            <template v-for="(cart, index) in goodsList">
                <cm-cart-product
                    class="product-list"
                    :listType="listType"
                    :key="index"
                    :data="cart"
                    vkey="productList"
                    @chooseAll="chooseAllProduct"
                    @chooseOne="chooseOneProduct"
                ></cm-cart-product>
            </template>
            <!-- 失效商品列表 -->
            <cm-cart-product
                class="product-list"
                :key="index"
                :data="failureList"
                :listType="failureListType"
                @chooseOne="chooseFailureProduct"
                v-if="failureList.length > 0"
            ></cm-cart-product>

            <!-- 底部按钮 -->
            <view class="footer" :style="[footerBottom]">
                <view class="radio" @click="chooseAll">
                    <text class="iconfont" :class="[isCheckAll ? 'icon-xuanze' : 'icon-weixuanze']"></text>
                    <text class="tip">全选</text>
                </view>
                <template v-if="!isshowDelbtn">
                    <view class="center">
                        <view class="row">
                            <text>总价：</text> <text class="total-price">
                                <text>￥{{ finallyPrice | formatPrice }}</text>
                                <text class="delete" v-if="allPrice > finallyPrice">￥{{ allPrice | formatPrice }}</text>
                            </text>
                        </view>
                        <!-- TODO -->
                        <view class="row" v-if="currentCouponIndex > -1 && currentCoupon">
                            <text>共减</text>
                            <text class="discounted-price">￥{{ currentCoupon.couponAmount | formatPrice }}</text>
                            <text @click="showDiscountedDetail">优惠明细</text>
                            <text
                                class="iconfont"
                                :class="showDitail ? 'tui-icon-arrowdown' : 'tui-icon-arrowup'"
                            ></text>
                        </view>
                    </view>
                    <view class="submit" @click="toConfirmation">去结算({{ allCount }})</view>
                </template>
                <view v-else class="footer-del">
                    <view class="btn btn-cancel" @tap.stop="hideDelManage">取消</view>
                    <view class="btn btn-confirm" @tap.stop="deleteList">删除</view>
                </view>
            </view>
        </template>
        <view class="empty" v-else>
            <cm-empty :image="StaticUrl + 'icon-empty-cart.png'" message="购物车空空的，快去逛逛吧~"></cm-empty>
        </view>
        <!-- 优惠券列表 TODO-->
        <cm-coupon-list
            title="优惠券"
            listType="search"
            :couponList="couponList"
            :visible="couponVisible"
            :btnUseType="2"
            @close="closeCouponList"
            @tabClick="couponListTabClick"
            @couponClick="couponClick"
            :tabs="couponListTabs"
        ></cm-coupon-list>
        <!-- 优惠明细 -->
        <cm-drawer
            title="优惠明细"
            :visible="showDitail"
            position="bottom"
            :offset="120"
            @close="showDitail = false"
            zIndex="99"
        >
            <template>
                <view class="discounted-ditail">
                    <view class="row">
                        <text>商品总额</text> <text>￥{{ allPrice | formatPrice }}</text>
                    </view>
                    <view class="row">
                        <text>促销满减</text> <text class="red">-￥{{ discountedPrice | formatPrice }}</text>
                    </view>
                    <view class="row" v-if="currentCouponIndex > -1 && currentCoupon">
                        <text>优惠券</text> <text class="red">-￥{{ currentCoupon.couponAmount | formatPrice }}</text>
                    </view>
                    <view class="row total">
                        <text>总计</text> 
                        <text>￥{{ finallyPrice | formatPrice }}</text>
                        <!-- <text class="delete">9999.99</text> -->
                    </view>
                    <view class="tip"> 实际订单金额以结算页为准 </view>
                </view>
            </template>
        </cm-drawer>
        <!-- 操作弹窗 -->
        <tui-modal
            :show="modal"
            @click="handleClick"
            @cancel="hideModal"
            :content="contentModalText"
            color="#333"
            :size="32"
            shape="circle"
            :maskClosable="false"
        ></tui-modal>
    </view>
</template>

<script>
import authorize from '@/common/authorize.js'
import CmCouponList from '@/components/cm-module/cm-coupon-list/cm-coupon-list'
import CmDrawer from '@/components/cm-module/cm-drawer/cm-drawer.vue'
import CmCartProduct from '@/components/cm-module/cm-cart-product/cm-cart-product.vue'
import HeaderCart from '@/components/cm-module/headerNavbar/header-cart.vue'
import CmEmpty from '@/components/cm-module/cm-empty/cm-empty.vue'
import {
    fetchSelectedProducts,
    findCouponBySelected,
    canUseCoupon,
    getCountPrice,
    couponSort,
} from '@/common/couponUtil.js'

import { mapGetters, mapActions, mapMutations } from 'vuex'

export default {
    components: {
        CmCouponList,
        CmDrawer,
        CmCartProduct,
        HeaderCart,
        CmEmpty
    },
    data() {
        return {
            nvabarData: {
                //顶部自定义导航
                showCapsule: 1, // 是否显示左上角图标  1表示显示  0表示不显示,
                showSearch: 0,
                title: '购物车' // 导航栏 中间的标题
            },
            headerBtnPosi: this.setHeaderBtnPosi(), //获取设备顶部胶囊高度
            systeminfo: this.setSysteminfo(),
            StaticUrl: this.$Static,
            CustomBar: this.CustomBar, // 顶部导航栏高度
            popupShow: false,
            handlerPros: {}, //监听单挑促销商品
            isCheckAll: false, //是否全选
            allPrice: 0, //所有价格
            totalOriginalPrice: 0, //所有原价价
            reducedPrice: 0, //满减
            isshowDelbtn: false,
            scrollHeight: 'auto',
            hasNextPage: false,
            modal: false,
            contentModalText: '',
            deleteType: 0,
            couponVisible: false,
            showDitail: false,
            listType: 'normal',
            failureListType: 'expired',
            scrollTop: 0,
            isRequest: true,

            currentCouponIndex: -1,
            selectedPoducts: [], //已勾选商品列表
            receiveCouponList: [], // 已领取优惠券
            ableCouponList: [], // 可领取优惠券
            canUseCouponList: [], // 当前选中商品可使用的优惠券
            currentTabIndex: 0
        }
    },
    onLoad() {
        this.setScrollHeight()
    },
    computed: {
        ...mapGetters([
            'hasLogin',
            'isIphoneX',
            'isEmpty',
            'goodsList',
            'failureList',
            'kindCount',
            'userId',
            'cartIds',
            'productIds'
        ]),
        //被选中的产品数量
        allCount() {
            return this.cartIds.length
        },
        footerBottom() {
            return {
                bottom: this.isIphoneX ? '0' : ''
            }
        },
        cartTopFixed() {
            return this.scrollTop > 0 && !this.isshowDelbtn
        },
        // 购物车顶部删除按钮top
        cartTop() {
            return {
                top: this.CustomBar + 'px'
            }
        },
        // 购物车页面padding
        cartPaddingTop() {
            let paddingTop = this.CustomBar
            let paddingBottom = 100
            if (this.cartTopFixed) {
                if(this.showReceiveCouponButton){
                    paddingTop += 85
                }else{
                    paddingTop += 40
                }
            }
            if (this.isIphoneX) {
                paddingBottom += 40
            }
            return {
                paddingTop: paddingTop + 'px',
                paddingBottom: paddingBottom + 'rpx'
            }
        },
        currentCoupon() {
            return this.canUseCouponList[this.currentCouponIndex] || null
        },
        nextCoupon() {
            if (this.currentCouponIndex <= 0) {
                return this.currentCoupon
            } else {
                return this.canUseCouponList[this.currentCouponIndex - 1]
            }
        },
        discountedPrice() {
            return 0
        },
        finallyPrice() {
            if (this.currentCoupon) {
                const finallyPrice = this.allPrice - this.discountedPrice - this.currentCoupon.couponAmount
                return finallyPrice < 0 ? 0 : finallyPrice
            }
            return this.allPrice - this.discountedPrice
        },
        couponTipText() {
            if (this.currentCouponIndex <= -1) return ''
            if (this.currentCoupon === this.nextCoupon) {
                if (this.nextCoupon.noThresholdFlag === 1) {
                    return `已享“减${this.currentCoupon.couponAmount}元”优惠券`
                }
                return `已享“满${this.currentCoupon.touchPrice}元减${this.currentCoupon.couponAmount}元”优惠券`
            }
            return `还差￥
                ${(this.nextCoupon.touchPrice - getCountPrice(this.selectedPoducts, this.nextCoupon)).toFixed(2)}
                元可用“满${this.nextCoupon.touchPrice}元减${this.nextCoupon.couponAmount}元”优惠券`
        },
        couponList() {
            if (this.currentTabIndex === 0) {
                return couponSort(this.receiveCouponList)
            } else {
                return couponSort(this.ableCouponList)
            }
        },
        couponListTabs() {
            const tabs = []
            const receiveCount = this.receiveCouponList.length
            const ableCouponCount = this.ableCouponList.length
            if (receiveCount > 0) {
                tabs.push({ name: `已领取优惠券(${receiveCount})` })
            } else {
                tabs.push({ name: '已领取优惠券' })
            }
            if (ableCouponCount > 0) {
                tabs.push({ name: `可领取优惠券(${ableCouponCount})` })
            } else {
                tabs.push({ name: '可领取优惠券' })
            }
            return tabs
        },
        showReceiveCouponButton(){
            // return this.ableCouponList.length > 0 || this.receiveCouponList.length > 0
            return true
        }
    },
    filters: {
        totalprice(val, count) {
            //单件商品的价格 × 数量
            return (val * count).toFixed(2)
        }
    },
    watch: {
        //深度监听所有数据，每次改变重新计算总价和总数
        goodsList: {
            deep: true,
            handler(val, oldval) {
                this.totalPeice()
                this.resetCouponUtil()
            }
        },
        isshowDelbtn(val) {
            if (val) {
                this.failureListType = 'expired delete'
                this.listType = 'normal delete'
            } else {
                this.failureListType = 'expired'
                this.listType = 'normal'
            }
        }
    },
    //下拉刷新
    onPullDownRefresh() {
        this.initCart().finally(() => {
            setTimeout(() => {
                uni.stopPullDownRefresh()
            }, 500)
        })
    },
    onShow() {
        if (this.hasLogin) {
            this.initData()
        } else {
            this.$api.redirectTo('/pages/authorize/login')
        }
    },
    onPageScroll(e) {
        this.scrollTop = e.scrollTop
    },
    methods: {
        ...mapActions('cart', ['initCart', 'removeFromCart']),
        ...mapMutations('cart', ['selectAllProduct', 'saveCartIds', 'selectAllFailure', 'saveProductIds']),
        initData() {
            this.saveCartIds([]) // 清空已选项
            this.saveProductIds([]) // 清空已选项
            this.isCheckAll = false
            this.isshowDelbtn = false
            this.initCart().finally(() => {
                this.isRequest = false
                this.getCouponList()
            })
        },
        // 获取优惠券列表
        getCouponList() {
            const productIds = []
            this.goodsList.forEach(shop => shop.productList.forEach(product => productIds.push(product.productId)))
            this.CouponService.GetCouponByProductIds({ userId: this.userId, productIds: productIds.join(',') }).then(
                res => {
                    this.receiveCouponList = res.data.receiveCouponList // 去掉重复的已领取优惠券
                    this.ableCouponList = res.data.ableCouponList
                    this.resetCouponUtil()
                }
            )
        },
        resetCouponUtil() {
            this.selectedPoducts = fetchSelectedProducts(this.goodsList)
            this.canUseCouponList = findCouponBySelected(this.productIds, this.receiveCouponList)
            this.currentCouponIndex = canUseCoupon(0, this.productIds, this.canUseCouponList, this.selectedPoducts)
        },
        // 领取优惠券弹窗
        receiveCoupon() {
            this.couponVisible = true
            this.getCouponList()
        },
        couponClick() {
            // 领取优惠券
            if (this.currentTabIndex === 1) {
                this.getCouponList()
            } else {
                this.couponVisible = false
            }
        },
        couponListTabClick(index) {
            this.currentTabIndex = index
        },
        // 关闭优惠券弹窗
        closeCouponList() {
            this.couponVisible = false
        },
        // 活动价弹窗
        clickPopupShow(pros, type) {
            if (pros.ladderList.length > 0) {
                this.popupShow = true
                this.handlerPros = pros
            }
        },
        // 优惠明细
        showDiscountedDetail() {
            this.showDitail = true
        },
        // 勾选单个失效商品
        chooseFailureProduct() {
            this.isSelectAll()
        },
        // 勾选供应商下所有商品
        chooseAllProduct() {
            this.isSelectAll()
        },
        // 勾选单核商品
        chooseOneProduct() {
            this.isSelectAll()
        },
        // 勾选全部商品
        chooseAll() {
            this.isCheckAll = !this.isCheckAll
            // 勾选所有有效商品
            this.selectAllProduct(this.isCheckAll)
            // 勾选所有失效商品
            if (this.isshowDelbtn) {
                this.selectAllFailure(this.isCheckAll)
            }
            this.isSelectAll()
        },
        // 判断是否全选商品
        isSelectAll() {
            // 是否勾选全部正常商品
            this.isCheckAll = this.goodsList.every(shop => shop.checked)
            if (this.isshowDelbtn) {
                this.isCheckAll = this.isCheckAll && this.failureList.every(product => product.productsChecked)
            }
            this.getCheckedProductId()
        },
        // 获取勾选商品的id
        getCheckedProductId() {
            const cartIds = []
            const productIds = []
            // 获取所有有效商品cartId
            this.goodsList.forEach(shop => {
                const ids = shop.productList.reduce((cartIds, prod) => {
                    if (prod.productsChecked) {
                        cartIds.push(prod.cartId)
                        productIds.push(prod.productId)
                    }
                    return cartIds
                }, [])
                cartIds.push(...ids)
            })
            // 获取所有失效商品cartId
            if (this.isshowDelbtn) {
                const ids = this.failureList.reduce((cartIds, prod) => {
                    if (prod.productsChecked) cartIds.push(prod.cartId)
                    return cartIds
                }, [])
                cartIds.push(...ids)
            }
            this.saveProductIds(productIds) // 保存已选商品
            this.saveCartIds(cartIds)
            this.resetCouponUtil()
        },
        //计算总价格,每次调用此方法，将初始值为0，遍历价格并累加
        totalPeice() {
            const priceObj = this.goodsList.reduce(
                (priceObj, shop) => {
                    shop.productList.forEach(prod => {
                        if (prod.productsChecked) {
                            priceObj.totalOriginalPrice += prod.price * prod.productCount
                            // 单品满减
                            if (prod.promotion && prod.promotion.type * 1 === 1 && prod.promotion.mode * 1 === 2) {
                                // 单品满减-重新计算供应商总价/满减金额
                                if (prod.price * prod.productCount >= prod.promotion.touchPrice) {
                                    priceObj.reducedPrice += prod.promotion.reducedPrice
                                }
                            }
                        }
                    })
                    priceObj.allPrice = priceObj.totalOriginalPrice - priceObj.reducedPrice
                    return priceObj
                },
                {
                    totalOriginalPrice: 0,
                    reducedPrice: 0,
                    allPrice: 0
                }
            )
            this.allPrice = priceObj.allPrice
        },
        //显示删除商品管理
        showDelManager() {
            this.isshowDelbtn = true
        },
        //隐藏删除商品管理
        hideDelManage() {
            this.selectAllFailure(false)
            this.isSelectAll()
            this.isshowDelbtn = false
        },

        //删除购物车商品
        deleteList() {
            if (this.cartIds.length <= 0) {
                return this.$util.msg('请选择要删除的商品~', 2000)
            } else {
                this.modal = true
                this.contentModalText = '确定删除选中的商品吗？'
            }
        },
        //从购物车移除商品
        handleClick(e) {
            if (e.index !== 1) return (this.modal = false)
            // 删除所有勾选的商品
            this.removeFromCart().finally(() => {
                this.isshowDelbtn = false
            })
            this.modal = false
        },
        //跳转确认订单页面
        toConfirmation() {
            if (this.cartIds.length <= 0) {
                return this.$util.msg('请先选择结算商品~', 2000)
            }
            let cartPramsData = {
                allPrice: this.allPrice,
                allCount: this.allCount,
                cartIds: this.cartIds.join(','),
                productIds: this.productIds.join(','),
                productCount: ''
            }
            uni.setStorageSync('commitCartPramsData', cartPramsData)
            this.$api.navigateTo('/pages/order/order-create')
        },
        hideModal() {
            this.modal = false
        },
        navToListPage(item) {
            this.$api.navigateTo(`/pages/goods/product?productId=${item.productId}`)
        },
        // 窗口高度-footer高度
        setScrollHeight() {
            const { windowHeight, pixelRatio } = uni.getSystemInfoSync()
            setTimeout(() => {
                const query = uni.createSelectorQuery().in(this)
                query.selectAll('.footer').boundingClientRect()
                query.exec(res => {
                    this.windowHeight = windowHeight
                    if (res[0][0]) {
                        this.scrollHeight = windowHeight - res[0][0].height
                    }
                })
            }, 500)
        },
        setHeaderBtnPosi() {
            // 获得胶囊按钮位置信息
            let headerBtnPosi = uni.getMenuButtonBoundingClientRect()
            return headerBtnPosi
        },
        setSysteminfo() {
            let systeminfo
            uni.getSystemInfo({
                // 获取设备信息
                success: res => {
                    systeminfo = res
                }
            })
            return systeminfo
        }
    }
}
</script>

<style lang="scss" scoped>
.cart {
    background: #f7f7f7;
    min-height: 100%;
    box-sizing: border-box;
    &.hasPaddingTop {
        padding-top: 80rpx;
    }
    
    .fixed {
        position: fixed;
        z-index: 9999;
    }
    
    .cart-top {
        flex: 0;
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 0 24rpx;
        width: 750rpx;
        height: 80rpx;
        background: #f7f7f7;
        box-sizing: border-box;
        
        .count {
            font-size: 30rpx;
            color: #333333;
        }
        .btn {
            display: flex;
            justify-content: center;
            align-items: center;
            width: 88rpx;
            height: 42rpx;
            background: #fff8fd;
            border: 1rpx solid #ff457b;
            border-radius: 24rpx;
            font-size: 26rpx;
            color: #ff457b;
        }
    }
    .receive-coupon {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 24rpx;
        background: #fff;
        .tip-text {
            width: 560rpx;
            font-size: 26rpx;
            color: #ff457b;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        .btn {
            width: 88rpx;
            height: 42rpx;
            background: linear-gradient(270deg, #f83c6c 0%, #fc32b4 100%);
            border-radius: 28rpx;
            font-size: 26rpx;
            color: #ffffff;
            text-align: center;
            line-height: 42rpx;
        }
    }
    .footer {
        position: fixed;
        bottom: -40rpx;
        left: 0;
        z-index: 899;
        display: flex;
        justify-content: space-between;
        align-items: center;
        width: 100%;
        height: 140rpx;
        box-sizing: border-box;
        padding: 0 24rpx 40rpx;
        border-top: 1rpx solid #eee;
        background: #ffffff;
        .radio {
            font-size: 36rpx;
            color: #b2b2b2;
            .icon-xuanze {
                color: #f83c6c;
            }
            .tip {
                font-size: 30rpx;
                color: #333333;
                margin-left: 6rpx;
            }
        }
        .row {
            &:nth-child(1) {
                font-size: 26rpx;
                color: #333333;
                .total-price {
                    color: #ff457b;
                    .delete{
                        font-size: 20rpx;
                        color: #999999;
                        text-decoration: line-through;
                        font-weight: normal;
                        margin-left: 10rpx;
                    }
                }
            }
            &:nth-child(2) {
                margin-top: 6rpx;
                font-size: 24rpx;
                color: #ff457b;
            }
            .discounted-price {
                margin-right: 32rpx;
            }
        }
        .submit {
            width: 210rpx;
            height: 80rpx;
            background: linear-gradient(90deg, #fc32b4 0%, #f83c6c 100%);
            border-radius: 40rpx;
            font-size: 30rpx;
            color: #ffffff;
            text-align: center;
            line-height: 80rpx;
        }
        .footer-del {
            width: 420rpx;
            height: 100rpx;
            position: absolute;
            padding-left: 200rpx;
            background: #ffffff;
            right: 0;
            top: 0;
            z-index: 1000;
            box-sizing: border-box;
            padding: 10rpx 0;
            display: flex;
            &.show {
                animation: showDelbtn 0s linear both;
            }
            &.none {
                animation: hideDelbtn 0s linear both;
            }
            .btn {
                flex: 1;
                margin: 0 8rpx;
                height: 100%;
                line-height: 80rpx;
                font-size: $font-size-28;
                color: #ffffff;
                text-align: center;
                float: left;
                border-radius: 40rpx;
            }
            .btn.btn-cancel {
                background: #f7f7f7;
                color: #b2b2b2;
            }
            .btn.btn-confirm {
                background: $btn-confirm;
                color: #ffffff;
            }
            @keyframes showDelbtn {
                0% {
                    transform: translateX(0);
                }
                100% {
                    transform: translateX(-100%);
                }
            }
            @keyframes hideDelbtn {
                0% {
                    transform: translateX(-100%);
                }
                100% {
                    transform: translateX(0);
                }
            }
        }
    }
    .discounted-ditail {
        padding: 52rpx 8rpx 0;
        .row {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 12rpx 0;
            text {
                font-size: 30rpx;
                color: #333333;
                &.red {
                    color: #f94b4b;
                }
            }
            &.total {
                font-size: 30rpx;
                font-weight: 600;
                .delete{
                    font-size: 20rpx;
                    color: #999999;
                    text-decoration: line-through;
                    font-weight: normal;
                    margin-left: 10rpx;
                }
            }
        }
        .tip {
            padding: 12rpx 0;
            font-size: 26rpx;
            color: #999999;
        }
    }
    .empty {
        height: 80vh;
    }
}
</style>
