<template>
	<view v-show="shown" class="mask flex-center">
		<view class="content">

			<view class="content-top">
				<text class="content-top-text">{{title}}</text>
				<image class="content-top-image" mode="widthFix"
					src="/uni_modules/uni-upgrade-center-app/static/bg_top.png"></image>
			</view>

			<view class="content-body">
				<view class="content-body-title">
					<text class="text title">{{subTitle}}</text>
					<text class="text version">v{{version}}</text>
				</view>
				<view class="body">
					<scroll-view class="box-des-scroll" scroll-y="true">
						<text class="text 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" :percent="downLoadPercent" activeColor="#3DA7FF" :show-info="true" :stroke-width="10" />
								<view style="width:100%;display: flex;justify-content: space-around;flex-direction: row;">
									<text class="text" style="font-size: 14px;">{{downLoadingText}}</text>
									<text class="text" style="font-size: 14px;">({{downloadedSize}}/{{packageFileSize}}M)</text>
								</view>
							</view>

							<button v-else class="content-button" @click="updateApp">
								{{downLoadBtnText}}
							</button>
						</template>

						<button v-else-if="downloadSuccess && !installed" class="content-button" :loading="installing" :disabled="installing" @click="installPackage">
							{{installing ? '正在安装……' : '下载完成，立即安装'}}
						</button>

						<button v-else-if="installed" class="content-button" @click="installPackage">
							安装未完成，点击安装
						</button>
					</template>
				</view>
			</view>

			<view class="content-bottom">
				<image v-if="!is_mandatory" class="close-img" mode="widthFix" src="/uni_modules/uni-upgrade-center-app/static/app_update_close.png" @click="closeUpdate">
				</image>
			</view>
		</view>
	</view>
</template>

