<template>
	<view class="u-skeleton" :class="[`u-skeleton--${type}`, `u-skeleton--${theme}`]" v-if="loading">
		<template v-if="type === 'paragraph'">
			<view class="u-skeleton-paragraph">
				<view 
					class="u-skeleton-paragraph-line" 
					v-for="(item, index) in paragraphRows" 
					:key="index"
					:style="{ width: `${lineWidth}%` }"
				></view>
			</view>
		</template>
		
		<template v-else-if="type === 'card'">
			<view class="u-skeleton-card">
				<view class="u-skeleton-card-header"></view>
				<view class="u-skeleton-card-content">
					<view class="u-skeleton-card-row"></view>
					<view class="u-skeleton-card-row" :style="{ width: '70%' }"></view>
					<view class="u-skeleton-card-row" :style="{ width: '90%' }"></view>
				</view>
			</view>
		</template>
		
		<template v-else-if="type === 'list'">
			<view class="u-skeleton-list-item" v-for="i in 3" :key="i">
				<view class="u-skeleton-list-avatar"></view>
				<view class="u-skeleton-list-content">
					<view class="u-skeleton-list-title"></view>
					<view class="u-skeleton-list-desc"></view>
				</view>
			</view>
		</template>
		
		<template v-else>
			<slot></slot>
		</template>
	</view>
</template>

<script setup>
import { computed } from 'vue'

const props = defineProps({
	loading: {
		type: Boolean,
		default: true
	},
	type: {
		type: String,
		default: 'paragraph',
		validator: value => ['paragraph', 'card', 'list', 'custom'].includes(value)
	},
	rows: {
		type: Number,
		default: 3
	},
	theme: {
		type: String,
		default: 'primary',
		validator: value => ['primary', 'dark', 'light'].includes(value)
	},
	lineWidth: {
		type: Number,
		default: 100
	}
})

const paragraphRows = computed(() => {
	return Array.from({ length: props.rows })
})
</script>

<style lang="less">
@keyframes u-skeleton-blink {
	0% { background-color: #f0f0f0; }
	50% { background-color: #e0e0e0; }
	100% { background-color: #f0f0f0; }
}

.u-skeleton {
	padding: 16rpx;
	border-radius: 8rpx;
	overflow: hidden;
	
	&--primary {
		background-color: #f7f7f7;
	}
	
	&--dark {
		background-color: #f0f0f0;
	}
	
	&--light {
		background-color: #ffffff;
	}
	
	&::before {
		content: "";
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		animation: u-skeleton-blink 1.5s infinite ease-in-out;
		z-index: 1;
	}
}

.u-skeleton-paragraph {
	padding: 20rpx;
	
	&-line {
		height: 24rpx;
		background-color: #e9e9e9;
		margin-bottom: 20rpx;
		border-radius: 4rpx;
	}
}

.u-skeleton-card {
	padding: 24rpx;
	background-color: #fff;
	border-radius: 8rpx;
	margin-bottom: 16rpx;
	
	&-header {
		height: 120rpx;
		background-color: #e9e9e9;
		border-radius: 8rpx;
		margin-bottom: 20rpx;
	}
	
	&-content {
		padding: 0 10rpx;
		
		&-row {
			height: 24rpx;
			background-color: #e9e9e9;
			border-radius: 4rpx;
			margin-bottom: 16rpx;
		}
	}
}

.u-skeleton-list {
	background-color: #fff;
	border-radius: 8rpx;
	padding: 16rpx;
	
	&-item {
		display: flex;
		padding: 20rpx 0;
		border-bottom: 1rpx solid #eee;
		
		&:last-child {
			border-bottom: none;
		}
		
		&-avatar {
			width: 64rpx;
			height: 64rpx;
			background-color: #e9e9e9;
			border-radius: 50%;
			margin-right: 16rpx;
		}
		
		&-content {
			flex: 1;
			
			&-title {
				width: 40%;
				height: 20rpx;
				background-color: #e9e9e9;
				border-radius: 4rpx;
				margin-bottom: 12rpx;
			}
			
			&-desc {
				width: 70%;
				height: 16rpx;
				background-color: #e9e9e9;
				border-radius: 4rpx;
			}
		}
	}
}
</style>