<template>
  <uni-popup
    class="upgrade-unipopup"
    ref="popup"
    type="center"
    :animation="false"
    :mask-click="false"
    style="z-index: 999">
    <view class="upgrade-popup">
      <image
        class="header-bg"
        src="../static/common/upgrade_bg.png"
        mode="widthFix"></image>
      <view class="main">
        <view class="version"
          >{{ t("version.newVersion") }}{{ versionName }}</view
        >
        <view class="content" v-if="versionDesc">
          <text class="title">{{ t("version.updateInfo") }}</text>
          <view class="desc" v-html="versionDesc"></view>
        </view>

        <!--下载状态-进度条显示 -->
        <view class="footer" v-if="isStartDownload">
          <view class="progress-view" @click="handleInstallApp">
            <view style="height: 100%">
              <view class="txt">{{ percentText }}</view>
              <view class="progress" :style="setProStyle"></view>
            </view>
          </view>
        </view>
        <!-- 强制更新 -->
        <view class="footer" v-else-if="isForceUpdate">
          <view class="btn upgrade force" @click="handleUpgrade">{{
            t("version.updateNow")
          }}</view>
        </view>
        <!-- 可选择更新 -->
        <view class="footer" v-else>
          <view class="btn close" @click="handleClose">{{
            t("version.updateLater")
          }}</view>
          <view class="btn upgrade" @click="handleUpgrade">{{
            t("version.updateNow")
          }}</view>
        </view>
      </view>
    </view>
  </uni-popup>
</template>

<script>
import {
  consumePendingAppUpgradeCheck,
  isHotUpdateRunning,
  HOT_UPDATE_FALLBACK_APP_CHECK_EVENT,
} from "@/utils/hot-update.js";
import { getAppVersion } from "@/api/app.js";
import { checkVersion, downloadApp, installApp } from "@/utils/upgrade.js";
// 引用全局变量$t
import { getCurrentInstance } from "vue";

export default {
  data() {
    return {
      isForceUpdate: true, //是否强制更新
      versionName: "", //版本名称
      versionDesc: "", //更新说明
      downloadUrl: "", //APP下载链接
      isDownloadFinish: false, //是否下载完成
      hasProgress: false, //是否能显示进度条
      currentPercent: 0, //当前下载百分比
      isStartDownload: false, //是否开始下载
      fileName: "", //下载后app本地路径名称
      hasTriggeredStartupAppCheck: false,
      pendingHotUpdateFallbackAppCheck: false,

      t: null, // 全局翻译函数
    };
  },
  computed: {
    //设置进度条样式，实时更新进度位置
    setProStyle() {
      return {
        width: (510 * this.currentPercent) / 100 + "rpx", //510：按钮进度条宽度
      };
    },
    //百分比文字
    percentText() {
      let percent = this.currentPercent;
      if (typeof percent !== "number" || isNaN(percent))
        return this.t("version.downloading"); // 下载中
      if (percent < 100) return `${this.t("version.download")}${percent}%`;
      return this.t("version.install"); // 下载完成
    },
  },

  onBackPress(options) {
    // 禁用返回
    if (options.from == "backbutton") {
      return true;
    }
  },
  mounted() {
    const { appContext } = getCurrentInstance();
    const t = appContext.config.globalProperties.$t;
    this.t = t;

    //检测版本
    // #ifdef APP
    /**
     * 这里保留原来的页面级整包更新检查，但增加一个非常轻量的互斥判断。
     *
     * 为什么要加这层判断：
     * 1. 当前项目原本就在登录页和首页自动挂载这个组件。
     * 2. 本次新增的 .wgt 热更新改到了 App 启动阶段，如果这里还无条件发起旧检查，
     *    启动时就可能同时出现“热更新弹窗”和“整包升级弹窗”。
     * 3. 这不是为了废掉原有逻辑，而是为了让原有逻辑在“启动热更新正在执行”时先让路，
     *    避免两个升级流程互相打架。
     *
     * 不加这段代码会怎样：
     * - App.vue onLaunch 触发热更新检查
     * - 页面 mounted 又触发旧的整包升级检查
     * - 用户可能连续看到两个升级提示，甚至两个流程同时下载，体验会非常差
     */

    if (this.pendingHotUpdateFallbackAppCheck) {
      this.triggerStartupAppCheckOnce();
    } else if (!isHotUpdateRunning()) {
      this.triggerStartupAppCheckOnce();
    } else {
      console.log(
        "skip page upgrade check because startup hot update is running"
      );
    }
    // #endif
  },
  created() {
    this.pendingHotUpdateFallbackAppCheck = consumePendingAppUpgradeCheck();
    uni.$on("upgrade-app", this.bindEmit);
    uni.$on(
      HOT_UPDATE_FALLBACK_APP_CHECK_EVENT,
      this.handleHotUpdateFallbackAppCheck
    );
  },
  beforeDestroy() {
    uni.$off("upgrade-app", this.bindEmit);
    uni.$off(
      HOT_UPDATE_FALLBACK_APP_CHECK_EVENT,
      this.handleHotUpdateFallbackAppCheck
    );
  },
  methods: {
    triggerStartupAppCheckOnce() {
      if (this.hasTriggeredStartupAppCheck) return;
      this.hasTriggeredStartupAppCheck = true;
      this.appCheckVersion();
    },
    handleHotUpdateFallbackAppCheck() {
      consumePendingAppUpgradeCheck();
      if (!this.t) {
        this.pendingHotUpdateFallbackAppCheck = true;
        return;
      }

      this.pendingHotUpdateFallbackAppCheck = false;
      this.triggerStartupAppCheckOnce();
    },
    async appCheckVersion() {
      const { data: remote } = await getAppVersion();
      const up = await checkVersion({
        name: remote.appVersion, //最新版本名称
        code: remote.appVersion, //最新版本号
        content: "", //更新内容
        url: remote.url, //下载链接
        forceUpdate: true, //是否强制升级
      });

      if (up) {
        this.open();
      }
    },
    open() {
      //打开升级弹窗
      console.log("open upgrade popup");
      this.$refs.popup.open();
    },
    bindEmit(e) {
      let { name, content, url, forceUpdate } = e;
      this.isForceUpdate = forceUpdate;
      this.versionName = name;
      this.versionDesc = content;
      this.downloadUrl = url;
    },
    //更新
    handleUpgrade() {
      if (this.downloadUrl) {
        this.isStartDownload = true;
        this.currentPercent = 0; // 初始化进度
        downloadApp(this.downloadUrl, (current, downloadedSize, totalSize) => {
          // 始终显示进度条，无需hasProgress判断
          this.currentPercent = current;
        })
          .then((fileName) => {
            this.isDownloadFinish = true;
            this.fileName = fileName;
            this.currentPercent = 100; // 确保最终显示100%
            if (fileName) {
              // 下载完成后，自动安装
              console.log("🚀 ~ handleUpgrade ~ fileName:", fileName);
              this.handleInstallApp();
            }
          })
          .catch((e) => {
            console.error("🚀 ~ handleUpgrade ~ e:", e);
            this.currentPercent = 0; // 失败时重置
          });
      } else {
        uni.showToast({
          title: this.t("version.downloadLinkNotExist"),
          icon: "none",
        });
      }
    },
    //安装app
    handleInstallApp() {
      //下载完成才能安装，防止下载过程中点击
      if (this.isDownloadFinish && this.fileName) {
        installApp(this.fileName, () => {
          this.$refs.popup.close();
          //安装成功,关闭升级弹窗
          // uni.navigateBack()
        });
      }
    },
    //关闭返回
    handleClose() {
      // uni.navigateBack()
      this.$refs.popup.close();
    },
  },
};
</script>

