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

/**
 * CenterUtils 弹跳动画 Hook
 *
 * 功能说明：
 * 1. 监听组件的显示/隐藏状态变化
 * 2. 执行炫酷的弹跳动画效果（类似 animate.css 的 bounceIn/bounceOut）
 * 3. 支持多种动画类型（上下弹跳、缩放弹跳）
 * 4. 使用弹跳、缩放、透明度三重动画效果，让动画更加生动
 * 5. 延迟隐藏机制，确保离开动画完整播放
 *
 * 动画效果详解（上下弹跳模式 up-down）：
 * - 进入动画：
 *   - 位置：从上方 120px 处冲到下方 40px（超出目标），轻微上弹到 -10px，最后稳定到 0
 *   - 缩放：从 0.9 倍缩小到 1.05 倍（轻微放大），轻微缩小到 0.98，回到正常 1.0
 *   - 透明度：从透明到不透明
 *   - 时长：0.7 秒
 *   - 缓动：使用强弹性贝塞尔曲线 [0.34, 1.56, 0.64, 1]，产生明显的过冲和回弹效果
 *
 * - 离开动画：
 *   - 位置：从正常位置向上弹跳 50px，回落到 20px，然后向上离开到 -120px
 *   - 缩放：轻微放大到 1.02，然后缩小到 0.85
 *   - 透明度：保持可见再淡出
 *   - 时长：0.5 秒
 *   - 缓动：使用超弹性曲线 [0.68, -0.6, 0.32, 1.6]，产生夸张的反向弹跳
 *
 * 动画效果详解（缩放弹跳模式 scale）：
 * - 进入动画：
 *   - 缩放：从 0 放大到 1.15 倍（超出目标），缩小到 0.92，回到正常 1.0
 *   - 时长：0.7 秒
 *   - 缓动：使用强弹性贝塞尔曲线
 *
 * - 离开动画：
 *   - 缩放：从 1.0 放大到 1.1，缩小到 0.85，最后消失到 0
 *   - 时长：0.5 秒
 *   - 缓动：使用超弹性曲线
 *
 * @param {boolean} isVisible - 控制组件的显示/隐藏
 *   - true: 组件应该显示，执行进入动画
 *   - false: 组件应该隐藏，执行离开动画
 * @param {string} type - 动画类型
 *   - 'up-down'：上下弹跳动画（默认值，从上方进入，向上方离开）
 *   - 'scale'：缩放弹跳动画（从中心放大进入，缩小离开）
 * @returns {object} 返回包含以下属性的对象：
 *   - controls: motion 动画控制器，绑定到 motion.div 的 animate 属性
 *   - isVisible: 延迟的可见性状态（用于等待离开动画完成后再隐藏组件）
 */