<script>
	import { openSchema as utsOpenSchema } from '@/uni_modules/uts-openSchema'
  import { createNotificationProgress, cancelNotificationProgress, finishNotificationProgress } from '@/uni_modules/uts-progressNotification'
  import { type CreateNotificationProgressOptions, type FinishNotificationProgressOptions } from '@/uni_modules/uts-progressNotification/utssdk/interface.uts'
	import { UniUpgradeCenterResult, StoreListItem } from '../../utils/call-check-version'

	const platform_iOS = 'iOS';
	const platform_Android = 'Android';
	const requiredKey = ['version', 'url', 'type']
	let downloadTask : DownloadTask | null = null;
	let openSchemePromise: Promise<boolean> | null = null;

	const openSchema = (url: string): Promise<boolean> => new Promise<boolean>((resolve,reject) =>{
    try{
      utsOpenSchema(url)
      resolve(true)
    }catch(e){
      reject(false)
    }
  })

	export default {
    emits: ['close', 'show'],
		data() {
			return {
				shown: false,
				// 从之前下载安装
				installForBeforeFilePath: '',

				// 安装
				installed: false,
				installing: false,

				// 下载
				downloadSuccess: false,
				downloading: false,

				downLoadPercent: 0,
				downloadedSize: 0,
				packageFileSize: 0,

				tempFilePath: '', // 要安装的本地包地址

				// 默认安装包信息
				title: '更新日志',
				contents: '',
				version: '',
				is_mandatory: false,
				url: "",
				platform: [] as string[],
        store_list: null as StoreListItem[] | null,

				// 可自定义属性
				subTitle: '发现新版本',
				downLoadBtnTextiOS: '立即跳转更新',
				downLoadBtnText: '立即下载更新',
				downLoadingText: '安装包下载中，请稍后'
			}
		},
		computed: {
			isiOS() : boolean {
				return this.platform.includes(platform_iOS);
			},
      isAndroid() : boolean {
				return this.platform.includes(platform_Android);
			},
			needNotificationProgress(): boolean {
				return this.isAndroid && !this.is_mandatory
			}
		},
    beforeUnmount() {
      if (this.needNotificationProgress) {
        cancelNotificationProgress()
      }
    },
		methods: {
      jumpToAppStore() {
        openSchema(this.url)
      },
			show(shown : boolean, localPackageInfo : UniUpgradeCenterResult | null) {
				if (localPackageInfo === null) return;

				for (let key in localPackageInfo) {
					if (requiredKey.indexOf(key) != -1 && localPackageInfo[key] === null) {
						console.error(`参数 ${key} 必填，请检查后重试`)
						uni.navigateBack()
						return;
					}
				}

				this.title = localPackageInfo.title
				this.url = localPackageInfo.url
				this.contents = localPackageInfo.contents
				this.is_mandatory = localPackageInfo.is_mandatory
				this.platform = localPackageInfo.platform
				this.version = localPackageInfo.version
        this.store_list = localPackageInfo.store_list
				this.shown = shown

        this.$emit('show')
			},
      askAbortDownload() {
        uni.showModal({
          title: '是否取消下载？',
          cancelText: '否',
          confirmText: '是',
          success: res => {
            if (res.confirm) {
              if (downloadTask !== null) downloadTask!.abort()
              this.closePopup()
            }
          }
        });
      },
			closeUpdate() {
				if (this.downloading) {
					if (this.is_mandatory) {
						return uni.showToast({
							title: '下载中，请稍后……',
							icon: 'none',
							duration: 500
						})
					}
          if (!this.needNotificationProgress) {
            this.askAbortDownload()
            return;
          }
				}
				this.closePopup()
			},
			closePopup() {
				this.shown = false
				this.downloadSuccess = false
				this.downloading = false
				this.downLoadPercent = 0
				this.downloadedSize = 0
				this.packageFileSize = 0
				this.tempFilePath = ''

				this.installing = false
				this.installed = false

        if (this.needNotificationProgress) cancelNotificationProgress()
        this.$emit('close')
			},
			updateApp() {
        const checkStoreScheme = this.checkStoreScheme()
        if (checkStoreScheme !== null) {
          checkStoreScheme
            .then(_ => { })
            .catch(() => { this.downloadPackage() })
            .finally(() => {
              openSchemePromise = null
            })
        } else { this.downloadPackage() }
			},
      // 跳转应用商店
      checkStoreScheme(): Promise<boolean> | null {
        if (this.store_list !== null) {
          const storeList: StoreListItem[] = this.store_list!.filter((item: StoreListItem): boolean => item.enable)
          if (storeList.length > 0) {
            if (openSchemePromise === null) {
              openSchemePromise = Promise.reject() as Promise<boolean>
            }
            storeList
              .sort((cur: StoreListItem, next: StoreListItem): number => next.priority - cur.priority)
              .map((item: StoreListItem): string => item.scheme)
              .reduce((promise: Promise<boolean>, cur: string): Promise<boolean> => {
                openSchemePromise = promise.catch((): Promise<boolean> => openSchema(cur))
                return openSchemePromise!
              }, openSchemePromise!)
            return openSchemePromise!
          }
        }

				return null
      },
			downloadPackage() {
				//下载包
				downloadTask = uni.downloadFile({
					url: this.url,
					success: res => {
						if (res.statusCode == 200) {
							this.tempFilePath = res.tempFilePath
							this.downLoadComplete()
						}
					},
					fail: err => {
						console.log('downloadFile err: ', err);
					}
				});
				if (downloadTask !== null) {
					this.downloading = true;
          if (this.needNotificationProgress) {
            this.closePopup()
          }
					downloadTask!.onProgressUpdate(res => {
						this.downLoadPercent = parseFloat(res.progress.toFixed(0));
						this.downloadedSize = parseFloat((res.totalBytesWritten / Math.pow(1024, 2)).toFixed(2));
						this.packageFileSize = parseFloat((res.totalBytesExpectedToWrite / Math.pow(1024, 2)).toFixed(2));

            if (this.needNotificationProgress) {
              createNotificationProgress({
              	title: "升级中心正在下载安装包……",
              	content: `${this.downLoadPercent}%`,
              	progress: this.downLoadPercent,
                onClick: () => {
                  if (!this.downloadSuccess) {
                    this.askAbortDownload()
                  }
                }
              } as CreateNotificationProgressOptions)
            }
					});
				}
			},
			downLoadComplete() {
				this.downloadSuccess = true;
				this.downloading = false;

				this.downLoadPercent = 0
				this.downloadedSize = 0
				this.packageFileSize = 0

				downloadTask = null;

        if (this.needNotificationProgress) {
          finishNotificationProgress({
            title: "安装升级包",
            content: "下载完成",
            onClick(){}
          } as FinishNotificationProgressOptions)

          this.installPackage();
          return
        }

				// 强制更新，直接安装
				if (this.is_mandatory) {
          this.installPackage();
				}
			},
			installPackage() {
				this.installing = true;
				// #ifdef APP
				uni.installApk({
					filePath: this.tempFilePath,
					success: _ => {
						console.log('installApk success');
						this.installing = false;
						this.installed = true;
					},
					fail: err => {
						console.error('installApk fail', err);
						// 安装失败需要重新下载安装包
						this.installing = false;
						this.installed = false;

						uni.showModal({
							title: '更新失败，请重新下载',
							content: `uni.installApk 错误码 ${err.errCode}`,
							showCancel: false
						});
					}
				});

				// 安装跳出覆盖安装，此处直接返回上一页
				if (!this.is_mandatory) {
					uni.navigateBack()
				}
				// #endif
			}
		}
	}