<style>
page {
  background: rgba(0, 0, 0, 0.5);
  /**设置窗口背景半透明*/
}
</style>
<style lang="scss" scoped>
:deep(.upgrade-unipopup) {
  z-index: 9999 !important;
}
.upgrade-popup {
  width: 580rpx;
  height: auto;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: #fff;
  border-radius: 20rpx;
  box-sizing: border-box;
  border: 1px solid #eee;
}

.header-bg {
  width: 100%;
  margin-top: -112rpx;
}

.main {
  padding: 10rpx 30rpx 30rpx;
  box-sizing: border-box;

  .version {
    font-size: 36rpx;
    color: #026df7;
    font-weight: 700;
    width: 100%;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    letter-spacing: 1px;
  }

  .content {
    margin-top: 60rpx;

    .title {
      font-size: 28rpx;
      font-weight: 700;
      color: #000000;
    }

    .desc {
      box-sizing: border-box;
      margin-top: 20rpx;
      font-size: 28rpx;
      color: #6a6a6a;
      max-height: 40vh;
      overflow-y: auto;
    }
  }

  .footer {
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
    flex-shrink: 0;
    margin-top: 100rpx;

    .btn {
      width: 246rpx;
      display: flex;
      justify-content: center;
      align-items: center;
      position: relative;
      z-index: 999;
      height: 96rpx;
      box-sizing: border-box;
      font-size: 32rpx;
      border-radius: 10rpx;
      letter-spacing: 2rpx;

      &.force {
        width: 500rpx;
      }

      &.close {
        border: 1px solid #e0e0e0;
        margin-right: 25rpx;
        color: #000;
      }

      &.upgrade {
        background-color: #026df7;
        color: white;
      }
    }

    .progress-view {
      width: 510rpx;
      height: 90rpx;
      display: flex;
      position: relative;
      align-items: center;
      border-radius: 6rpx;
      background-color: #dcdcdc;
      display: flex;
      justify-content: flex-start;
      padding: 0px;
      box-sizing: border-box;
      border: none;
      overflow: hidden;

      &.active {
        background-color: #026df7;
      }

      .progress {
        height: 100%;
        background-color: #026df7;
        padding: 0px;
        box-sizing: border-box;
        border: none;
        border-top-left-radius: 10rpx;
        border-bottom-left-radius: 10rpx;
        transition: width 0.3s ease; // 添加平滑过渡动画
      }

      .txt {
        font-size: 28rpx;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        color: #fff;
      }
    }
  }
}
</style>
