<script>
    export default {
        props: {
            info: {
                type: Object,
                default: () => {},
            },
        },
        data() {
            return {
                id: nanoid(),
                options: {},
                data: {},
                location: {},
                cloudImage: {},
            }
        },
        async mounted() {
            uni.showLoading({ title: '加载中...', mask: true })
            const data = this.info
            this.options = {
                container: this.id,
                control: {
                    navigation: {
                        zoom: false,
                        compass: false,
                    },
                    info: false,
                    reset: true,
                    geolocate: true,
                },
                style: {
                    zoom: data.radius <= 380 ? 14 : data.radius <= 1000 ? 12.7 : data.radius < 2000 ? 12.7 : 11.5,
                    center: [data.lon, data.lat],
                },
            }
        },
        methods: {
            onMapLoad(_data) {
                uni.hideLoading()
                this.data = this.info
                // this.getLocation().then((res) => (this.location = res))
            },
            onLoadCloudImage(data) {
                if (data.open) {
                    this.findCloudImage()
                } else {
                    this.cloudImage = ''
                }
            },
            async getLocation() {
                return new Promise((resolve) => {
                    uni.getLocation({
                        type: 'gcj02',
                        geocode: true,
                        success(res) {
                            resolve(res)
                        },
                        fail() {
                            Message.toast('获取定位信息失败！')

                            // FEXID: 默认定位
                            resolve({
                                latitude: 111.866827,
                                longitude: 26.848348,
                            })
                        },
                    })
                })
            },
            findCloudImage() {},
        },
    }
</script>

