<template>
	<button class="im-button" :class="[
		`im-button--${type}`,
		`im-button--${size} `,
		`im-button--${size}--${shape}`,
		{
			'im-button--disabled': disabled,
			'im-button--loading': loading,
			'im-button--block': block,
			'im-button--plain': plain,
			'im-button--hairline': hairline,
			'im-button--native': native
		}
	]" :style="buttonStyles" :disabled="disabled || loading" :loading="loading && showLoading" :form-type="formType"
		:open-type="openType" :hover-class="disabled || loading ? '' : hoverClass" :hover-start-time="hoverStartTime"
		:hover-stay-time="hoverStayTime" :app-parameter="appParameter" :lang="lang" :session-from="sessionFrom"
		:send-message-title="sendMessageTitle" :send-message-path="sendMessagePath" :send-message-img="sendMessageImg"
		:show-message-card="showMessageCard" @click="handleClick" @getuserinfo="onGetUserInfo" @contact="onContact"
		@getphonenumber="onGetPhoneNumber" @error="onError" @launchapp="onLaunchApp" @opensetting="onOpenSetting"
		@chooseavatar="onChooseAvatar">
		<!-- 加载状态 -->
		<view v-if="loading && showLoading" class="im-button__loading">
			<text v-if="loadingText" class="im-button__loading-text">
				{{ loadingText }}
			</text>
		</view>

		<!-- 图标 -->
		<view v-if="(icon || $slots.icon) && !loading" class="im-button__icon">
			<slot v-if="$slots.icon" name="icon">
				<image v-if="icon" :src="icon" class="im-button__icon-image"
					:class="[`im-button__icon--${iconPosition}`]" mode="aspectFit" />
			</slot>
			<im-icon v-else-if="icon" :name="icon"></im-icon>
		</view>

		<!-- 文本内容 -->
		<text v-if="!loading || !hideTextWhenLoading" class="im-button__text" :class="[`im-button__text--${size}`]"
			:style="textStyles">
			<slot>{{ text }}</slot>
		</text>

		<!-- 角标 -->
		<view v-if="badge || $slots.badge" class="im-button__badge">
			<slot name="badge">
				<view v-if="badge" class="im-button__badge-content" :class="{
					'im-button__badge--dot': badge === true,
					'im-button__badge--text': badge !== true
				}">
					<text v-if="badge !== true" class="im-button__badge-text">
						{{ formatBadge(badge) }}
					</text>
				</view>
			</slot>
		</view>
	</button>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { validator } from '../../index'
import type {
	ButtonProps,
	ButtonEmits
} from '../../types/components/button'

// ButtonProps 和 ButtonEmits
const props = withDefaults(defineProps<ButtonProps>(), {
	type: 'default',
	size: 'medium',
	shape: 'round',
	disabled: false,
	loading: false,
	loadingColor: '#ffffff',
	showLoading: true,
	hideTextWhenLoading: false,
	block: false,
	plain: false,
	hairline: false,
	native: false,
	iconPosition: 'left',
	iconSize: '32rpx',
	textSize: 'medium',
	color: '',
	bgColor: '',
	borderColor: '',
	border: true,
	textColor: '',
	width: '',
	height: '',
	padding: '',
	margin: '',
	radius: '',
	shadow: '',
	hoverClass: 'im-button--hover',
	hoverStartTime: 20,
	hoverStayTime: 70,
	lang: 'zh_CN'
})

const emit = defineEmits<ButtonEmits>()

// 计算属性
const buttonStyles = computed(() => {
	const styles: Record<string, string> = {}

	// 自定义颜色
	if (props.color && !props.plain) {
		styles.backgroundColor = props.color
		styles.borderColor = props.color
	}

	if (props.bgColor) {
		styles.background = props.bgColor
	}

	if (props.borderColor) {
		styles.borderColor = props.borderColor
	}

	if (!props.border) {
		styles.border = '0 solid transparent'
	}

	if (props.textColor) {
		styles.color = props.textColor
	}

	// 尺寸和布局
	if (props.width) {
		styles.width = props.width
	}

	if (props.height) {
		styles.height = props.height
	}

	if (props.padding) {
		styles.padding = props.padding
	}

	if (props.margin) {
		styles.margin = props.margin
	}

	if (props.radius) {
		styles.borderRadius = props.radius
	}

	if (props.shadow) {
		styles.boxShadow = props.shadow
	}

	if (props.block) {
		styles.width = '100%'
	}

	return styles
})

