<script setup lang="ts">
interface Props {
  // 默认展示的行数
  inline?: number
  // 是否默认展开
  defaultExpanded?: boolean
  // 展开按钮文字
  expandText?: string
  // 收起按钮文字
  collapseText?: string
  // 行高（px），用于计算行数
  lineHeight?: number
}
const props = withDefaults(defineProps<Props>(), {
  inline: 3,
  defaultExpanded: false,
  expandText: '展开',
  collapseText: '收起',
  lineHeight: 100,
})

const emit = defineEmits<{
  (e: 'toggle', isExpanded: boolean): void
}>()

const _this = getCurrentInstance()

const isExpanded = ref(props.defaultExpanded)
const contentHeight = ref(0)
const showToggle = ref(false)

const toggleText = computed(() =>
  isExpanded.value ? props.collapseText : props.expandText,
)

const contentStyle = computed(() => {
  const style: Record<string, string> = {}
  if (isExpanded.value) {
    style.overflow = 'visible'
  }
  else {
    // 收起状态，限制行数
    style.overflow = 'hidden'
    style.maxHeight = `${props.inline * props.lineHeight}rpx`
  }

  return style
})

function handleToggle() {
  isExpanded.value = !isExpanded.value
  emit('toggle', isExpanded.value)
}

function getContentHeight() {
  return new Promise<number>((resolve) => {
    const query = uni.createSelectorQuery().in(_this)
    query.select('.collapse-panel__content').boundingClientRect()
    query.exec((res) => {
      if (res && res[0]) {
        resolve(res[0].height)
      }
      else {
        resolve(0)
      }
    })
  })
}

async function checkNeedToggle() {
  await nextTick()

  try {
    const height = await getContentHeight()
    contentHeight.value = height
    const maxHeightInPx = (props.inline * props.lineHeight) / 2
    showToggle.value = height > maxHeightInPx
  }
  catch (error) {
    console.error('获取内容高度失败:', error)
  }
}

// 暴露方法给父组件
defineExpose({
  expand: () => {
    isExpanded.value = true
    emit('toggle', true)
  },
  collapse: () => {
    isExpanded.value = false
    emit('toggle', false)
  },
  toggle: handleToggle,
  refresh: checkNeedToggle,
  isExpanded: computed(() => isExpanded.value),
})

// 监听inline变化，重新检查
watch(() => props.inline, () => {
  if (!isExpanded.value) {
    checkNeedToggle()
  }
})

onMounted(() => {
  setTimeout(() => {
    checkNeedToggle()
  }, 100)
})
</script>

<template>
  <view class="collapse-panel">
    <view
      class="collapse-panel__content pb20rpx"
      :class="{
        'collapse-panel__content--collapsed': !isExpanded,
        'collapse-panel__content--expanded': isExpanded,
      }"
      :style="contentStyle"
    >
      <slot />
    </view>

    <view
      v-if="showToggle"
      class="collapse-panel__toggle"
      @tap="handleToggle"
    >
      <text class="collapse-panel__toggle-text">
        {{ toggleText }}
      </text>
      <view class="collapse-panel__toggle-icon" :class="{ 'collapse-panel__toggle-icon--expanded': isExpanded }">
        <wd-icon name="arrow-down" size="22px" />
      </view>
    </view>
  </view>
</template>

<style lang="scss" scoped>
.collapse-panel {
  width: 100%;

  &__content {
    overflow: hidden;
    transition: max-height 0.3s ease;
    line-height: 1.5;

    &--collapsed {
      position: relative;

      // 添加渐变遮罩效果（可选）
      &::after {
        content: '';
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        height: 60rpx;
        background: linear-gradient(to bottom, transparent, #ffffff);
        pointer-events: none;
      }
    }
  }

  &__toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16rpx 0;
    color: #222222;
    font-size: 28rpx;

    &-text {
      margin-right: 8rpx;
    }

    &-icon {
      transition: transform 0.3s ease;
      font-size: 24rpx;
      display: flex;
      align-items: center;
      justify-content: center;
      width: 32rpx;
      height: 32rpx;

      &--expanded {
        transform: rotate(180deg);
      }
    }
  }
}

// 如果在小程序中需要更精确的文本行数控制，可以使用以下样式类
.text-lines {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}
</style>
