<template>
  <view class="mask flex-center">
    <view class="content botton-radius">
      <view class="content-top">
        <text class="content-top-text">{{ title }}</text>
        <image
          class="content-top"
          style="top: 0"
          width="100%"
          height="100%"
          src="../../static/images/app_update_bg_top.png"
        >
        </image>
      </view>
      <view class="content-header"></view>
      <view class="content-body">
        <view class="title">
          <text>{{ subTitle }}</text>
          <!-- <text style="padding-left:20rpx;font-size: 0.5em;color: #666;">v.{{version}}</text> -->
        </view>
        <view class="body">
          <scroll-view class="box-des-scroll" scroll-y="true">
            <text class="box-des">
              {{ contents }}
            </text>
          </scroll-view>
        </view>
        <view class="footer flex-center">
          <template v-if="isiOS">
            <button class="content-button" style="border: none; color: #fff" plain @click="jumpToAppStore">
              {{ downLoadBtnTextiOS }}
            </button>
          </template>
          <template v-else>
            <template v-if="!downloadSuccess">
              <view class="progress-box flex-column" v-if="downloading">
                <progress
                  class="progress"
                  border-radius="35"
                  :percent="downLoadPercent"
                  activeColor="#3DA7FF"
                  show-info
                  stroke-width="10"
                />
                <view style="width: 100%; font-size: 14px; display: flex; justify-content: space-around">
                  <text>{{ downLoadingText }}</text>
                  <text>({{ downloadedSize }}/{{ packageFileSize }}M)</text>
                </view>
              </view>

              <button v-else class="content-button" style="border: none; color: #fff" plain @click="downloadPackage">
                {{ downLoadBtnText }}
              </button>
            </template>
            <button
              v-else-if="downloadSuccess"
              class="content-button"
              style="border: none; color: #fff"
              plain
              :loading="installing"
              :disabled="installing"
              @click="installPackage"
            >
              {{ installing ? '正在安装……' : '下载完成，立即安装' }}
            </button>

            <button
              v-if="installed && isWGT"
              class="content-button"
              style="border: none; color: #fff"
              plain
              @click="restart"
            >
              安装完毕，点击重启
            </button>
          </template>
        </view>
      </view>

      <image
        v-if="!is_mandatory"
        class="close-img"
        src="../../static/images/app_update_close.png"
        @click.stop="closeUpdate"
      ></image>
    </view>
  </view>
</template>

<script setup>
import { ref, computed } from 'vue'
import { onLoad, onBackPress } from '@dcloudio/uni-app'

const localFilePathKey = '__localFilePath__'
const platform_iOS = 'iOS'
let downloadTask = null

// 工具函数保持原样
function compare(v1 = '0', v2 = '0') {
  v1 = String(v1).split('.')
  v2 = String(v2).split('.')
  const minVersionLens = Math.min(v1.length, v2.length)

  let result = 0
  for (let i = 0; i < minVersionLens; i++) {
    const curV1 = Number(v1[i])
    const curV2 = Number(v2[i])

    if (curV1 > curV2) {
      result = 1
      break
    } else if (curV1 < curV2) {
      result = -1
      break
    }
  }

  if (result === 0 && v1.length !== v2.length) {
    const v1BiggerThenv2 = v1.length > v2.length
    const maxLensVersion = v1BiggerThenv2 ? v1 : v2
    for (let i = minVersionLens; i < maxLensVersion.length; i++) {
      const curVersion = Number(maxLensVersion[i])
      if (curVersion > 0) {
        v1BiggerThenv2 ? (result = 1) : (result = -1)
        break
      }
    }
  }

  return result
}

// 响应式状态
const installForBeforeFilePath = ref('')
const installed = ref(false)
const installing = ref(false)
const downloadSuccess = ref(false)
const downloading = ref(false)
const downLoadPercent = ref(0)
const downloadedSize = ref(0)
const packageFileSize = ref(0)
const tempFilePath = ref('')

const title = ref('更新日志')
const contents = ref('')
const is_mandatory = ref(false)
const subTitle = ref('发现新版本')
const downLoadBtnTextiOS = ref('立即跳转更新')
const downLoadBtnText = ref('立即下载更新')
const downLoadingText = ref('安装包下载中，请稍后')

