<template>
	<view
		class="cl-skeleton"
		:class="[
			{
				'is-loading': loading,
				'is-dark': isDark
			},
			`cl-skeleton--${props.type}`,
			`${loading ? `${pt.loading?.className}` : ''}`,
			pt.className
		]"
		ref="skeletonRef"
	>
		<template v-if="loading">
			<cl-icon
				name="image-line"
				:pt="{
					className: '!text-surface-400'
				}"
				:size="40"
				v-if="type == 'image'"
			></cl-icon>
		</template>

		<template v-else>
			<slot></slot>
		</template>
	</view>
</template>

<script setup lang="ts">
import { computed, onMounted, ref, watch, type PropType } from "vue";
import type { PassThroughProps } from "../../types";
import { AnimationEngine, createAnimation, isDark, parsePt } from "@/cool";

defineOptions({
	name: "cl-skeleton"
});

const props = defineProps({
	pt: {
		type: Object,
		default: () => ({})
	},
	loading: {
		type: Boolean,
		default: true
	},
	type: {
		type: String as PropType<"text" | "image" | "circle" | "button">,
		default: "text"
	}
});

type PassThrough = {
	className?: string;
	loading?: PassThroughProps;
};

const pt = computed(() => parsePt<PassThrough>(props.pt));

// 组件引用
const skeletonRef = ref<UniElement | null>(null);

// 动画实例
let animation: AnimationEngine | null = null;

// 开始动画
function start() {
	if (!props.loading) return;

	animation = createAnimation(skeletonRef.value, {
		duration: 2000,
		loop: -1,
		alternate: true
	})
		.opacity("0.3", "1")
		.play();
}

// 停止动画
function stop() {
	if (animation != null) {
		animation!.stop();
		animation!.reset();
	}
}

onMounted(() => {
	watch(
		computed(() => props.loading),
		(val: boolean) => {
			if (val) {
				start();
			} else {
				stop();
			}
		},
		{
			immediate: true
		}
	);
});
</script>

<style lang="scss" scoped>
.cl-skeleton {
	&.is-loading {
		@apply bg-surface-100 rounded-md;

		&.is-dark {
			@apply bg-surface-600;
		}

		&.cl-skeleton--text {
			height: 40rpx;
			width: 300rpx;
		}

		&.cl-skeleton--image {
			@apply flex flex-row items-center justify-center;
			width: 120rpx;
			height: 120rpx;
			border-radius: 16rpx;
		}

		&.cl-skeleton--circle {
			@apply rounded-full;
			width: 120rpx;
			height: 120rpx;
		}

		&.cl-skeleton--button {
			@apply rounded-lg;
			height: 66rpx;
			width: 150rpx;
		}
	}
}
</style>
