/* eslint-disable */

declare global {
    interface Window {
        plus: any;
    }
}

interface SystemInfo {
    os: 'Web' | 'Android' | 'iOS'; // 客户端操作系统
    version: string; // 客户端版本号
    versionCode: string; // 客户端版本代码
    statusBarHeight: number; // 状态栏高度
}

const urlScheme = {
    appStore: {
        name: 'App Store',
        pname: '',
        scheme: 'itms-apps://'
    },
    alipay: {
        name: '支付宝',
        pname: 'com.eg.android.AlipayGphone',
        scheme: 'alipay://'
    },
    taobao: {
        name: '淘宝',
        pname: 'com.taobao.taobao',
        scheme: 'taobao://'
    },
    qq: {
        name: 'QQ',
        pname: 'com.tencent.mobileqq',
        scheme: 'mqq://'
    },
    weixin: {
        name: '微信',
        pname: 'com.tencent.mm',
        scheme: 'weixin://'
    },
    jd: {
        name: '京东',
        pname: 'com.jingdong.app.mall',
        scheme: 'openApp.jdMobile://'
    },
    weibo: {
        name: '新浪微博',
        pname: 'com.sina.weibo',
        scheme: 'sinaweibo://'
    },
    youku: {
        name: '优酷',
        pname: 'com.youku.phone',
        scheme: 'youku://'
    }
}

