<template>
	<view class="wrap">
		<view class="waterfalls">
			<view v-for="(columnList, columnIndex) in listData" :key="columnIndex">
				<view :style="{ width: columnWidth + 'rpx' }" class="column">
					<view v-for="(item,j) in columnList" :key="j">
						<slot name="column-list" v-bind:item="item">
							<view :style="itemStyle(item)" @click="handleImageClick(item)" class="waterfalls-item">
								<image :style="{height: getStyle(item)['height'] + 'rpx'}" class="item-image load" :class="{ error: item.error }" :src="item.image" mode="aspectFill"></image>
								<view class="item-info" v-if="item.title != undefined && item.title.length">
									<view class="title" v-if="item.title != undefined && item.title.length">{{ item.title }}</view>
									<view class="price" v-if="item.sell_price != undefined">
										<text>￥{{ item.sell_price }}</text>
										<text v-if="item.market_price != undefined && item.market_price > 0">￥{{ item.market_price }}</text>
									</view>
								</view>
							</view>
						</slot>
					</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script setup>
	import { computed,watch,ref,onMounted,nextTick,getCurrentInstance } from "vue";
	
	const props = defineProps({
		column: { //列的数量
			type: Number,
			default: 3,
		},
		columnWidth: {  //列的宽度
			type: Number,
			default: 230,
		},
		columnMarginTop: { //每项距离上一项的距离
			type: Number,
			default: 20,
		},
		list: { //列表数据，分页时候直接更新list
			type: Array,
			default: [],
		},
		isRefreshList: { //取反则重置列表数据
			type: Boolean,
			default: false,
		}
	});
	 
	const emits   	   = defineEmits(["click"]);
	
	let listData       = ref([]);
	let listDataHeight = ref([]);
	
	watch(()=>props.isRefreshList,(newValue,oldValue)=>{
		refreshList();
	})
	
	watch(()=>props.list,(newValue,oldValue)=>{
		nextTick(async () => {
			if (newValue.length){
				for(let i = 0; i < newValue.length; i++){
					const item = newValue[i]
					if(!item.width || !item.height){
						uni.getImageInfo({
							src: item.image,
							success(image) {
								item.width = image.width;
								item.height = image.height;
								item.error  = false;
							},
							fail(err) {
								item.error = true;
							}
						});
					}
					addListItem(item)
				}
			}
		});
	},{ deep: false })
	
	const init = async()=>{
		refreshList();
	}
	
	onMounted(()=>{
		init();
	})
	
	/**
	 * 更新单个瀑布流
	 */
	const addListItem = (item)=>{
		const { height } = getStyle(item);
		const minIndex = getMinColumn(listDataHeight.value);
		if (listData.value[minIndex]) {
			listData.value[minIndex].push(item);
			listDataHeight.value[minIndex] += height;
		}
	}
	
	/**
	 * 刷新瀑布流
	 */
	const refreshList = ()=>{
		let a  = [];
		let b  = [];
		for (let i = 0; i < props.column; i++) a.push([]);
		for (let i = 0; i < props.column; i++) b.push(0);
		listData.value 		 = a;
		listDataHeight.value = b;
	}
	
	/**
	 * 每项样式
	 */
	const itemStyle = (item)=>{
		const { width, height } = getStyle(item);
		return { width: width + "rpx", minHeight: height + "rpx", marginBottom: props.columnMarginTop + "rpx" };
	}
	
	/**
	 * width、height转换
	 */
	const getStyle = (item)=>{
		const width = props.columnWidth;
		return { width, height: parseInt((width * (item.height || 500)) / (item.width || 500)) };
	}
	
	/**
	 * 点击图片
	 */
	const handleImageClick = (item)=>{
		emits("click", item);
	}
	
	/**
	 * 获取高度最小一列
	 */
	const getMinColumn = (listDataHeight)=>{
		let minIndex = 0;
		let minHeight = 0;
		listDataHeight.map((columnHeight, columnIndex) => {
			if (columnIndex == 0) {
				minHeight = columnHeight;
			} else if (columnHeight < minHeight) {
				minIndex = columnIndex;
				minHeight = columnHeight;
			}
		});
		
		return minIndex;
	}
	
	defineExpose({ itemStyle, getStyle });
</script>

<style lang="scss" scoped>
	.wrap {
		padding-top: 15rpx;
		width: 710rpx;
		margin: 0 auto;
		.waterfalls {
			width: 100%;
			display: flex;
			padding-bottom: 10rpx;
			align-items: flex-start;
			justify-content: space-between;
			.column {
				.waterfalls-item {
					display: flex;
					flex-direction: column;
					flex-wrap: wrap;
					transition: opacity 1s;
					position: relative;
					background-color: #fff;
					border-radius: 10rpx;
					overflow: hidden;
					.item-image {
						// border-radius: 10rpx;
						width: 100%;
						height: 100%;
						opacity: 0;
							
						&.load {
							opacity: 1;
						}
					}
					.item-info {
						padding: 30rpx 15rpx 20rpx 15rpx;
						.title {
							font-size: 29rpx;
						}
						.price {
							padding-top: 10rpx;
							text {
								&:nth-child(1) { 
									color: red;
									font-size: 32rpx;
								}
								&:nth-child(2) {
									color: #999;
									font-size: 26rpx;
									text-decoration: line-through;
									padding-left: 15rpx;
									position: relative;
									top: -1rpx;
								}
							}
						}
					}
				}
			}
		}
	}
	
	.load {
		animation: Load 1.5s ease;
	}
	
	.error {
		background: #f2f2f2 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAiAQMAAAAatXkPAAAABlBMVEUAAADMzMzIT8AyAAAAAXRSTlMAQObYZgAAAIZJREFUCNdlzjEKwkAUBNAfEGyCuYBkLyLuxRYW2SKlV1JSeA2tUiZg4YrLjv9PGsHqNTPMSAQuyAJgRDHSyvBPwtZoSJXakeJI9iuRLGDygdl6V0yKDtyMAeMPZySj8yfD+UapvRPj2JOwkyAooSV5IwdDjPdCPspe8LyTl9IKJvDETKKRv6vnlUasgg0fAAAAAElFTkSuQmCC) no-repeat center center;
	}
	
	@keyframes Load {
		0% {
			opacity: 0;
		}
	
		100% {
			opacity: 1;
		}
	}
</style>