<template>
  <section
    class="collapsible-panel"
    :class="{ 'collapsible-panel--collapsed': isCollapsed }"
  >
    <div class="collapsible-panel__header" @click="handleHeaderClick">
      <PanelHeader :title="title" :subtitle="subtitle">
        <template #title-icon>
          <slot name="title-icon" />
        </template>
        <template #extra>
          <slot name="header-right" />
          <button
            v-if="collapsible"
            class="collapsible-panel__toggle"
            type="button"
            :aria-expanded="!isCollapsed"
            :aria-label="isCollapsed ? '展开面板' : '收起面板'"
            @click.stop="toggle"
          >
            <img
              :src="toggleIcon"
              alt=""
              class="collapsible-panel__toggle-icon"
              :class="{ 'is-collapsed': isCollapsed }"
            />
          </button>
        </template>
      </PanelHeader>
    </div>

    <transition
      name="collapsible-panel-collapse"
      @before-enter="onBeforeEnter"
      @enter="onEnter"
      @after-enter="onAfterEnter"
      @before-leave="onBeforeLeave"
      @leave="onLeave"
      @after-leave="onAfterLeave"
    >
      <div v-show="!isCollapsed" class="collapsible-panel__body">
        <div class="collapsible-panel__content">
          <slot />
        </div>
      </div>
    </transition>
  </section>
</template>

<script setup>
import { computed, ref } from "vue";
import PanelHeader from "./PanelHeader.vue";
import toggleIcon from "../../assets/images/展开icon.png";

const props = defineProps({
  /** 面板标题 */
  title: {
    type: String,
    required: true,
  },
  /** 面板副标题 */
  subtitle: {
    type: String,
    default: "",
  },
  /**
   * v-model:collapsed 控制收起状态
   * 不传表示非受控模式，由 startCollapsed 控制初始值
   * 传入 true/false 表示受控模式，状态由父组件完全控制
   */
  collapsed: {
    type: Boolean,
    default: undefined,
  },
  /** 是否可收缩 */
  collapsible: {
    type: Boolean,
    default: true,
  },
  /** 初始是否收起（仅在非受控模式下生效） */
  startCollapsed: {
    type: Boolean,
    default: false,
  },
});

const emit = defineEmits(["update:collapsed", "toggle", "title-click"]);

// 判断是否受控组件
const isControlled = computed(() => props.collapsed !== undefined);

// 内部收起状态
const internalCollapsed = ref(!!props.startCollapsed);

// 计算当前收起状态
const isCollapsed = computed({
  get() {
    return isControlled.value ? !!props.collapsed : internalCollapsed.value;
  },
  set(value) {
    if (isControlled.value) {
      emit("update:collapsed", value);
    } else {
      internalCollapsed.value = value;
    }
    emit("toggle", value);
  },
});

// 处理标题点击事件
function handleHeaderClick() {
  emit("title-click");
}

// 切换收起/展开
function toggle() {
  if (!props.collapsible) return;
  isCollapsed.value = !isCollapsed.value;
}

// 改进的过渡动画钩子
function onBeforeEnter(el) {
  el.style.height = "0";
  el.style.overflow = "hidden";
}

function onEnter(el) {
  // 使用 requestAnimationFrame 确保动画流畅
  requestAnimationFrame(() => {
    el.style.height = `${el.scrollHeight}px`;
  });
}

function onAfterEnter(el) {
  el.style.height = "";
  el.style.overflow = "";
}

function onBeforeLeave(el) {
  el.style.height = `${el.scrollHeight}px`;
  el.style.overflow = "hidden";
}

function onLeave(el) {
  // 强制重排以确保动画触发
  el.offsetHeight; // eslint-disable-line no-unused-expressions
  el.style.height = "0";
}

function onAfterLeave(el) {
  el.style.height = "";
  el.style.overflow = "";
}
</script>

<style scoped lang="scss">
@use "@/styles/mixins.scss" as *;
@use "../../assets/styles/common.scss" as *;

