#include <extra2d/scene/transition_flip_scene.h>
#include <extra2d/core/math_types.h>
#include <extra2d/graphics/camera/camera.h>
#include <extra2d/graphics/core/render_backend.h>

namespace extra2d {

/**
 * @brief 构造函数，初始化翻页过渡场景
 * @param duration 过渡持续时间（秒）
 * @param inScene 要进入的目标场景
 * @param axis 翻转轴
 */
TransitionFlipScene::TransitionFlipScene(float duration, Ptr<Scene> inScene,
                                         Axis axis)
    : TransitionScene(duration, inScene), axis_(axis) {}

/**
 * @brief 创建翻页过渡场景的静态工厂方法
 * @param duration 过渡持续时间（秒）
 * @param inScene 要进入的目标场景
 * @param axis 翻转轴
 * @return 过渡场景智能指针
 */
Ptr<TransitionFlipScene> TransitionFlipScene::create(float duration,
                                                     Ptr<Scene> inScene,
                                                     Axis axis) {
  return makePtr<TransitionFlipScene>(duration, inScene, axis);
}

/**
 * @brief 启动过渡动画
 *
 * 翻页过渡不需要特殊的初始化
 */
void TransitionFlipScene::onTransitionStart() {
}

/**
 * @brief 更新过渡进度
 * @param dt 帧间隔时间（秒）
 */
void TransitionFlipScene::updateTransition(float dt) {
  TransitionScene::updateTransition(dt);
}

/**
 * @brief 渲染过渡内容
 * @param renderer 渲染后端引用
 *
 * 根据进度控制新旧场景的翻转角度
 */
void TransitionFlipScene::renderContent(RenderBackend &renderer) {
  float easeProgress = progress_ < 0.5f ? 2.0f * progress_ * progress_
                                        : -1.0f + (4.0f - 2.0f * progress_) * progress_;

  float angle = easeProgress * PI_F;

  if (progress_ < 0.5f) {
    if (outScene_) {
      float currentAngle = angle;

      Camera *camera = outScene_->getActiveCamera();
      float originalRotation = camera ? camera->getRotation() : 0.0f;

      if (axis_ == Axis::Horizontal) {
        if (camera) {
          camera->setRotation(originalRotation + currentAngle * RAD_TO_DEG);
        }
      } else {
        if (camera) {
          camera->setRotation(originalRotation - currentAngle * RAD_TO_DEG);
        }
      }

      outScene_->renderContent(renderer);

      if (camera) {
        camera->setRotation(originalRotation);
      }
    }
  } else {
    if (inScene_) {
      float currentAngle = angle - PI_F;

      Camera *camera = inScene_->getActiveCamera();
      float originalRotation = camera ? camera->getRotation() : 0.0f;

      if (axis_ == Axis::Horizontal) {
        if (camera) {
          camera->setRotation(originalRotation + currentAngle * RAD_TO_DEG);
        }
      } else {
        if (camera) {
          camera->setRotation(originalRotation - currentAngle * RAD_TO_DEG);
        }
      }

      inScene_->renderContent(renderer);

      if (camera) {
        camera->setRotation(originalRotation);
      }
    }
  }

}

} // namespace extra2d