export default new (class {
    private readonly plusready = new Promise<void>((resolve) => {
        if (this.hasPlus()) {
            resolve()
        } else {
            document.addEventListener('plusready', () => resolve())
        }
    })

    /**
     * 系统信息
     */
    private systemInfo: SystemInfo = {
        os: 'Web', // 客户端操作系统
        version: '1.0', // 客户端版本号
        versionCode: '100000', // 客户端版本代码
        statusBarHeight: 0, // 状态栏高度
    }

    constructor() {
        this.plusready.then(() => {
            const plus = window.plus
            this.systemInfo.os = plus.os.name
            this.systemInfo.statusBarHeight = plus.navigator.getStatusbarHeight()

            plus.runtime.getProperty(plus.runtime.appid, (info: any) => {
                this.systemInfo.version = info.version
                this.systemInfo.versionCode = info.versionCode
            })
        })

        // 监听返回按钮事件
        this.onPlusReady((plus) => {
            let firstBack = true
            const webview = plus.webview.currentWebview()

            plus.key.addEventListener('backbutton', () => {
                webview.canBack((e: any) => {
                    // 判断能否继续返回
                    if (e.canBack) {
                        webview.back()
                    } else {
                        // 1秒内连续两次按返回键退出应用
                        if (firstBack) {
                            firstBack = false
                            plus.nativeUI.toast('再按一次退出应用')
                            setTimeout(() => {
                                firstBack = true
                            }, 1000)
                        } else {
                            plus.runtime.quit()
                        }
                    }
                })
            })
        })
    }

    hasPlus() {
        return !!window.plus
    }

    onPlusReady(callback: (plus: Window['plus']) => void) {
        this.plusready.then(() => {
            callback(window.plus)
        })
    }

    /**
     * 退出应用程序
     */
    quit() {
        this.onPlusReady((plus) => {
            plus.runtime.quit()
        })
    }

    /**
     * 获取系统信息
     * @param prop 
     * @returns 
     */
    getSystemInfo<K extends keyof SystemInfo>(prop: K) {
        return this.systemInfo[prop]
    }

    /**
     * 获取状态栏高度
     * @param callback 
     */
    getStatusBarHeight(callback: (statusbarHeight: number) => void) {
        this.onPlusReady((plus) => {
            const height = plus.navigator.getStatusbarHeight()
            callback(height)
        })
    }

    /**
     * 设置状态栏文字颜色
     * @param color dark - 暗色，light - 亮色
     */
    setStatusBarStyle(color: 'dark' | 'light') {
        this.onPlusReady((plus) => {
            plus.navigator.setStatusBarStyle(color)
        })
    }

    /**
     * 隐藏状态栏
     */
    hideStatusBar() {
        this.onPlusReady((plus) => {
            plus.navigator.setFullscreen(true)
        })
    }

    /**
     * 显示状态栏
     */
    showStatusBar() {
        this.onPlusReady((plus) => {
            plus.navigator.setFullscreen(false)
        })
    }

    /**
     * 设置应用全屏
     */
    setFullSreen() {
        this.onPlusReady((plus) => {
            this.hideStatusBar()
            plus.navigator.hideSystemNavigation()
        })
    }

    /**
     * 应用退出全屏
     */
    exitFullSreen() {
        this.onPlusReady((plus) => {
            this.showStatusBar()
            plus.navigator.showSystemNavigation()
        })
    }

    /**
     * 更新应用
     * @param url 
     */
    updateApp(url: string) {
        this.onPlusReady((plus) => {
            const dtask = plus.downloader.createDownload(
                url,
                {
                    filename: ''
                },
                function (d: { filename: string }, status: number) {
                    if (status == 200) {
                        // 当前下载的状态
                        installApp(d.filename) // 调用安装的方法
                    } else {
                        //plus.nativeUI.alert('下载失败')
                    }
                }
            )

            dtask.start() // 开启下载的任务
            // app自动更新进度
            dtask.addEventListener('statechanged', function (task: { state: number }) {
                // 给下载任务设置一个监听 并根据状态  做操作
                switch (task.state) {
                    case 1:
                        console.log('正在下载')
                        break
                    case 2:
                        console.log('已连接到服务器')
                        break
                    case 3:
                    // console.log(task)
                    // console.log(task.downloadedSize)//当前的大
                    // console.log(task.totalSize)//安装包的大小
                }
            })

            // 自动更新
            function installApp(path: string) {
                plus.nativeUI.showWaiting('正在更新...')
                plus.runtime.install(
                    path,
                    {
                        // true表示强制安装，不进行版本号的校验；false则需要版本号校验，如果将要安装应用的版本号不高于现有应用的版本号则终止安装，并返回安装失败。 仅安装wgt和wgtu时生效，默认值 false
                        force: false
                    },
                    function () {
                        plus.nativeUI.closeWaiting()
                        console.log('更新成功！')
                        plus.runtime.restart()
                    },
                    function (e: { message: string }) {
                        plus.nativeUI.closeWaiting()
                        plus.nativeUI.alert('更新失败：' + e.message)
                    }
                )
            }
        })
    }

    /**
     * 保存图片到相册
     * @param base64Data 
     */
    saveImage(base64Data: string, fileName?: string) {
        this.onPlusReady((plus) => {
            const bitmap = new plus.nativeObj.Bitmap()
            const filename = fileName ?? new Date().getTime()
            bitmap.loadBase64Data(base64Data)
            bitmap.save(`_doc/${filename}.jpg`, { overwrite: true, quality: 100, }, (e: Event) => {
                //保存到系统相册
                plus.gallery.save(
                    e.target,
                    () => {
                        //销毁Bitmap图片
                        bitmap.clear()
                        plus.nativeUI.toast('已保存到相册中')
                    },
                    () => {
                        //销毁Bitmap图片
                        bitmap.clear()
                        plus.nativeUI.toast('保存失败')
                    }
                )
            }, (err: { message: string }) => {
                plus.nativeUI.toast(err.message)
            })
        })
    }

    /**
     * 打开本地文件(安卓生产包可能无效)
     * https://www.html5plus.org/doc/zh_cn/runtime.html#plus.runtime.openFile
     * @param filePath 
     */
    openFile(filePath: string) {
        if (this.hasPlus()) {
            this.onPlusReady((plus) => {
                plus.runtime.openFile('_www/' + filePath)
            })
        } else {
            window.open(filePath)
        }
    }

    /**
     * https://www.html5plus.org/doc/zh_cn/runtime.html#plus.runtime.openURL
     * @param url 
     */
    openURL(url: string) {
        if (this.hasPlus()) {
            this.onPlusReady((plus) => {
                plus.runtime.openURL(url)
            })
        } else {
            window.open(url)
        }
    }

    /**
     * 读取本地文件内容
     * @param filePath 
     * @returns 
     */
    getLocalFileContent(filePath: string) {
        return new Promise<any>((resolve, reject) => {
            this.onPlusReady((plus) => {
                plus.io.resolveLocalFileSystemURL('_www/' + filePath, (entry: any) => {
                    entry.file((file: any) => {
                        const fileReader = new plus.io.FileReader()
                        fileReader.readAsText(file, 'utf-8')
                        fileReader.onloadend = (evt: any) => {
                            resolve(evt.target.result)
                        }
                    })
                }, (e: any) => {
                    reject(e.message)
                })
            })
        })
    }

    /**
     * 内容分享
     */
    share() {
        this.onPlusReady((plus) => {
            // 成功回调
            const success = (services: any) => {
                console.log('分享列表', services)
                services.forEach((e: any) => {
                    if (e.id === 'weixin') {
                        e.send({
                            type: 'web',
                            title: '标题',
                            content: '内容',
                            href: 'https://',
                        }, () => {
                            console.log('分享成功')
                        }, (e: Error) => {
                            console.log('分享失败', e.message)
                        })
                    }
                })
            }
            // 失败回调
            const error = (e: Error) => {
                console.log('获取分享列表失败', e.message)
            }
            plus.share.getServices(success, error)
        })
    }

    /**
     * 打开第三方APP
     * @param app 
     */
    launchApplication<K extends keyof typeof urlScheme>(app: K) {
        this.onPlusReady((plus) => {
            const os = this.getSystemInfo('os')
            const params = Object.create(null)

            if (os === 'Android') {
                params.pname = urlScheme[app].pname
            }
            if (os === 'iOS') {
                params.action = urlScheme[app].scheme
            }

            plus.runtime.launchApplication(params, (e: Error) => {
                console.log('失败', e.message)
            })
        })
    }
})