.collapsible-panel {
  display: flex;
  flex-direction: column;
  &:not(:last-child) {
    margin-bottom: vh(17);
  }
  border: 2px solid transparent; /* 防止 hover 时抖动 */

  &__header {
    position: relative;

    &--clickable {
      cursor: pointer;
      user-select: none;

      &:hover {
        opacity: 0.95;
      }
    }
  }

  &__toggle {
    cursor: pointer;
    border: none;
    background: transparent;
    padding: vw(4);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: opacity 0.2s ease;
    margin-left: vw(8);

    &:hover {
      opacity: 0.8;
    }

    &:active {
      transform: scale(0.95);
    }
  }

  &__toggle-icon {
    width: vw(24);
    height: auto;
    transition: transform 0.3s ease;

    &.is-collapsed {
      // transform: rotate(-90deg);
    }
  }

  &__body {
    position: relative;
    overflow: hidden;
    transition: height 0.3s ease;

    // 使用伪元素作为背景层，九宫格实现
    &::before {
      content: "";
      position: absolute;
      inset: 0;
      border-style: solid;
      border-width: vh(25) vw(30);
      border-image-source: url("../../assets/images/通用卡片bg.png");
      border-image-slice: 25 30 25 30 fill;
      border-image-width: vh(25) vw(30);
      border-image-repeat: stretch;
      box-sizing: border-box;
      pointer-events: none; // 不阻挡鼠标事件
      z-index: -1; // 放在内容下方
    }
  }

  &__content {
    position: relative;
    padding: vh(5) vw(20) vh(5); // 留出空间避免被圆角遮挡
    z-index: 1;

    // 如果内容需要滚动
    &.scrollable {
      max-height: vh(400);
      overflow-y: auto;
      @extend .panel--scrollable;
    }
  }

  // 折叠状态
  &--collapsed {
    .collapsible-panel__body {
      height: 0;
      border-width: 0; // 折叠时移除 border
    }
  }
}

// .collapsible-panel:hover {
//   cursor: pointer;
//   border: 2px solid rgba(255, 80, 80, 0.8);
//   animation: glowPulse 1.6s ease-in-out infinite;

//   box-shadow: 0 0 12px rgba(255, 80, 80, 0.8), 0 0 25px rgba(255, 0, 0, 0.5),
//     0 0 45px rgba(255, 0, 0, 0.35), inset 0 0 18px rgba(255, 80, 80, 0.8),
//     inset 0 0 35px rgba(255, 30, 30, 0.55), inset 0 0 55px rgba(255, 0, 0, 0.4);
// }

// /* 闪动动画 */
// @keyframes glowPulse {
//   0% {
//     box-shadow: 0 0 12px rgba(255, 80, 80, 0.8), 0 0 25px rgba(255, 0, 0, 0.5),
//       0 0 45px rgba(255, 0, 0, 0.35), inset 0 0 18px rgba(255, 80, 80, 0.8),
//       inset 0 0 35px rgba(255, 30, 30, 0.55),
//       inset 0 0 55px rgba(255, 0, 0, 0.4);
//   }

//   50% {
//     box-shadow: 0 0 18px rgba(255, 120, 120, 1), 0 0 35px rgba(255, 40, 40, 0.7),
//       0 0 65px rgba(255, 0, 0, 0.45), inset 0 0 25px rgba(255, 80, 80, 1),
//       inset 0 0 45px rgba(255, 40, 40, 0.7), inset 0 0 75px rgba(255, 0, 0, 0.5);
//   }

//   100% {
//     box-shadow: 0 0 12px rgba(255, 80, 80, 0.8), 0 0 25px rgba(255, 0, 0, 0.5),
//       0 0 45px rgba(255, 0, 0, 0.35), inset 0 0 18px rgba(255, 80, 80, 0.8),
//       inset 0 0 35px rgba(255, 30, 30, 0.55),
//       inset 0 0 55px rgba(255, 0, 0, 0.4);
//   }
// }
</style>
