<template>
	<view class="async-switch"
		:class="{
			'async-switch--active': value,
			'async-switch--disabled': disabled,
			'async-switch--loading': innerLoading
		}"
		@click="handleClick"
	>
		<!-- 开关轨道 -->
		<view class="async-switch__track"></view>
		<!-- 开关按钮 -->
		<view class="async-switch__thumb"></view>
		<!-- 加载状态遮罩 -->
		<view v-if="innerLoading" class="async-switch__loading-mask">
			<u-loading mode="circle"></u-loading>
		</view>
	</view>
</template>

<script>
	export default {
		name: 'AsyncSwitch',
		props: {
			// 开关当前状态（双向绑定）
			value: {
				type: Boolean,
				default: false
			},
			// 是否禁用
			disabled: {
				type: Boolean,
				default: false
			},
			// 加载状态（外部可控制）
			loading: {
				type: Boolean,
				default: false
			},
			// 开关激活色
			activeColor: {
				type: String,
				default: '#016BF6'
			},
			// 开关未激活色
			inactiveColor: {
				type: String,
				default: '#ffffff'
			},
			// 异步变更处理函数（必须返回Promise）
			asyncChange: {
				type: Function,
				required: true
			}
		},
		data() {
			return {
				// 内部加载状态（避免外部直接覆盖）
				innerLoading: this.loading
			};
		},
		watch: {
			// 监听外部传入的loading属性变化，同步到内部状态
			loading(newVal) {
				this.innerLoading = newVal;
			}
		},
		methods: {
			/**
			 * 处理开关点击事件（Vue2 异步方法写法）
			 */
			async handleClick() {
				// 禁用/加载中时不响应点击
				if (this.disabled || this.innerLoading) return;

				// 目标状态（当前状态取反）
				const targetValue = !this.value;

				try {
					// 开启加载状态
					this.innerLoading = true;
					// 执行外部传入的异步操作
					const result = await this.asyncChange(targetValue);

					// 异步操作成功且返回值不为false时，更新开关状态
					if (result !== false) {
						// Vue2 触发自定义事件，实现v-model双向绑定
						this.$emit('input', targetValue); // v-model 底层依赖input事件
						this.$emit('change', targetValue); // 额外的change回调
					}
				} catch (error) {
					// 异步操作失败，触发error事件
					this.$emit('error', error);
					console.error('Switch异步更新失败:', error);
				} finally {
					// 无论成功/失败，关闭加载状态
					this.innerLoading = false;
				}
			}
		}
	};
</script>

<style scoped>
	.async-switch {
		position: relative;
		width: 52px;
		height: 32px;
		border-radius: 16px;
		background-color: #ffffff;
		transition: background-color 0.3s ease;
		cursor: pointer;
		box-sizing: border-box;
		border: 1px solid #eee;
	}

	/* 激活状态 */
	.async-switch--active {
		background-color: #016BF6;
	}

	/* 禁用状态 */
	.async-switch--disabled {
		opacity: 0.5;
		cursor: not-allowed;
	}

	/* 加载状态 */
	.async-switch--loading {
		opacity: 0.8;
		cursor: wait;
	}

	.async-switch__track {
		width: 100%;
		height: 100%;
		border-radius: 16px;
	}

	.async-switch__thumb {
		position: absolute;
		top: 1px;
		left: 1px;
		width: 28px;
		height: 28px;
		border-radius: 50%;
		background-color: #fff;
		box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
		transition: left 0.3s ease;
	}

	.async-switch--active .async-switch__thumb {
		left: 22px;
	}

	/* 加载遮罩 */
	.async-switch__loading-mask {
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		border-radius: 16px;
		background-color: rgba(0, 0, 0, 0.15);
		display: flex;
		align-items: center;
		justify-content: center;
		z-index: 10;
	}
</style>