const version = ref('')
const url = ref('')
const type = ref('')
const platform = ref('')

// 计算属性
const isWGT = computed(() => type.value === 'wgt')
const isiOS = computed(() => !isWGT.value && platform.value.includes(platform_iOS))

// 方法
function checkLocalStoragePackage() {
  const localFilePathRecord = uni.getStorageSync(localFilePathKey)
  if (localFilePathRecord) {
    const { version: recordVersion, savedFilePath, installed: recordInstalled } = localFilePathRecord

    if (!recordInstalled && compare(recordVersion, version.value) === 0) {
      downloadSuccess.value = true
      installForBeforeFilePath.value = savedFilePath
      tempFilePath.value = savedFilePath
    } else {
      deleteSavedFile(savedFilePath)
    }
  }
}

async function closeUpdate() {
  if (downloading.value) {
    if (is_mandatory.value) {
      uni.showToast({ title: '下载中，请稍后……', icon: 'none', duration: 500 })
      return
    }
    uni.showModal({
      title: '是否取消下载？',
      cancelText: '否',
      confirmText: '是',
      success: res => {
        if (res.confirm) {
          downloadTask?.abort()
          uni.navigateBack()
        }
      }
    })
    return
  }

  if (downloadSuccess.value && tempFilePath.value) {
    await saveFile(tempFilePath.value, version.value)
    uni.navigateBack()
    return
  }

  uni.navigateBack()
}

function downloadPackage() {
  downloading.value = true
  downloadTask = uni.downloadFile({
    url: url.value,
	header:{
		"Accept-Encoding": "identity"
	},
    success: res => {
      if (res.statusCode === 200) {
        downloadSuccess.value = true
        tempFilePath.value = res.tempFilePath
        // 强制更新
        if (is_mandatory.value) {
          installPackage()
        }
      }
    },
    complete: () => {
      downloading.value = false
      downLoadPercent.value = 0
      downloadedSize.value = 0
      packageFileSize.value = 0
      downloadTask = null
    }
  })

  downloadTask.onProgressUpdate(res => {
    downLoadPercent.value = res.progress
    downloadedSize.value = (res.totalBytesWritten / 1024 ** 2).toFixed(2)
    packageFileSize.value = (res.totalBytesExpectedToWrite / 1024 ** 2).toFixed(2)
  })
}

function installPackage() {
  // #ifdef APP-PLUS
  if (isWGT.value) {
    installing.value = true
  }

  plus.runtime.install(
    tempFilePath.value,
    {
      force: false
    },
    async () => {
      installing.value = false
      installed.value = true

      if (isWGT.value) {
        if (is_mandatory.value) {
          uni.showLoading({ icon: 'none', title: '安装成功，正在重启……' })
          setTimeout(() => {
            uni.hideLoading()
            restart()
          }, 1000)
        }
      } else {
        const localFilePathRecord = uni.getStorageSync(localFilePathKey)
        uni.setStorageSync(localFilePathKey, {
          ...localFilePathRecord,
          installed: true
        })
      }
    },
    async err => {
      if (installForBeforeFilePath.value) {
        await deleteSavedFile(installForBeforeFilePath.value)
        installForBeforeFilePath.value = ''
      }

      installing.value = false
      installed.value = false

      uni.showModal({
        title: `更新失败${isWGT.value ? '' : '，APK文件不存在'}，请重新下载`,
        content: err.message,
        showCancel: false
      })
    }
  )

  if (!isWGT.value) {
    uni.navigateBack()
  }
  // #endif
}

function restart() {
  installed.value = false
  // #ifdef APP-PLUS
  plus.runtime.restart()
  // #endif
}

async function saveFile(tempFilePath, version) {
  try {
    const res = await uni.saveFile({ tempFilePath })
    uni.setStorageSync(localFilePathKey, {
      version,
      savedFilePath: res.savedFilePath
    })
  } catch (err) {
    console.error('保存文件失败:', err)
  }
}

