<template>
	<view class="container">
		<!-- 页面顶部 -->
		<UiPageHeader :back="type == 'inner'" :class="`head__${type}`">
			<template slot="custom">
				<view class="head--title">
					<text>购物车</text>
					<text v-if="list.length">({{list.length}})</text>
				</view>
				<template v-if="list.length">
					<view v-if="mode == 'normal'" class="head--edit" @click="handleToggleMode">编辑</view>
					<view v-else class="head--finish" @click="handleToggleMode">完成</view>
				</template>
			</template>
		</UiPageHeader>

		<u-loadmore v-if="isLoading" status="loading" />
		<!-- 购物车数据为空 -->
		<BsEmpty v-if="!list.length && !isLoading" class="empty"
			tips="去挑点喜欢的好货吧~">
			<image slot="icon" class="empty--icon" src="@/static/goods/cart.png"></image>
			<view slot="btn" class="empty--btn" @click="$Router.pushTab('/')">去逛逛</view>
		</BsEmpty>

		<!-- 购物车商品列表 -->
		<template v-else >
			<UiWhiteBox class="cart-item" v-for="(item, index) in list" :key="index" >
				<label class="cart-item--radio" @click.stop="handleCheckItem(item.id)">
					<radio class="radio" color="#FF875B" 
						:checked="checkedIds.length ? checkedIds.includes(item.id) : false" />
				</label>
				<image class="cart-item--image" :src="item.product.mainPicture" mode="scaleToFill" 
					@click="$Router.push(`/goodsDetail?id=${item.productId}`)"></image>
				<view class="cart-item--content" @click="$Router.push(`/goodsDetail?id=${item.productId}`)">
					<view class="cart-item--title">{{ item.product.name }}</view>
					<view class="cart-item--props">{{ item.productSku.name }}</view>
					<view class="cart-item--footer">
						<UiMoney class="cart-item--price" :money="item.productSku.sellPrice" prefix></UiMoney>
						<view class="cart-item--stepper">
							<u-number-box :min="1" button-size="40rpx" bgColor="#F5F6FA" 
								:value="item.number" :max="item.maxBuyNum" @change="onChangeStepper($event, item)" >
								<text slot="minus" class="cart-item--stepper-icon">-</text>
								<text slot="plus" class="cart-item--stepper-icon">+</text>
							</u-number-box>
						</view>
					</view>
				</view>
			</UiWhiteBox>
		</template>
		
		<template v-if="!isLoading">
			<view class="title">为您推荐</view>
			<!-- <BsChoiceGoods></BsChoiceGoods> -->
		</template>

		<!-- 底部操作栏 -->
		<view v-if="list.length" :class="`footer footer__${type}`">
			<label class="all-radio" @click="handleCheckAll">
				<radio class="radio" color="#FF875B"
					:checked="checkedIds.length > 0 && checkedIds.length === list.length" />
				<text>全选</text>
			</label>
			<view class="total-info">
				<text>合计：</text>
				<UiMoney class="goods-price" :money="totalPrice" prefix/>
			</view>
			<view class="cart-action">
				<UiButton v-if="mode == 'edit'" size="max" :disable="!checkedIds.length" @click="handleDelete">删除</UiButton>
				<UiButton v-else type="gradual" size="max" :disable="!checkedIds.length" @click="handleOrder">去结算({{list.length}})</UiButton>
			</view>
		</view>
	</view>
</template>

<script>
import { Debounce } from '@/common/utils';
import BsEmpty from '@/components/BsEmpty.vue';
import BsChoiceGoods from '@/components/BsChoiceGoods.vue';
import UiPageHeader from '@/components/UiPageHeader.vue';
import {ApiGetCartList, ApiPutCartNum, ApiDeleteCartGoods} from '@/common/api/cart';
import UiMoney from '../../../components/UiMoney.vue';
import UiButton from '../../../components/UiButton.vue';
import UiWhiteBox from '../../../components/UiWhiteBox.vue';

const CartIdsIndex = 'CartIds';

