<template>
	<view 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/app/bg_top.png"></image>
			</view>

			<view class="content-space"></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/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 {
		data() {
			return {
				// 从之前下载安装
				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
			}
		},
		onUnload() {
			if (this.needNotificationProgress) {
				cancelNotificationProgress()
			}
		},
		onLoad(onLoadOptions: OnLoadOptions) {
			const local_storage_key: string | null = onLoadOptions['local_storage_key']
			if (local_storage_key == null) {
				console.error('local_storage_key为空，请检查后重试')
				this.closePopup()
				return;
			};

			const localPackageInfo = uni.getStorageSync(local_storage_key);
			if (localPackageInfo == null) {
				console.error('安装包信息为空，请检查后重试')
				this.closePopup()
				return;
			};

			this.show(JSON.parse<UniUpgradeCenterResult>(JSON.stringify(localPackageInfo)) as UniUpgradeCenterResult)
		},
		onBackPress(options : OnBackPressOptions) : boolean | null {
			if (this.is_mandatory) return true
			if (!this.needNotificationProgress) {
				if (downloadTask !== null) {
					downloadTask!.abort()
				}
			}
			return false
		},
		methods: {
			jumpToAppStore() {
				openSchema(this.url)
			},
			show(localPackageInfo : UniUpgradeCenterResult | null) {
				if (localPackageInfo === null) return;

				for (let key in localPackageInfo) {
					if (requiredKey.indexOf(key) != -1 && localPackageInfo[key] === null) {
						console.error(`参数 ${key} 必填，请检查后重试`)
						this.closePopup()
						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
			},
			askAbortDownload() {
				uni.showModal({
					title: '是否取消下载？',
					cancelText: '否',
					confirmText: '是',
					success: res => {
						if (res.confirm) {
							if (downloadTask !== null) downloadTask!.abort()
							this.closePopup()
						}
					}
				});
			},
			closeUpdate() {
				if (this.downloading && !this.needNotificationProgress) {
					this.askAbortDownload()
					return;
				}

				this.closePopup()
			},
			closePopup() {
				this.downloadSuccess = false
				this.downloading = false
				this.downLoadPercent = 0
				this.downloadedSize = 0
				this.packageFileSize = 0
				this.tempFilePath = ''

				this.installing = false
				this.installed = false

				uni.closeDialogPage({
					dialogPage: this.$page
				})
			},
			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<boolean>(() : 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: _ => {
						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-space {
		width: 100%;
		height: 50px;
		background-color: #fff;
		position: absolute;
		top: 140px;
		z-index: -1;
	}

	.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>