<script module="mapbox" lang="renderjs">
    import * as turf from '@turf/turf'
    import { appendScript, appendStylesheet } from '/@/utils/dom'
    import { accessToken, defaultStyle, loadMapControl, PopupImage, buildTdtTileUrl, EmptyImage, CustomControl } from '/@/components/Map/Mapbox'
    import { getResourceUrl } from '/@/utils/proxy'
    import { strawForestMatchExpression } from '/@/pages/tabbar/check/data'

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

    export default {
        mounted() {},
        data() {
            return {
                data: {}
            }
        },
        methods: {
            loadLibs() {
                const id = 'mapbox-gl'
                const resource = 'static/mapbox-gl-js/v2.10.0/mapbox-gl'
                return Promise.all([appendScript(id, `${resource}.js`), appendStylesheet(id, `${resource}.css`)])
            },
            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,
                    }),
                    localIdeographFontFamily: "'Noto Sans', 'Noto Sans CJK SC', sans-serif",
                })

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

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

                        // 加载地图控件
                        loadMapControl(mapboxgl, map, options?.control)

                        // 添加云图切换控件
                        map.addControl(new CustomControl({
                            onOpen: () => {
                                this.$ownerInstance.callMethod('onLoadCloudImage', {
                                    open: true,
                                })
                                return Promise.resolve()
                            },
                            onClose: () => {
                                this.$ownerInstance.callMethod('onLoadCloudImage', {
                                    open: false,
                                })
                            }
                        }), 'top-right')

                        // 地图是否加载完成
                        this.mapLoaded = true

                        // debug
                    }).catch()
                })
            },
            // 初始化各类底层图层
            initMapBasicLayers() {
                const map = this.map
                return new Promise((resolve) => {
                    // 添加脉冲点
                    map.addImage('plusingDot', this.buildPlusingDot(), { pixelRatio: 2 })

                    // 云图数据源
                    map.addSource('cloud-image-source', {
                        type: 'image',
                        url: EmptyImage,
                        coordinates: [
                            [108, 31],
                            [116, 31],
                            [116, 23],
                            [108, 23],
                        ],
                    })
                    // 云图图层
                    map.addLayer({
                        id: 'cloud-image-layer',
                        type: 'raster',
                        source: 'cloud-image-source',
                        layout: {
                            visibility: 'none',
                        },
                        paint: {
                            'raster-fade-duration': 0,
                        },
                    },
                    '100000-line')

                    // 核查范围图层
                    map.addSource('maine', {
                        type: 'geojson',
                        data: {
                            type: 'FeatureCollection',
                            features: [],
                        },
                    })
                    map.addLayer({
                        id: 'maine',
                        type: 'fill',
                        source: 'maine',
                        layout: {},
                        paint: {
                            'fill-color': '#fff',
                            'fill-opacity': 0.02,
                        },
                    })
                    map.addLayer({
                        id: 'outline',
                        type: 'line',
                        source: 'maine',
                        layout: {
                            'line-cap': 'round',
                            'line-join': 'round',
                        },
                        paint: {
                            'line-color': '#09c8ff',
                            'line-dasharray': [0.2, 2],
                            'line-width': 2,
                        },
                    })
                    map.addLayer({
                        id: 'linetext',
                        type: 'symbol',
                        source: 'maine',
                        layout: {
                            'symbol-placement': 'line',
                            'text-field': '{radius}m',
                        },
                        paint: {
                            'text-color': '#ff0062',
                            'text-halo-width': 2,
                            'text-halo-color': '#fff',
                        },
                    })

                    // 火点图层
                    map.addSource('points', {
                        type: 'geojson',
                        data: {
                            type: 'FeatureCollection',
                            features: [],
                        },
                    })
                    map.addLayer({
                        id: 'points',
                        type: 'symbol',
                        source: 'points',
                        layout: {
                            'icon-size': 0.25,
                            'icon-image': strawForestMatchExpression,
                            'icon-allow-overlap': true,
                            'icon-ignore-placement': true,
                        },
                        paint: {},
                    })

                    // 核查点图层
                    map.addSource('check-points', {
                        type: 'geojson',
                        data: {
                            type: 'FeatureCollection',
                            features: [],
                        },
                    })
                    map.addLayer({
                        id: 'check-points',
                        type: 'symbol',
                        source: 'check-points',
                        layout: {
                            'icon-image': 'plusingDot',
                            'icon-allow-overlap': true,
                            'icon-ignore-placement': true,
                        },
                        paint: {},
                    })

                    resolve()
                })
            },
            flyTo(data) {
                const map = this.map
                const center = [data.lon, data.lat]
                const point = turf.point(center, {
                    code: data.code,
                    status: data.status,
                    radius: data.radius,
                    mapIconStatus: `INITIAL.${data.status}`,
                })
                const circle = turf.circle(point, Number(Number(data.radius / 1000).toFixed(2)))

                // 更新核查半径数据源
                map.getSource('maine').setData(circle)
                // 更新火点信息数据源
                map.getSource('points').setData(point)
                // 移动视图
                map.flyTo({
                    zoom: data.radius <= 380 ? 14 : (data.radius <= 1000 ? 12.7 : (data.radius < 2000 ? 12.7 : 11.5)),
                    center: [center[0], center[1]],
                })
            },
            // 脉冲圆点
            buildPlusingDot() {
                const map = this.map
                const size = 60

                // 脉冲点
                return {
                    width: size,
                    height: size,
                    data: new Uint8Array(size * size * 4),
                    onAdd: function() {
                        var canvas = document.createElement('canvas')
                        canvas.width = this.width
                        canvas.height = this.height
                        this.context = canvas.getContext('2d')
                        this.context.imageSmoothingEnabled = true
                    },
                    render: function() {
                        var duration = 1500
                        var t = (performance.now() % duration) / duration

                        var radius = (size / 2) * 0.4
                        var outerRadius = (size / 2) * 0.7 * t + radius
                        var context = this.context

                        // draw outer circle
                        context.clearRect(0, 0, this.width, this.height)
                        context.beginPath()
                        context.arc(this.width / 2, this.height / 2, outerRadius, 0, Math.PI * 2)
                        context.fillStyle = 'rgba(255, 200, 200, ' + (1 - t) + ')'
                        context.fill()

                        // draw inner circle
                        context.beginPath()
                        context.arc(this.width / 2, this.height / 2, radius, 0, Math.PI * 2)
                        context.fillStyle = 'rgba(255, 100, 100, 1)'
                        context.strokeStyle = 'white'
                        context.lineWidth = 3 // 2 + 4 * (1 - t)
                        context.fill()
                        context.stroke()

                        // update this image's data with data from the canvas
                        this.data = context.getImageData(0, 0, this.width, this.height).data

                        // keep the map repainting
                        map.triggerRepaint()

                        // return `true` to let the map know that the image was updated
                        return true
                    },
                }
            },
            changeOptions(options) {
                if (!options.container) {
                    return
                }

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

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

                this.data = data
                this.flyTo(data)
            },
            changeLocation(location) {
                if (!this.loaded) {
                    return
                }

                console.log('changeLocation', location)
                // 更新火点信息数据源
                this.map.getSource('check-points').setData({
                    type:  "Feature",
                    geometry: { type: 'Point', coordinates: [location.latitude, location.longitude] }
                })
            },
            changeCloudImage(image) {
                if (!this.loaded) {
                    return
                }

                console.log('changeCloudImage', image)
                const map = this.map
                if (image) {
                    map.getSource('cloud-image-source').updateImage({ url: getResourceUrl(image.src) })
                    map.setLayoutProperty('cloud-image-layer', 'visibility', 'visible')
                    map.flyTo({
                        zoom: 4.7,
                        center: [111.866827, 26.848348],
                    })
                } else {
                    map.setLayoutProperty('cloud-image-layer', 'visibility', 'none')
                    this.flyTo(this.data)
                }
            },
        },
    }
</script>

<!-- renderjs 视图层模块 -->
<template>
    <!-- #ifdef APP-PLUS || H5 -->
    <view
        class="map wrap"
        :id="id"
        :options="options"
        :change:options="mapbox.changeOptions"
        :data="data"
        :change:data="mapbox.changeData"
        :location="location"
        :change:location="mapbox.changeLocation"
        :cloudImage="cloudImage"
        :change:cloudImage="mapbox.changeCloudImage"
    >
        <!--  -->
    </view>
    <!-- #endif -->
    <!-- #ifndef APP-PLUS || H5 -->
    <view class="empty wrap">非 APP、H5 环境不支持</view>
    <!-- #endif -->
</template>

<style lang="less" scoped>
    .wrap {
        display: flex;
        width: 100%;
        height: 100%;
    }
</style>