export default {
    components: {
        BsEmpty,
        BsChoiceGoods,
        UiPageHeader,
        UiMoney,
        UiButton,
        UiWhiteBox
	},
	props : {
		type : {
			type : String,
			// 页面类型 inner内页 tabBar tabBar页面
			default : 'inner' 
		}
	},
    data() {
        return {
            // 正在加载
            isLoading: true,
            // 当前模式: normal正常 edit编辑
            mode: 'normal',
            // 购物车商品列表
            list: [],
            // 购物车商品总数量
            total: null,
            // 选中的商品ID记录
            checkedIds: [],
        }
    },
    watch: {
        // 监听选中的商品
        checkedIds: {
            handler(val) {
				// 记录到缓存中
                uni.setStorageSync(CartIdsIndex, val)
            },
            immediate: false
        }
    },
	computed : {
		totalPrice(){
			const checkedList = this.list.filter(item => this.checkedIds.includes(item.id));
			let tempPrice = 0;
			checkedList.forEach(item => {
				// 商品单价, 为了方便计算先转换单位为分 (整数)
                const unitPrice = item.productSku.sellPrice * 100
                tempPrice += unitPrice * item.number
			});
            return (tempPrice / 100).toFixed(2)

		}
	},
    methods: {
		/**
		 * 组件缺少onShow onLoad生命周期，提供一个open方法给页面及组件使用
		 */
		open(options) {
			
			// 获取购物车商品列表
			this.getCartList();
			this.isLoading = false;
			// 获取缓存中的选中记录
			this.checkedIds = uni.getStorageSync(CartIdsIndex) || [];
		},

        /**
		 * 获取购物车商品列表
		 */
        async getCartList() {
			this.isLoading = true;
			// APP有Bug到拦截器里跳转不了 待研究问题
			if(!this.$store.state.token){
				uni.redirectTo({url: '/login'});
			}
			const {error, result} = await ApiGetCartList();
			if(error){
				uni.$u.toast(error.message);
				return false;
			}
			this.list = result.map(item => {
				const singleBuyLimit = item.product.singleBuyLimit;
				const stock = item.productSku.stock;
				const maxBuyNum =  singleBuyLimit ? Math.min(singleBuyLimit, stock || 1) : stock
				return {
					...item,
					maxBuyNum
				}
			});
			this.onClearInvalidId();
			this.isLoading = false;
        },

        /**
		 * 清除checkedIds中无效的ID
		 */
        onClearInvalidId() {
			this.checkedIds = this.checkedIds.filter(i => this.list.findIndex(item => item.id === i) > -1);
        },

        /**
		 * 切换当前模式
		 */
        handleToggleMode() {
            this.mode = this.mode == 'normal' ? 'edit' : 'normal'
        },

        /**
		 * 监听步进器更改事件
		 */
        onChangeStepper({ value }, item) {
			
            // 这里是组织首次启动时的执行
            if (item.number == value) {
				uni.$u.toast('数量不能再少了');
				return false
			}
            // 记录一个节流函数句柄
            if (!item.debounceHandle) {
				item.oldValue = item.number
                item.debounceHandle = Debounce(this.updateCartNum, 500)
            }
            // 更新商品数量
            item.number = value
            // 提交更新购物车数量 (节流)
            item.debounceHandle(item, item.oldValue, value);
        },

        /**
		 * 提交更新购物车数量
		 */
        async updateCartNum(item, oldValue, newValue) {
			const {error, result} = await ApiPutCartNum({
				id : item.id,
				number : item.number
			});
			if(error){
				this.$toast(error.message);
				item.number = item.sku;
				return false;
			}
			if(result.isBeyondMaxLimit){
				uni.$u.toast('数量超出范围');
				item.number = result.canSetShoppingCartNumber;
				return false;
			}
        },


        /**
		 * 选中商品
		 */
        handleCheckItem(cartId) {
            const { checkedIds } = this
            const index = checkedIds.findIndex(id => id === cartId)
            index < 0 ? checkedIds.push(cartId) : checkedIds.splice(index, 1)
        },

        /**
		 * 全选事件
		 */
        handleCheckAll() {
            const { checkedIds, list } = this
            this.checkedIds = checkedIds.length === list.length ? [] : list.map(item => item.id)
        },

        /**
		 * 结算选中的商品
		 */
        handleOrder() {
            const ids = this.checkedIds;
            if (ids.length) {
                this.$Router.push({
					path : '/orderSubmit', 
					query : { 
						mode: 'cart', 
						ids:ids.join(',') 
					}
				})
            }
        },

        /**
		 * 删除选中的商品
		 */
        handleDelete() {
			const ids = this.checkedIds;
            if (!ids.length) {
                return false
			}
			
			this.$msb.confirm({
				content : '您确定要删除该商品吗？',
				confirm : async ()=>{
					const {error} = await ApiDeleteCartGoods({idList : ids.join(',')});
					if(error){
						uni.$u.toast(error.message);
						return false;
					}
					this.list = this.list.filter(item => !ids.includes(item.id));
					this.checkedIds = [];
					this.onClearInvalidId();
				}
			})
        }

    }
}
</script>

<style lang="scss">
  page {
	background: $color-grey1;
	padding-bottom: 240rpx;
	
  }
