<template>
	<view class="user-avatar" :style="wrapStyle" @click="$emit('click')">
		<image v-if="src" class="user-avatar-img" :src="src" mode="aspectFill" :style="imgStyle" />
		<view v-else class="user-avatar-placeholder" :class="'gradient-' + gradientIndex" :style="placeholderStyle">
			<text class="user-avatar-text" :style="textStyle">{{ displayText }}</text>
		</view>
	</view>
</template>

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

/**
 * 文字提取：中文 ≤2 全量，>2 取最后两位；英文取前两词首字母大写，一词取前两位
 */
function getAvatarText(name) {
	const n = String(name || '').trim()
	if (!n) return '?'
	// 是否主要为中文（CJK）：非空字符里 CJK 占多数则按中文处理
	const cjkCount = (n.match(/[\u4e00-\u9fff\u3400-\u4dbf]/g) || []).length
	const letterCount = n.replace(/\s/g, '').length
	const isCJK = letterCount > 0 && cjkCount >= letterCount / 2
	if (isCJK) {
		if (n.length <= 2) return n
		return n.slice(-2)
	}
	// 英文/其他：按空格分词
	const words = n.split(/\s+/).filter(Boolean)
	if (words.length >= 2) {
		const a = (words[0][0] || '').toUpperCase()
		const b = (words[1][0] || '').toUpperCase()
		return (a + b) || '?'
	}
	if (words.length === 1 && words[0].length >= 2) return words[0].slice(0, 2).toUpperCase()
	if (words.length === 1 && words[0].length === 1) return words[0].toUpperCase()
	return '?'
}

/** 渐变色库 [左上深, 右下浅]，135deg，共 20 组 */
const AVATAR_GRADIENT_PAIRS = [
	['#1e3a8a', '#93c5fd'], ['#166534', '#86efac'], ['#c2410c', '#fdba74'], ['#b91c1c', '#fca5a5'], ['#5b21b6', '#c4b5fd'],
	['#0f766e', '#5eead4'], ['#3730a3', '#a5b4fc'], ['#0d9488', '#2dd4bf'], ['#b45309', '#fcd34d'], ['#be123c', '#fda4af'],
	['#0369a1', '#7dd3fc'], ['#4d7c0f', '#bef264'], ['#86198f', '#e879f9'], ['#db2777', '#fbcfe8'], ['#047857', '#6ee7b7'],
	['#6d28d9', '#ddd6fe'], ['#1e40af', '#93c5fd'], ['#ea580c', '#fed7aa'], ['#0e7490', '#99f6e4'], ['#881337', '#fbcfe8'],
]

/**
 * 根据 id 或 name 哈希得到固定索引 0~19，同一 id/name 对应同一种渐变
 * id 为空时用 name，确保无 id 时也有稳定渐变
 */
function getGradientIndex(id, name) {
	const s = String(id || '').trim() || String(name || '').trim()
	let hash = 0
	for (let i = 0; i < s.length; i++) {
		hash = ((hash << 5) - hash + s.charCodeAt(i)) | 0
	}
	return Math.abs(hash) % AVATAR_GRADIENT_PAIRS.length
}

const props = defineProps({
	/** 显示名称，用于占位文字 */
	name: { type: String, default: '' },
	/** 用户唯一标识，用于占位背景色 */
	id: { type: String, default: '' },
	/** 头像图片地址，有则显示图片，无则显示占位 */
	src: { type: String, default: '' },
	/** 尺寸数值，默认 48 */
	size: { type: Number, default: 48 },
	/** 尺寸单位：'px' | 'rpx'，默认 px；rpx 便于在 uni-app 中与页面 rpx 一致 */
	unit: { type: String, default: 'px' },
})

defineEmits(['click'])

const displayText = computed(() => getAvatarText(props.name))

const gradientIndex = computed(() => getGradientIndex(props.id, props.name))

const su = computed(() => props.unit || 'px')

const wrapStyle = computed(() => {
	const u = su.value
	const w = props.size + u
	return {
		width: w,
		height: w,
		borderRadius: '50%',
	}
})

const imgStyle = computed(() => {
	const u = su.value
	const w = props.size + u
	return {
		width: w,
		height: w,
		borderRadius: '50%',
	}
})

