<!-- webview only -->
<template>
    <section class="bl___webview-container bilibili_webview zIndexByJs" :data-zIndex="zIndex"></section>
</template>

<script>
    export default {
        name: 'Bili__AdjustWebview',
        props: {
            "src": {
                type: String,
                default: ""
            },
            "id": {
                type: String,
                default: ''
            },
            "enableBounce": {
                type: Boolean,
                default: true
            },
            "zIndex": {
                type: Number,
                default: 0
            },
            "enableScroll": {
                type: Boolean,
                default: true
            },
            "enablePullDownRefresh": {
                type: Boolean,
                default: true
            },
            "enableNavigate": {
                type: String,
                default: ''
            }
        },
        watch: {
           src(value) {
              this.updateSrc(value)
           },
           enableBounce() {
               this.updateStyles();
           },
           enableScroll() {
               this.updateStyles();
           },
           enablePullDownRefresh() {
               this.updateStyles();
           }
        },
        data(){
            return {
                isRGBReg: /^rgb/i,
                rgbReg:  /\d+/gi,
                styles: {}
            }
        },
        mounted() {
            const APPID = window.__smallAppFE.APPID;
            const isInternalSmallApp = APPID.indexOf('bilinternal') === 0 || APPID.indexOf('biliwidget') === 0;
            if(!isInternalSmallApp) {
                console.warn('not support this component')
                this.$el.remove();
                return
            }
            const that = this;
            // 引入层级算法，自动保持层级
            SmallApp.computeIndex();
            const parentId = that.$parent._bili_id || that.$parent._uid;

            SmallApp.waitStyleOver().then(()=>{
                that.styles = that._computeStyle();
                SmallApp.nativeComponent({
                    ...that._getBasicData(),
                    actionType: "create",
                    styles: that.styles,
                    src: that.src,
                    biliExtra: JSON.stringify({
                        parent: parentId,
                        enableNavigate: that.enableNavigate
                    })
                });
            });

            this._watchStyle();
        },
        beforeDestroy() {
            SmallApp.nativeComponent({
                ...this._getBasicData(),
                actionType: "destroy",
                id: this._uid,
                customId: this.id,
            });
            this.observer.disconnect();
        },
        methods: {
            updateStyles() {
                let positionInfo = this.$el.getBoundingClientRect();
                let styleInfo = window.getComputedStyle(this.$el);
                let isFixed = styleInfo.getPropertyValue("position") === "fixed";
                const newStyles = {
                    x: isFixed ? positionInfo.left : positionInfo.left + SmallApp.getScrollData('left'),
                    y: isFixed ? positionInfo.top : positionInfo.top + SmallApp.getScrollData('top'),
                    width: positionInfo.width,
                    height: positionInfo.height,
                    fixed: isFixed,
                    hidden: styleInfo.getPropertyValue("display") === "none",
                    backgroundColor: this.toHEXColor(styleInfo.backgroundColor),
                    enableBounce: this.enableBounce,
                    enableScroll: this.enableScroll,
                    enablePullDownRefresh: this.enablePullDownRefresh
                };
                const diffStyles = this.diffJson(this.styles, newStyles);
                if (diffStyles) {
                    this.styles = newStyles;
                    SmallApp.nativeComponent({
                        ...this._getBasicData(),
                        actionType: "styleUpdate",
                        styles: diffStyles
                    });
                }
            },
            updateSrc(src) {
                SmallApp.nativeComponent({
                    ...this._getBasicData(),
                    actionType: "srcUpdate",
                    src
                });
            },
            _watchStyle(){
                const that = this;
                this.observer = new MutationObserver( () => {
                    SmallApp.waitStyleOver().then(()=>{
                        that.updateStyles()
                    });
                });

                this.observer.observe(document.body, {
                    attributes: true,
                    childList: true,
                    characterData: true,
                    subtree: true
                });
            },
            _computeStyle() {
                let styleInfo = global.getComputedStyle(this.$el);
                let positionInfo = this.$el.getBoundingClientRect();
                let isFixed = styleInfo.getPropertyValue("position") === "fixed";
                const result = {
                    x: isFixed ? positionInfo.left : positionInfo.left + SmallApp.getScrollData('left'),
                    y: isFixed ? positionInfo.top : positionInfo.top + SmallApp.getScrollData('top'),
                    width: parseFloat(styleInfo.width),
                    height: parseFloat(styleInfo.height),
                    fixed: isFixed,
                    hidden: styleInfo.getPropertyValue("display") === "none",
                    backgroundColor: this.toHEXColor(styleInfo.backgroundColor),
                    enableBounce: this.enableBounce,
                    enableScroll: this.enableScroll,
                    enablePullDownRefresh: this.enablePullDownRefresh
                }
                return result;
            },
            _getBasicData(){
                return {
                    type: "native-component",
                    id: this._uid,
                    customId: this.id,
                    name: "adjustablewebview",
                    zIndex: Number(this.$el.getAttribute('B-zIndex'))
                }
            },
            _styleUpdate(key, value) {
                SmallApp.nativeComponent({
                    ...this._getBasicData(),
                    actionType: "styleUpdate",
                    styles: {
                        [key]: value
                    }
                });
            },
            // handleMessage，作为事件的触发，该方法NA会直接调用。
            handleMessage(message) {
                if (message.type === 'native-component') {
                    this.$emit(message.event.type, message.event.detail);
                }
            },
            toHEX(number){
                const str = '0123456789ABCDEF';
                let temp = '';
                let cur = number % 16;
                temp = str.substr(cur, 1);
                cur = (number - cur) / 16;
                return str.substr(cur, 1) + temp;
            },
            toHEXColor(color){
                if (this.isRGBReg.test(color)) {
                    const [r, g, b] = color.match(this.rgbReg);
                    return '#' + this.toHEX(r) + this.toHEX(g) + this.toHEX(b);
                }
                return color;
            },
            diffJson(oldJson, newJson){
                if (typeof newJson !== "object" || typeof oldJson !== "object") {
                    return newJson;
                }

                let diff = null;
                Object.keys(newJson).forEach((k) => {
                    if (oldJson[k] !== newJson[k]) {
                        if (!diff) {
                            diff = {};
                        }

                        diff[k] = newJson[k];
                    }
                });

                return diff;
            }
        },

    };
</script>

<style lang="less">
    .bilibili_webview{
        width: 300px;
        height: 150px;
    }
</style>