const textStyles = computed(() => {
	const styles: Record<string, string> = {}

	if (props.textColor) {
		styles.color = props.textColor
	}

	return styles
})

// const loadingStyle = computed(() => {
// 	return {
// 		color: props.loadingColor
// 	}
// })

// const loadingDotCount = computed(() => {
// 	// 根据按钮大小决定点数
// 	switch (props.size) {
// 		case 'mini': return 3
// 		case 'small': return 4
// 		case 'medium': return 5
// 		case 'large': return 6
// 		default: return 5
// 	}
// })

// 方法
const formatBadge = (badge: boolean | number | string): string => {
	if (typeof badge === 'boolean') return ''
	if (validator.isNumber(badge)) {
		return Number(badge) > 99 ? '99+' : badge.toString()
	}
	badge = String(badge)
	return badge.length > 2 ? `${badge.slice(0, 2)}...` : badge
}

// 事件处理
const handleClick = (event: PointerEvent) => {
	if (props.disabled || props.loading) {
		return
	}
	emit('click', event)
}

const onGetUserInfo = (detail: any) => {
	emit('getuserinfo', detail)
}

const onContact = (detail: any) => {
	emit('contact', detail)
}

const onGetPhoneNumber = (detail: any) => {
	emit('getphonenumber', detail)
}

const onError = (detail: any) => {
	emit('error', detail)
}

const onLaunchApp = (detail: any) => {
	emit('launchapp', detail)
}

const onOpenSetting = (detail: any) => {
	emit('opensetting', detail)
}

const onChooseAvatar = (detail: any) => {
	emit('chooseavatar', detail)
}
</script>

<style lang="scss" scoped>
uni-button:after {
	border: 0;
}

