import { accessToken, defaultStyle, loadMapControl, loadMapboxLibs } from '/@/components/Map/Mapbox'

// renderjs 官方文档
// https://uniapp.dcloud.io/tutorial/renderjs.html
// renderjs 的一些细节问题
// https://juejin.cn/post/7049185827582115870

export default {
    mounted() {},
    methods: {
        loadLibs: loadMapboxLibs,
        initMap(options) {
            // 移除地图
            if (this.map && this.map.remove) {
                this.map.remove()
            }

            // 加载地图
            const mapboxgl = window.mapboxgl
            const map = new mapboxgl.Map({
                accessToken,
                container: options.container,
                style: Object.assign({
                    ...defaultStyle,
                    ...options?.style,
                }),
            })

            // 绑定作用域
            this.map = map

            // 加载地图控件
            map.on('load', () => {
                // #ifdef APP-PLUS
                if (options?.control?.geolocate) {
                    window.navigator.permissions = undefined
                    options.control.geolocate = {
                        geolocation: {
                            getCurrentPosition: (onPositionSuccess, _onPositionError, options) => {
                                this.onPositionSuccess = onPositionSuccess
                                this.$ownerInstance.callMethod('getCurrentPosition', options)
                            },
                        },
                    }
                }
                // #endif

                // 加载地图图层
                this.initMapLayers()
                    .then(() => {
                        // 调用逻辑层方法
                        this.loaded = true
                        this.$ownerInstance.callMethod('onMapLoad', {
                            center: map.getCenter(),
                        })

                        // 加载地图控件
                        loadMapControl(mapboxgl, map, options?.control)
                    })
                    .catch(console.log)
            })
        },
        initMapLayers() {
            this.addPointLayer()
            return this.addPopupImage()
        },
        addPointLayer() {
            this.map.addLayer({
                id: 'point',
                type: 'symbol',
                source: {
                    type: 'geojson',
                    data: {
                        type: 'FeatureCollection',
                        features: [],
                    },
                },
                layout: {
                    'text-field': ['get', 'name'],
                    'icon-text-fit': 'both',
                    'icon-image': 'popup',
                    'icon-allow-overlap': true,
                    'text-allow-overlap': true,
                },
            })
        },
        addPopupImage() {
            return new Promise((resolve, reject) => {
                const popup = 'https://docs.mapbox.com/mapbox-gl-js/assets/popup.png'
                this.map.loadImage(popup, (error, image) => {
                    if (error) {
                        reject(error)
                    } else {
                        this.map.addImage('popup', image, {
                            stretchX: [
                                [25, 55],
                                [85, 115],
                            ],
                            stretchY: [[25, 100]],
                            content: [25, 25, 115, 100],
                            pixelRatio: 2,
                        })
                        resolve()
                    }
                })
            })
        },
        changeOptions(options) {
            if (!options.container) {
                return
            }

            if (typeof window.mapboxgl === 'object') {
                this.initMap(options)
            } else {
                this.loadLibs().then(() => {
                    this.initMap(options)
                })
            }
        },
        changePosition(position) {
            if (!this.loaded) {
                return
            }

            this.onPositionSuccess?.(position)
        },
        changeDataPoint(point) {
            if (!this.loaded) {
                return
            }

            // 更新数据源
            this.map.getSource('point').setData({
                type: 'FeatureCollection',
                features: [point],
            })
        },
    },
}