</style>
<style lang="scss" scoped>
  // 页面顶部
.head {
    height: 88rpx;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 30rpx;
    background-color: $color-grey0;
    position: sticky;
    top: var(--window-top);
	z-index: 999;
	&--title text{
		font-size: 36rpx;
		font-weight: bold;
	}
	&--totla{
		font-size: 36rpx;
		color: $color-grey6;
	}
	&--edit,&--finish{
		font-size: $font-size-base;
		color: $color-grey4;
	}
	&--finish{
		color: $color-yellow4;
	}
	&__tabBar{
		justify-content: center;
		.head--edit,.head--finish{
			position: absolute;
			right: 30rpx;
		}
	}

}

// 购物车列
.cart-item {
	width: 690rpx;
    display: flex;
    align-items: center;
    padding: 50rpx 40rpx 40rpx 24rpx;
    margin: 0 auto 20rpx;
    &--radio {
		width: 56rpx;
		height: 80rpx;
		line-height: 80rpx;
		margin-right: 10rpx;
		text-align: center;
    }
    &--image {
		width: 170rpx;
		height: 170rpx;
		display: block;
		border-radius: 12rpx;
    }

    &--content {
		flex: 1;
		padding-left: 24rpx;
	}

    &--title {
		font-size: $font-size-base;
		line-height: 36rpx;
		font-weight: bold;
		max-height: 76rpx;
		overflow: hidden;
		text-overflow: ellipsis;
		display:-webkit-box; 
		-webkit-box-orient:vertical;
		-webkit-line-clamp:2; 
		
	}

	&--props {
        margin-top: 14rpx;
        height: 40rpx;
        color: $color-grey4;
        font-size: $font-size-sm;
        overflow: hidden;

        &-item {
          display: inline-block;
          margin-right: 14rpx;
        }
	}
	&--footer {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-top: 20rpx;
	}
	&--stepper-icon{
		font-size: 38rpx;
		color: $color-grey3;
		margin:0 14rpx;
	}
	&--stepper-input{
		height:40rpx;
		margin: 0 14rpx;
	}
}

// 空数据按钮
.empty{
	background: $color-grey0;
	&--btn {
		width: 220rpx;
		margin: 0 auto 10rpx auto;
		font-size: $font-size-base;
		height: 64rpx;
		line-height: 64rpx;
		text-align: center;
		color: $color-grey6;
		border-radius: 50rpx;
		border: 1px solid rgb(192, 185, 185);
	}
	&--icon{
		width: 304rpx;
		height: 192rpx;
	}
}

.title{
	font-size: $font-size-lg;
	text-align: center;
	margin: 51rpx auto 30rpx auto;
	display: flex;
	align-items: center;
	justify-content: space-between;
	width: 500rpx;
	&::after,&::before{
		display: inline-block;
		content: '';
		width: 160rpx;
		height: 2rpx;
		background: linear-gradient(90deg, $color-grey3 0%, rgba(204, 204, 204, 0) 100%);
		
	}
	&::before{
		
		background: linear-gradient(270deg, $color-grey3 0%, rgba(204, 204, 204, 0) 100%);
	}
}

// 底部操作栏
.footer {
    display: flex;
    align-items: center;
    height: 140rpx;
    background: $color-grey0;
    padding: 0 30rpx;
	position: fixed;
	bottom: 120rpx;
    left: 0;
    right: 0;
	z-index: 11;
	margin-bottom: constant(safe-area-inset-bottom);
   	margin-bottom: env(safe-area-inset-bottom);
	&__inner{
		bottom: 0;
	}
    .all-radio {
      width: 140rpx;
      display: flex;
	  align-items: center;
	  text{
		  color: $color-grey5;
		  font-size: $font-size-base;
	  }

      .radio {
		  margin-right: 5rpx;
      }
    }

    .total-info {
      flex: 1;
      display: flex;
      align-items: center;
      justify-content: flex-end;
	  padding-right: 30rpx;
	  text{
		font-size: $font-size-base;
		color: $color-grey5;

	  }
    }


}
/deep/{
	.cart-item--price{
		text{
			font-size: $font-size-lg;
			color: $color-yellow4;
			font-weight: bold;
		}
		.ui-money--prefix{
			font-size: $font-size-sm;
		}
	}
	.uni-radio-input{
		width: 36rpx;
		height: 36rpx;
	}
	.goods-price{
		margin-bottom: 10rpx;
		text{
			font-size: 40rpx;
			color: $color-yellow4;
			font-weight: bold;
		}
		.ui-money--prefix{
			font-size: $font-size-lg;
		}
	}
}
</style>
