<script lang="ts" setup>
    import URI from 'urijs'
    import * as _ from 'lodash-es'
    import { isProdMode } from '@/utils/env'

    const page = reactive({
        security: false,
        title: '',
        link: '',
        styles: {
            progress: {
                color: '#42c02e',
                height: '1%',
            },
        },
    })

    onLoad(({ title, link, sub }) => {
        page.title = title ? decodeURIComponent(title) : ''
        page.link = decodeURIComponent(link)

        // 嵌入页面进行二级子页面跳转时，参数会被多次 encode
        if (sub) {
            page.title = decodeURIComponent(page.title)
            page.link = decodeURIComponent(page.link)
        }

        if (!link) {
            Message.toast('页面打开失败，参数错误')
            uni.navigateBack()
            return
        }

        // 设置标题栏为文件名
        if (page.title && page.title !== 'undefined') {
            uni.setNavigationBarTitle({
                title: page.title,
            })
        }

        // #ifdef APP-PLUS
        // 本地网页或白名单同源检测
        if (page.link.startsWith('/hybrid/') || page.link.startsWith('/static/') || isSameOrigin(new URI(page.link))) {
            page.security = true

            // 延迟获取 webview 对象，插入 js 文件
            setTimeout(() => {
                const pages = getCurrentPages()
                const currentPage = pages[pages.length - 1]
                const currentWebview = currentPage.$getAppWebview()
                const webview = currentWebview.children()[0]
                webview.appendJsFile('_www/static/uni.webview.1.5.6.js')
            }, 1000)
        } else {
            // 对于不安全或不信任的网站地址或可能触发 plus API 的来源，采用手动创建 webview 的方式打开
            const { windowHeight, statusBarHeight } = uni.getSystemInfoSync()
            const webview = plus.webview.create(page.link, 'no-security-webview', {
                plusrequire: 'none',
                progress: page.styles.progress,
                top: `${statusBarHeight + 44}px`,
                height: `${windowHeight}px`,
            })
            const pages = getCurrentPages()
            const currentPage = pages[pages.length - 1]
            const currentWebview = currentPage.$getAppWebview()
            currentWebview.setStyle({ progress: page.styles.progress })
            currentWebview.append(webview)
        }
        // #endif
        // #ifndef APP-PLUS
        page.security = true
        // #endif
    })

    // 安全域白名单，防止 APP 环境的意外注入和非法安全调用 plus API 的问题
    const allows = ['yiring.com', 'uniapp.dcloud.io']
    // 在安全域白名单中，但仍然需要排除的链接（通常是代理的网站链接）
    const denyLinks = []
    function isSameOrigin(url: URI) {
        if (denyLinks.includes(url.href())) {
            return false
        }

        return allows.some((item) => {
            const regex = new RegExp(`^(.*\\.)?${item}$`, 'i')
            return regex.test(url.hostname())
        })
    }

    // 监听来自 webview 的消息
    const onPostMessage = _.debounce(function (e: { detail: { data: any } }) {
        console.warn('onPostMessage', e)

        if (!isProdMode()) {
            Message.alert(JSON.stringify(e.detail.data))
        }
    }, 200)
</script>

<template>
    <view class="wrap" v-if="page.link">
        <template v-if="page.security">
            <web-view
                :src="page.link"
                :update-title="!page.title"
                :webview-styles="page.styles"
                @message="onPostMessage"
            />
        </template>
    </view>
</template>