const placeholderStyle = computed(() => {
	const u = su.value
	const w = props.size + u
	return {
		width: w,
		height: w,
		borderRadius: '50%',
	}
})

const textStyle = computed(() => ({
	fontSize: (props.size * 0.4) + su.value,
}))
</script>

<style scoped>
.user-avatar {
	overflow: hidden;
	flex-shrink: 0;
}
.user-avatar-img {
	display: block;
}
.user-avatar-placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
}
.user-avatar-text {
	color: #ffffff;
	font-weight: 500;
	font-family: 'PingFang SC', 'Roboto', -apple-system, sans-serif;
}
</style>
<style>
/* 无 scoped，避免编译后动态 class 与 data-v 不匹配导致渐变不生效；用 .user-avatar 限定避免污染；135deg 左上深→右下浅 */
.user-avatar .user-avatar-placeholder.gradient-0 { background-color: #1e3a8a; background-image: linear-gradient(135deg, #1e3a8a, #93c5fd); }
.user-avatar .user-avatar-placeholder.gradient-1 { background-color: #166534; background-image: linear-gradient(135deg, #166534, #86efac); }
.user-avatar .user-avatar-placeholder.gradient-2 { background-color: #c2410c; background-image: linear-gradient(135deg, #c2410c, #fdba74); }
.user-avatar .user-avatar-placeholder.gradient-3 { background-color: #b91c1c; background-image: linear-gradient(135deg, #b91c1c, #fca5a5); }
.user-avatar .user-avatar-placeholder.gradient-4 { background-color: #5b21b6; background-image: linear-gradient(135deg, #5b21b6, #c4b5fd); }
.user-avatar .user-avatar-placeholder.gradient-5 { background-color: #0f766e; background-image: linear-gradient(135deg, #0f766e, #5eead4); }
.user-avatar .user-avatar-placeholder.gradient-6 { background-color: #3730a3; background-image: linear-gradient(135deg, #3730a3, #a5b4fc); }
.user-avatar .user-avatar-placeholder.gradient-7 { background-color: #0d9488; background-image: linear-gradient(135deg, #0d9488, #2dd4bf); }
.user-avatar .user-avatar-placeholder.gradient-8 { background-color: #b45309; background-image: linear-gradient(135deg, #b45309, #fcd34d); }
.user-avatar .user-avatar-placeholder.gradient-9 { background-color: #be123c; background-image: linear-gradient(135deg, #be123c, #fda4af); }
.user-avatar .user-avatar-placeholder.gradient-10 { background-color: #0369a1; background-image: linear-gradient(135deg, #0369a1, #7dd3fc); }
.user-avatar .user-avatar-placeholder.gradient-11 { background-color: #4d7c0f; background-image: linear-gradient(135deg, #4d7c0f, #bef264); }
.user-avatar .user-avatar-placeholder.gradient-12 { background-color: #86198f; background-image: linear-gradient(135deg, #86198f, #e879f9); }
.user-avatar .user-avatar-placeholder.gradient-13 { background-color: #db2777; background-image: linear-gradient(135deg, #db2777, #fbcfe8); }
.user-avatar .user-avatar-placeholder.gradient-14 { background-color: #047857; background-image: linear-gradient(135deg, #047857, #6ee7b7); }
.user-avatar .user-avatar-placeholder.gradient-15 { background-color: #6d28d9; background-image: linear-gradient(135deg, #6d28d9, #ddd6fe); }
.user-avatar .user-avatar-placeholder.gradient-16 { background-color: #1e40af; background-image: linear-gradient(135deg, #1e40af, #93c5fd); }
.user-avatar .user-avatar-placeholder.gradient-17 { background-color: #ea580c; background-image: linear-gradient(135deg, #ea580c, #fed7aa); }
.user-avatar .user-avatar-placeholder.gradient-18 { background-color: #0e7490; background-image: linear-gradient(135deg, #0e7490, #99f6e4); }
.user-avatar .user-avatar-placeholder.gradient-19 { background-color: #881337; background-image: linear-gradient(135deg, #881337, #fbcfe8); }
</style>