</script>

<style>
	.flex-center {
		/* #ifndef APP-NVUE | UNI-APP-X */
		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, .65);
	}

	.content {
		position: relative;
		top: 0;
		width: 600rpx;
		background-color: transparent;
	}

	.text {
		font-family: Source Han Sans CN;
	}

	.content-top {
		width: 100%;
		border-bottom-color: #fff;
		border-bottom-width: 15px;
		border-bottom-style: solid;
	}

	.content-top-image {
		width: 100%;
		position: relative;
		bottom: -18px;
	}

	.content-top-text {
		font-size: 22px;
		font-weight: bold;
		color: #F8F8FA;
		position: absolute;
		width: 65%;
		top: 77.5px;
		left: 25px;
		z-index: 1;
	}

	.content-body {
		box-sizing: border-box;
		padding: 0 25px;
		width: 100%;
		background-color: #fff;
		border-bottom-left-radius: 15px;
		border-bottom-right-radius: 15px;
	}

	.content-body-title {
		flex-direction: row;
		align-items: center;
	}

	.content-body-title .version {
		padding-left: 10px;
		color: #fff;
		font-size: 10px;
		margin-left: 5px;
		padding: 2px 4px;
		border-radius: 10px;
		background: #50aefd;
	}

	.title {
		font-size: 16px;
		font-weight: bold;
		color: #3DA7FF;
		line-height: 38px;
	}

	.footer {
		height: 75px;
		display: flex;
		align-items: center;
		justify-content: space-around;
	}

	.box-des-scroll {
		box-sizing: border-box;
		padding: 0 15px;
		height: 100px;
	}

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

	.progress-box {
		width: 100%;
	}

	.progress {
		width: 90%;
		height: 20px;
	}

	.content-bottom {
		height: 75px;
	}

	.close-img {
		width: 35px;
		height: 35px;
		z-index: 1000;
		position: relative;
		bottom: -25px;
		left: 132px;
	}

	.content-button {
		width: 100%;
		height: 40px;
		line-height: 40px;

		font-size: 15px;
		font-weight: 400;
		border-radius: 20px;
		border: none;
		color: #fff;

		text-align: center;

		background-color: #1785ff;
	}

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