async function deleteSavedFile(filePath) {
  try {
    await uni.removeSavedFile({ filePath })
    uni.removeStorageSync(localFilePathKey)
  } catch (err) {
    console.error('删除文件失败:', err)
  }
}

function jumpToAppStore() {
  plus.runtime.openURL(url.value)
}

// 生命周期
onLoad(params => {
  const { local_storage_key } = params
  if (!local_storage_key) {
    console.error('local_storage_key为空')
    // uni.navigateBack()
    return
  }

  const localPackageInfo = uni.getStorageSync(local_storage_key)
  if (!localPackageInfo) {
    console.error('安装包信息为空')
    uni.navigateBack()
    return
  }

  const requiredKeys = ['version', 'url', 'type']
  for (const key of requiredKeys) {
    if (!localPackageInfo[key]) {
      console.error(`参数 ${key} 必填`)
      uni.navigateBack()
      return
    }
  }

  // 更新响应式状态
  version.value = localPackageInfo.version
  url.value = localPackageInfo.url
  type.value = localPackageInfo.type
  platform.value = localPackageInfo.platform || ''
  title.value = localPackageInfo.title || '更新日志'
  contents.value = localPackageInfo.contents || ''
  is_mandatory.value = localPackageInfo.is_mandatory || false
  subTitle.value = localPackageInfo.subTitle || '发现新版本'
  downLoadBtnTextiOS.value = localPackageInfo.downLoadBtnTextiOS || '立即跳转更新'
  downLoadBtnText.value = localPackageInfo.downLoadBtnText || '立即下载更新'
  downLoadingText.value = localPackageInfo.downLoadingText || '安装包下载中，请稍后'

  checkLocalStoragePackage()
})

onBackPress(() => {
  if (is_mandatory.value) return true
  if (downloadTask) downloadTask.abort()
  return false
})
</script>

<style>
page {
  background: transparent;
}

.flex-center {
  /* #ifndef APP-NVUE */
  display: flex;
  /* #endif */
  justify-content: center;
  align-items: center;
}

.mask {
  position: fixed;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.65);
}

.botton-radius {
  border-bottom-left-radius: 15px;
  border-bottom-right-radius: 15px;
}

.content {
  position: relative;
  top: 0;
  width: 400px;
  background-color: #fff;
  box-sizing: border-box;
  padding: 0 30px;
  font-family: Source Han Sans CN;
  max-height: 80vh;
  overflow: hidden;
  border-radius: 20px;
}

.content-top {
  position: absolute;
  top: -55px;
  left: 0;
  width: 400px;
  height: 180px;
}

.content-top-text {
  font-size: 24px;
  font-weight: bold;
  color: #f8f8fa;
  position: absolute;
  top: 80px;
  left: 30px;
  z-index: 1;
}

.content-header {
  padding-top: 80px;
  height: 40px;
}

.content-body {
  padding-bottom: 20px;
}

.title {
  font-size: 20px;
  font-weight: bold;
  color: #3da7ff;
  line-height: 1.5;
  margin-bottom: 15px;
}

.footer {
  height: 90px;
  display: flex;
  align-items: center;
  justify-content: space-around;
  margin-top: 15px;
}

.box-des-scroll {
  box-sizing: border-box;
  padding: 0 20px;
  height: 50px;
  text-align: left;
  margin-bottom: 15px;
}

.box-des {
  font-size: 16px;
  color: #000000;
  line-height: 1.5;
}

.progress-box {
  width: 100%;
}

.progress {
  width: 90%;
  height: 20px;
  border-radius: 10px;
  margin-bottom: 10px;
}

.close-img {
  width: 40px;
  height: 40px;
  z-index: 1000;
  position: absolute;
  bottom: -70px;
  left: calc(50% - 20px);
}

.content-button {
  text-align: center;
  flex: 1;
  font-size: 18px;
  font-weight: 400;
  color: #ffffff;
  border-radius: 20px;
  margin: 0 10px;
  height: 50px;
  line-height: 50px;
  background: linear-gradient(to right, #1785ff, #3da7ff);
  min-width: 160px;
}

.flex-column {
  display: flex;
  flex-direction: column;
  align-items: center;
}
</style>