.im-button {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border: 1rpx solid transparent;
	font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', sans-serif;
	font-weight: 500;
	text-align: center;
	white-space: nowrap;
	vertical-align: middle;
	user-select: none;
	cursor: pointer;
	transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
	outline: none;
	box-sizing: border-box;

	// 禁用状态
	&--disabled {
		opacity: 0.6;
		cursor: not-allowed;
	}

	// 加载状态
	&--loading {
		cursor: not-allowed;
	}

	// 块级按钮
	&--block {
		display: flex;
		width: 100%;
	}

	// 朴素按钮
	&--plain {
		background-color: transparent !important;
	}

	// 细边框
	&--hairline {
		position: relative;
		// border-width: 1rpx;

		&::after {
			content: '';
			position: absolute;
			top: 0;
			left: 0;
			right: 0;
			bottom: 0;
			border: 1rpx solid currentColor; //
			border-radius: inherit;
			pointer-events: none;
			transform: scale(0.5);
			transform-origin: center;
		}
	}

	// 原生按钮
	&--native {
		padding: 0;
		background-color: transparent;
		border: none;
		line-height: normal;

		&::after {
			display: none;
		}
	}

	// 悬停效果
	&--hover {
		opacity: 0.8;
		transform: translateY(-1rpx);
	}

	// 尺寸
	&--mini {
		height: 32rpx;
		padding: 0 16rpx;
		font-size: $im-font-size-mini;
		border-radius: 20rpx;

		// 形状
		&--square {
			border-radius: 8rpx;
		}

		&--circle {
			border-radius: 50%;
			padding: 0 8rpx;
		}
	}

	&--small {
		height: 48rpx;
		padding: 0 24rpx;
		font-size: $im-font-size-small;
		border-radius: 32rpx;

		// 形状
		&--square {
			border-radius: 8rpx;
		}

		&--circle {
			border-radius: 50%;
			padding: 0 12rpx;
		}
	}

	&--medium {
		height: 60rpx;
		padding: 0 32rpx;
		font-size: $im-font-size;
		border-radius: 40rpx;

		// 形状
		&--square {
			border-radius: 8rpx;
		}

		&--circle {
			border-radius: 50%;
			padding: 0 16rpx;
		}
	}

	&--large {
		height: 80rpx;
		padding: 0 40rpx;
		font-size: $im-font-size-large;
		border-radius: 48rpx;

		// 形状
		&--square {
			border-radius: 8rpx;
		}

		&--circle {
			border-radius: 50%;
			padding: 0 20rpx;
		}
	}

	// 类型
	&--default {
		color: #606266;
		background-color: #ffffff;
		border-color: #dcdfe6;

		&.im-button--plain {
			color: #606266;
			border-color: #dcdfe6;
		}
	}

	&--primary {
		color: #ffffff;
		background-color: #409eff;
		border-color: #409eff;

		&.im-button--plain {
			color: #409eff;
			background-color: transparent;
			border-color: #409eff;
		}
	}

	&--success {
		color: #ffffff;
		background-color: #67c23a;
		border-color: #67c23a;

		&.im-button--plain {
			color: #67c23a;
			background-color: transparent;
			border-color: #67c23a;
		}
	}

	&--warning {
		color: #ffffff;
		background-color: #e6a23c;
		border-color: #e6a23c;

		&.im-button--plain {
			color: #e6a23c;
			background-color: transparent;
			border-color: #e6a23c;
		}
	}

	&--danger {
		color: #ffffff;
		background-color: #f56c6c;
		border-color: #f56c6c;

		&.im-button--plain {
			color: #f56c6c;
			background-color: transparent;
			border-color: #f56c6c;
		}
	}

	&--info {
		color: #ffffff;
		background-color: #909399;
		border-color: #909399;

		&.im-button--plain {
			color: #909399;
			background-color: transparent;
			border-color: #909399;
		}
	}

	// 内部元素
	&__loading {
		display: flex;
		align-items: center;
		justify-content: center;

		&-spinner {
			display: inline-flex;
			align-items: center;
			justify-content: center;
			margin-right: 8rpx;
		}

		&-dot {
			width: 6rpx;
			height: 6rpx;
			border-radius: 50%;
			margin: 0 2rpx;
			animation: button-loading 1.4s infinite ease-in-out both;

			@keyframes button-loading {

				0%,
				80%,
				100% {
					transform: scale(0.6);
					opacity: 0.6;
				}

				40% {
					transform: scale(1);
					opacity: 1;
				}
			}
		}

		&-text {
			font-size: inherit;
			color: inherit;
		}
	}

	&__icon {
		display: flex;
		align-items: center;
		justify-content: center;
		margin-right: 8rpx;

		&--right {
			margin-right: 0;
			margin-left: 8rpx;
			order: 1;
		}

		&-image {
			width: v-bind(iconSize);
			height: v-bind(iconSize);
		}
	}

	&__text {
		display: inline-block;
		line-height: 1;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;

		&--mini {
			font-size: $im-font-size-mini;
		}

		&--small {
			font-size: $im-font-size-small;
		}

		&--medium {
			font-size: $im-font-size;
		}

		&--large {
			font-size: $im-font-size-large;
		}
	}

	&__badge {
		position: absolute;
		top: 6rpx;
		right: 6rpx;
		z-index: 1;

		&-content {
			display: flex;
			align-items: center;
			justify-content: center;
		}

		&--dot {
			width: 12rpx;
			height: 12rpx;
			background-color: #fa3534;
			border-radius: 50%;
			border: 2rpx solid #ffffff;
		}

		&--text {
			min-width: 16rpx;
			height: 16rpx;
			padding: 4rpx;
			background-color: #fa3534;
			border-radius: 16rpx;
			border: 2rpx solid #ffffff;
		}

		&-text {
			color: #ffffff;
			font-size: 16rpx;
			font-weight: bold;
			line-height: 1;
		}
	}
}
</style>