import { useAnimation } from "motion/react";
import { useEffect, useRef } from "react";

/**
 * RightUtils 子菜单动画 Hook
 *
 * 功能说明：
 * 1. 监听子菜单的展开/收起状态变化
 * 2. 执行炫酷的弹跳动画效果（从下向上进入，从上向下离开）
 * 3. 支持首次加载动画，初始化时就会显示并执行进入动画
 * 4. 使用弹跳、缩放、透明度三重动画效果，让动画更加生动
 *
 * 动画效果详解：
 * - 展开动画（进入）：
 *   - 位置：从下方 80px 处冲到上方 15px（超出目标），轻微回落到 5px，最后稳定到 0
 *   - 缩放：从 0.9 倍缩小到 1.05 倍（轻微放大），轻微缩小到 0.98，回到正常 1.0
 *   - 透明度：从透明到不透明
 *   - 时长：0.7 秒
 *   - 缓动：使用强弹性贝塞尔曲线 [0.34, 1.56, 0.64, 1]，产生明显的过冲和回弹效果
 *
 * - 收起动画（离开）：
 *   - 位置：从正常位置向上弹跳 20px，回落到 10px，然后向下离开到 100px
 *   - 缩放：轻微放大到 1.02，然后缩小到 0.85
 *   - 透明度：保持可见再淡出
 *   - 时长：0.5 秒
 *   - 缓动：使用超弹性曲线 [0.68, -0.6, 0.32, 1.6]，产生夸张的反向弹跳
 *
 * @param {boolean} isVisible - 子菜单是否可见
 *   - true: 子菜单应该展开，执行展开动画
 *   - false: 子菜单应该收起，执行收起动画
 * @returns {object} 返回包含以下属性的对象：
 *   - controls: motion 动画控制器，绑定到 motion.div 的 animate 属性
 */