export function useCenterUtilsAnimation(isVisible, type = "up-down") {
  // ==================== 状态和引用管理 ====================

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

  // 标记是否是首次渲染
  // 作用：首次渲染时需要特殊处理，确保初始状态正确设置
  // 首次渲染不执行离开动画，直接执行进入动画
  const isFirstRender = useRef(true);

  // 组件的实际显示状态
  // 作用：延迟隐藏，确保离开动画执行完成后才将组件从 DOM 中移除
  const [displayState, setDisplayState] = useState(isVisible);

  useEffect(() => {
    // ==================== 显示状态：执行进入动画 ====================
    if (isVisible) {
      // 步骤 1：确保组件处于显示状态
      if (!displayState) {
        setDisplayState(true);
      }

      // 步骤 2：根据动画类型执行进入动画
      // ----------------------------------------------------------------

      // 类型 1：上下弹跳动画（炫酷 bounceInDown 效果）
      if (type === "up-down") {
        if (isFirstRender.current) {
          // === 首次渲染：炫酷弹跳进入 ===
          controls.start({
            y: [-120, 40, -10, 0], // 四个关键帧：上方120px -> 超出下方40px（大弹跳）-> 轻微上弹 -> 稳定
            opacity: [0, 1, 1, 1], // 快速淡入
            scale: [0.9, 1.05, 0.98, 1], // 缩放：缩小 -> 轻微放大 -> 轻微缩小 -> 正常
            transition: {
              duration: 0.7, // 总动画时长：0.7 秒
              times: [0, 0.5, 0.75, 1], // 时间点分布：快速下落，多次回弹
              ease: [0.34, 1.56, 0.64, 1], // 强弹性贝塞尔曲线，产生明显的回弹效果
            },
          }).then(() => {
            isFirstRender.current = false;
          });
        }
        else {
          // === 非首次渲染：炫酷弹跳进入 ===
          controls.start({
            y: [-120, 40, -10, 0],
            opacity: [0, 1, 1, 1],
            scale: [0.9, 1.05, 0.98, 1],
            transition: {
              duration: 0.7,
              times: [0, 0.5, 0.75, 1],
              ease: [0.34, 1.56, 0.64, 1],
            },
          });
        }
      }
      // ----------------------------------------------------------------

      // 类型 2：缩放弹跳动画（炫酷 bounceIn 效果）
      else if (type === "scale") {
        if (isFirstRender.current) {
          // === 首次渲染：炫酷缩放弹跳 ===
          controls.start({
            scale: [0, 1.15, 0.92, 1], // 四个关键帧：0 -> 超出115% -> 缩小到92% -> 正常
            opacity: [0, 1, 1, 1],
            transition: {
              duration: 0.7,
              times: [0, 0.4, 0.7, 1], // 时间点分布
              ease: [0.34, 1.56, 0.64, 1], // 强弹性曲线
            },
          }).then(() => {
            isFirstRender.current = false;
          });
        }
        else {
          // === 非首次渲染：炫酷缩放弹跳 ===
          controls.start({
            scale: [0, 1.15, 0.92, 1],
            opacity: [0, 1, 1, 1],
            transition: {
              duration: 0.7,
              times: [0, 0.4, 0.7, 1],
              ease: [0.34, 1.56, 0.64, 1],
            },
          });
        }
      }
    }

    // ==================== 隐藏状态：执行离开动画 ====================
    else {
      // 步骤 1：根据动画类型执行离开动画
      // ----------------------------------------------------------------

      // 类型 1：上下弹跳动画（炫酷 bounceOutUp 效果）
      if (type === "up-down") {
        controls.start({
          y: [0, -50, 20, -120], // 四个关键帧：正常 -> 超出上方50px -> 回落 -> 向上离开
          opacity: [1, 1, 0.8, 0], // 保持可见再淡出
          scale: [1, 1.02, 0.95, 0.85], // 缩放：轻微放大 -> 轻微缩小
          transition: {
            duration: 0.5, // 总动画时长：0.5 秒
            times: [0, 0.2, 0.5, 1], // 时间点分布：快速弹起，缓慢落下
            ease: [0.68, -0.6, 0.32, 1.6], // 超弹性曲线，产生夸张的回弹效果
          },
        }).then(() => {
          setDisplayState(false);
        });
      }
      // ----------------------------------------------------------------

      // 类型 2：缩放弹跳动画（炫酷 bounceOut 效果）
      else if (type === "scale") {
        controls.start({
          scale: [1, 1.1, 0.85, 0], // 四个关键帧：正常 -> 放大到110% -> 缩小到85% -> 消失
          opacity: [1, 1, 0.6, 0],
          transition: {
            duration: 0.5,
            times: [0, 0.3, 0.6, 1],
            ease: [0.68, -0.6, 0.32, 1.6], // 超弹性曲线
          },
        }).then(() => {
          setDisplayState(false);
        });
      }
    }
  }, [isVisible, type, controls, displayState]);

  // 返回动画控制器和延迟的可见性状态
  // - controls：用于绑定到 motion.div 的 animate 属性
  // - isVisible：延迟的可见性状态，用于条件渲染（等待离开动画完成）
  return {
    controls,
    isVisible: displayState,
  };
}
