<script setup lang="ts">
import { ref, watch } from 'vue'
import CardHeader from './CardHeader.vue'

const props = defineProps({
  shadow: {
    type: Boolean,
    default: true,
  },
  className: {
    type: String,
    default: '',
  },
  title: {
    type: String,
    default: '',
  },
  collapsible: {
    type: Boolean,
    default: false,
  },
  defaultCollapsed: {
    type: Boolean,
    default: false,
  },
})

const isCollapsed = ref(props.defaultCollapsed)

function handleToggle(collapsed: boolean) {
  isCollapsed.value = collapsed
}

// 过渡动画钩子函数
function onEnter(el: HTMLElement) {
  el.style.height = '0'
  el.style.overflow = 'hidden'
  el.style.opacity = '0'
  el.style.transformOrigin = 'top'
  el.style.transform = 'scaleY(0.8)'

  // 触发回流
  void el.offsetHeight

  el.style.transition = 'height 0.2s ease, opacity 0.2s ease, transform 0.2s ease'
  el.style.height = `${el.scrollHeight}px`
  el.style.opacity = '1'
  el.style.transform = 'scaleY(1)'
}

function onAfterEnter(el: HTMLElement) {
  el.style.height = ''
  el.style.overflow = ''
  el.style.transition = ''
  el.style.transformOrigin = ''
}

function onBeforeLeave(el: HTMLElement) {
  el.style.height = `${el.scrollHeight}px`
  el.style.overflow = 'hidden'
  el.style.transformOrigin = 'top'

  // 触发回流
  void el.offsetHeight
}

function onLeave(el: HTMLElement) {
  el.style.transition = 'height 0.2s ease, opacity 0.2s ease, transform 0.2s ease'
  el.style.height = '0'
  el.style.opacity = '0'
  el.style.transform = 'scaleY(0.8)'
}
watch(() => props.defaultCollapsed, (newVal) => {
  isCollapsed.value = newVal
})
</script>

<template>
  <div class="card-container" :class="[shadow ? 'with-shadow' : '', className]">
    <CardHeader
      v-if="title"
      :title="title"
      :collapsible="collapsible"
      :default-collapsed="defaultCollapsed"
      @toggle="handleToggle"
    />
    <transition
      name="collapse-transition"
      @enter="onEnter"
      @after-enter="onAfterEnter"
      @before-leave="onBeforeLeave"
      @leave="onLeave"
    >
      <div v-show="!isCollapsed" class="card-content">
        <slot />
      </div>
    </transition>
  </div>
</template>

<style lang="less" scoped>
.card-container {
  background-color: #fff;
  border-radius: 8px;
  border: 1px solid #e5e7eb;
  padding: 10px;
  // margin-bottom: 0;

  &.with-shadow {
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
  }
}

.card-content {
  will-change: height, opacity, transform;
  transform-origin: top;
}
</style>