export function useChildMenuAnimation(isVisible) {
  // ==================== 状态和引用管理 ====================

  // motion 动画控制器，用于控制 motion.div 的动画
  const controls = useAnimation();

  // 标记子菜单是否已经执行过展开动画
  // 作用：防止重复执行展开动画，只在首次显示时执行
  const isExpanded = useRef(false);

  // 标记是否是首次渲染
  // 作用：首次渲染时需要特殊处理，确保初始状态正确设置
  const isFirstRender = useRef(true);

  useEffect(() => {
    // ==================== 首次渲染 ====================
    if (isFirstRender.current) {
      if (isVisible) {
        // ===== 执行展开动画：从下向上炫酷弹跳进入 =====
        controls.start({
          // Y 轴位置关键帧（四个关键帧实现弹跳效果）：
          // ① 80：从下方 80px 处开始
          // ② -15：快速冲到上方 15px（超出目标位置，产生过冲效果）
          // ③ 5：轻微回落到下方 5px
          // ④ 0：最终稳定到正常位置
          y: [80, -15, 5, 0],

          // 透明度关键帧：
          // ① 0：初始完全透明
          // ② 1：快速变为不透明
          // ③ 1：保持不透明
          // ④ 1：保持不透明
          opacity: [0, 1, 1, 1],

          // 缩放关键帧（配合位置变化，增强弹跳感）：
          // ① 0.9：从 90% 大小开始（轻微缩小）
          // ② 1.05：放大到 105%（轻微放大，配合位置过冲）
          // ③ 0.98：缩小到 98%（轻微缩小，配合位置回落）
          // ④ 1：回到正常大小 100%
          scale: [0.9, 1.05, 0.98, 1],

          transition: {
            duration: 0.7, // 总动画时长：0.7 秒
            // 关键帧时间点分布：
            // ① 0：0% 时（0s）在 y=80 处
            // ② 0.5：50% 时（0.35s）在 y=-15 处（过冲峰值）
            // ③ 0.75：75% 时（0.525s）在 y=5 处（回落）
            // ④ 1：100% 时（0.7s）在 y=0 处（稳定）
            times: [0, 0.5, 0.75, 1],

            // 强弹性贝塞尔曲线 [0.34, 1.56, 0.64, 1]：
            // - 第一个值 0.34：控制起始加速度（较小，平稳开始）
            // - 第二个值 1.56：控制起始减速度（大于 1，产生过冲）
            // - 第三个值 0.64：控制结束加速度（小于 1，平滑过渡）
            // - 第四个值 1：控制结束减速度（正常结束）
            // 这个曲线会产生明显的过冲和回弹效果
            ease: [0.34, 1.56, 0.64, 1],
          },
        }).then(() => {
          // ===== 动画完成，标记状态 =====
          isExpanded.current = true; // 标记已展开
          isFirstRender.current = false; // 标记首次渲染完成
        });
      }
      else {
        // 如果首次渲染时不需要显示，直接标记首次渲染完成
        isFirstRender.current = false;
      }
      return;
    }

    // ==================== 展开动画（非首次渲染）====================
    if (isVisible && !isExpanded.current) {
      // ===== 从下向上炫酷弹跳进入 =====
      controls.start({
        y: [80, -15, 5, 0], // 位置：下方80px -> 上方15px（过冲）-> 下方5px（回落）-> 正常
        opacity: [0, 1, 1, 1], // 透明度：透明 -> 不透明 -> 不透明 -> 不透明
        scale: [0.9, 1.05, 0.98, 1], // 缩放：90% -> 105% -> 98% -> 100%
        transition: {
          duration: 0.7, // 总动画时长：0.7 秒
          times: [0, 0.5, 0.75, 1], // 时间点分布
          ease: [0.34, 1.56, 0.64, 1], // 强弹性贝塞尔曲线
        },
      }).then(() => {
        isExpanded.current = true; // 标记已展开
      });
    }

    // ==================== 收起动画 ====================
    else if (!isVisible && isExpanded.current) {
      // ===== 从上向下炫酷弹跳离开 =====
      controls.start({
        // Y 轴位置关键帧：
        // ① 0：从正常位置开始
        // ② -20：向上弹跳到上方 20px（反向过冲）
        // ③ 10：回落到下方 10px
        // ④ 100：向下离开到 100px 处
        y: [0, -20, 10, 100],

        // 透明度关键帧：
        // ① 1：初始不透明
        // ② 1：弹跳过程中保持不透明
        // ③ 0.8：开始淡出
        // ④ 0：完全透明
        opacity: [1, 1, 0.8, 0],

        // 缩放关键帧：
        // ① 1：从正常大小开始
        // ② 1.02：轻微放大到 102%（配合向上弹跳）
        // ③ 0.95：缩小到 95%（配合回落）
        // ④ 0.85：继续缩小到 85%（配合向下离开）
        scale: [1, 1.02, 0.95, 0.85],

        transition: {
          duration: 0.5, // 总动画时长：0.5 秒（比进入动画短，显得更轻快）
          // 关键帧时间点分布：
          // ① 0：0% 时（0s）在正常位置 y=0
          // ② 0.2：20% 时（0.1s）在 y=-20 处（快速弹起）
          // ③ 0.5：50% 时（0.25s）在 y=10 处（回落）
          // ④ 1：100% 时（0.5s）在 y=100 处（完全离开）
          times: [0, 0.2, 0.5, 1],

          // 超弹性曲线 [0.68, -0.6, 0.32, 1.6]：
          // - 第一个值 0.68：较大的起始加速度
          // - 第二个值 -0.6：负值表示反向过冲（产生夸张的向上弹跳）
          // - 第三个值 0.32：较小的结束加速度
          // - 第四个值 1.6：大于 1 的结束减速度（产生回弹效果）
          // 这个曲线会产生夸张的反向弹跳效果
          ease: [0.68, -0.6, 0.32, 1.6],
        },
      }).then(() => {
        isExpanded.current = false; // 标记已收起
      });
    }
  }, [isVisible, controls]);

  // 返回动画控制器
  return {
    controls,
  };
}
