#include <extra2d/scene/transition_scene.h>
#include <extra2d/graphics/core/render_backend.h>
#include <extra2d/utils/logger.h>

namespace extra2d {

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

/**
 * @brief 场景进入时的回调
 *
 * 调用退出场景的过渡开始回调，初始化进入场景，并启动过渡
 */
void TransitionScene::onEnter() {
  Scene::onEnter();

  if (outScene_) {
    outScene_->onExitTransitionDidStart();
  }

  if (inScene_) {
    inScene_->onEnter();
    inScene_->onAttachToScene(inScene_.get());
  }

  onTransitionStart();
}

/**
 * @brief 场景退出时的回调
 *
 * 调用退出场景的 onExit 和进入场景的过渡完成回调
 */
void TransitionScene::onExit() {
  if (outScene_) {
    outScene_->onExit();
    outScene_->onDetachFromScene();
  }

  if (inScene_) {
    inScene_->onEnterTransitionDidFinish();
  }

  Scene::onExit();
}

/**
 * @brief 更新过渡进度（基类默认实现）
 * @param dt 帧间隔时间（秒）
 *
 * 子类应重写此方法更新动画进度，默认实现简单计时
 */
void TransitionScene::updateTransition(float dt) {
  if (isFinished_ || isCancelled_) {
    return;
  }

  elapsed_ += dt;
  progress_ = duration_ > 0.0f ? std::min(1.0f, elapsed_ / duration_) : 1.0f;

  if (progress_ >= 1.0f) {
    finish();
  }
}

/**
 * @brief 完成过渡
 *
 * 标记过渡完成并调用完成回调
 */
void TransitionScene::finish() {
  if (isFinished_ || isCancelled_) {
    return;
  }

  isFinished_ = true;

  E2D_LOG_DEBUG("TransitionScene::finish - 过渡完成，切换到目标场景");

  if (finishCallback_) {
    finishCallback_();
  }
}

/**
 * @brief 取消过渡
 * @param immediate 是否立即完成（false则回滚到原场景）
 */
void TransitionScene::cancel(bool immediate) {
  if (isFinished_ || isCancelled_) {
    return;
  }

  isCancelled_ = true;

  if (immediate) {
    // 立即完成，切换到新场景
    E2D_LOG_DEBUG("TransitionScene::cancel - 立即完成过渡");
    finish();
  } else {
    // 回滚到原场景
    E2D_LOG_DEBUG("TransitionScene::cancel - 取消过渡，回滚到原场景");
    if (cancelCallback_) {
      cancelCallback_();
    }
  }
}

/**
 * @brief 渲染过渡内容
 * @param renderer 渲染后端引用
 *
 * 默认先渲染退出场景，再渲染进入场景
 */
void TransitionScene::renderContent(RenderBackend &renderer) {
  drawOutScene(renderer);
  drawInScene(renderer);
}

/**
 * @brief 绘制退出场景
 * @param renderer 渲染后端引用
 */
void TransitionScene::drawOutScene(RenderBackend &renderer) {
  if (outScene_) {
    outScene_->renderContent(renderer);
  }
}

/**
 * @brief 绘制进入场景
 * @param renderer 渲染后端引用
 */
void TransitionScene::drawInScene(RenderBackend &renderer) {
  if (inScene_) {
    inScene_->renderContent(renderer);
  }
}

} // namespace extra2d
