<!-- 
  默认头像组件
  参考 zt-vue-element 的 CropperAvatar 实现
  支持默认头像逻辑：头像URL优先，否则显示用户昵称首字母
-->
<template>
  <view class="avatar-container" @click="handleClick">
    <!-- 有头像时显示图片 -->
    <image 
      v-if="avatarUrl" 
      :src="avatarUrl" 
      :style="avatarStyle"
      class="avatar-image"
      mode="aspectFill"
      @error="handleImageError"
    />
    
    <!-- 无头像时显示首字母头像 -->
    <view 
      v-else 
      class="avatar-initial"
      :style="[avatarStyle, initialStyle]"
    >
      {{ initialText }}
    </view>
    
    <!-- 编辑按钮 -->
    <view v-if="editable && !readonly" class="edit-mask">
      <text class="edit-icon">+</text>
    </view>
  </view>
</template>

<script setup>
import { computed, ref, watch } from 'vue'

// 组件属性
const props = defineProps({
  // 头像URL
  src: {
    type: String,
    default: ''
  },
  // 用户昵称，用于生成首字母
  nickname: {
    type: String,
    default: ''
  },
  // 头像尺寸
  size: {
    type: [String, Number],
    default: 80
  },
  // 是否可编辑
  editable: {
    type: Boolean,
    default: false
  },
  // 是否只读
  readonly: {
    type: Boolean,
    default: false
  },
  // 背景色（用于首字母头像）
  bgColor: {
    type: String,
    default: '#0055A2'
  },
  // 文字色（用于首字母头像）
  textColor: {
    type: String,
    default: '#ffffff'
  },
  // 自定义初始字符
  initial: {
    type: String,
    default: ''
  }
})

// 事件定义
const emit = defineEmits(['click', 'error'])

// 响应式数据
const avatarUrl = ref(props.src)
const imageError = ref(false)

// 计算属性
const avatarStyle = computed(() => {
  const size = typeof props.size === 'number' ? `${props.size}rpx` : props.size
  return {
    width: size,
    height: size,
    borderRadius: '50%'
  }
})

const initialStyle = computed(() => ({
  backgroundColor: props.bgColor,
  color: props.textColor,
  fontSize: `${Math.floor(props.size * 0.4)}rpx`,
  fontWeight: 'bold'
}))

// 生成初始字符逻辑
const initialText = computed(() => {
  // 如果提供了自定义初始字符，使用它
  if (props.initial) {
    return props.initial.charAt(0).toUpperCase()
  }
  
  // 如果有昵称，取首字母
  if (props.nickname) {
    // 处理中文和英文
    const firstChar = props.nickname.charAt(0)
    // 如果是中文，直接使用
    if (/[\u4e00-\u9fa5]/.test(firstChar)) {
      return firstChar
    }
    // 如果是英文，转大写
    return firstChar.toUpperCase()
  }
  
  // 默认返回用户图标
  return '用'
})

// 监听src变化
watch(() => props.src, (newSrc) => {
  avatarUrl.value = newSrc
  imageError.value = false
}, { immediate: true })

// 方法
const handleClick = () => {
  if (!props.readonly) {
    emit('click')
  }
}

const handleImageError = () => {
  imageError.value = true
  avatarUrl.value = '' // 清空URL，显示首字母头像
  emit('error')
}

// 暴露方法给父组件
defineExpose({
  refresh: () => {
    avatarUrl.value = props.src
    imageError.value = false
  }
})
</script>

<style lang="scss" scoped>
.avatar-container {
  position: relative;
  display: inline-block;
  overflow: hidden;
  
  &:hover .edit-mask {
    opacity: 1;
  }
}

.avatar-image {
  display: block;
  object-fit: cover;
}

.avatar-initial {
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--theme-primary, #0055A2);
  color: #ffffff;
  font-weight: bold;
  text-align: center;
  user-select: none;
}

.edit-mask {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.edit-icon {
  color: #ffffff;
  font-size: 48rpx;
  font-weight: bold;
}
</style>