import CesiumUtil from '@/views/pipelineDefect/common/cesiumUtil'
import HandleManage from '@/views/pipelineDefect/common/cesiumEvent'
import GraphicUtil from '@/views/pipelineDefect/common/graphic'

import { appconfig } from 'staticPub/config'
import { projUtil } from '@/views/pipelineDefect/common/proj'

import defectImg1 from '@/assets/images/traingle1.png'
import defectImg2 from '@/assets/images/traingle2.png'
import defectImg3 from '@/assets/images/traingle3.png'
import defectImg4 from '@/assets/images/traingle4.png'
import defectImg0 from '@/assets/images/traingle0.png'

import { getDefectDataBySE, getDefectData } from '@/views/pipelineDefect/api/pipelineDefect'

export const mapMixin = {
    data() {
        return {
            cesiumUitl: null,
            handleManage: null,
            graphicUtil: null,
            clkHanderIndex: 0,
            removeListener: null,
            //
            lightLayerName: 'bslightlayer', // 高亮的图层名
            propertyName: 'bsdata', // 添加到地图实体里的数据名
            geometryType: 'geometryType', // 类型区分
            lightStyle: {
                line: 'rgba(0, 255, 255, 0.6)',
                point: 'rgba(0, 255, 255, 0.6)'
            },
            currentDataProjName: appconfig.currPRJ,

            lightFeaText: 'lightFea',

            //
            pSname: 'pipeline',
            dSname: 'defect'
        }
    },
    methods: {
        // 初始化
        initDefectMap() {
            console.log('加载管线')
            let psource = this.getSource(this.pSname), 
                dsource = this.getSource(this.dSname)
            if (psource && dsource && [...dsource.entities.values, ...psource.entities.values].length !== 0) {
                this.setPipeAndDefectVisible()
            } else {
                getDefectData().then(res => {
                    console.log('获取数据')
                    let data = res.result
                    let { strucDefectFeatures, funcDefectFeatures, pipeDefectFeatures } = this.getFeatures(data)
                    if ([...strucDefectFeatures, ...funcDefectFeatures, ...pipeDefectFeatures].length !== 0) {
                        let lines = [...strucDefectFeatures, ...funcDefectFeatures]
                        this.addLines(lines)
                        this.addDefects(pipeDefectFeatures)
                        this.setPipeAndDefectVisible()
                    }
                })
            }
        },
        //
        setCamera () {
            let { lon, lat, height } = appconfig.currCenter
            this.cesiumUitl.setView(CesiumUtil.degrees2Car3(parseFloat(lon), parseFloat(lat), parseFloat(height)))
        },
        // 设置图层显隐
        setSourceVisible (sourceName, visible) {
            let source = this.getSource(sourceName)
            if (source) {
                let entities = source.entities.values
                entities.forEach(e => { e.show = visible })
            }
        },
        // 设置默认的显隐
        setPipeAndDefectVisible () {
            let activeSideItem = this.$store.state.app.activeSideItem
            let showLines = ['检测报告管理', '管道检测历史管理', '管道评估结果管理']
            let showDefects = ['检测报告管理', '管道缺陷管理']
            this.setSourceVisible(this.pSname, showLines.includes(activeSideItem))
            this.setSourceVisible(this.dSname, showDefects.includes(activeSideItem))
        },
        removeEvent () {
            this.handleManage.remove(this.clkHanderIndex)
            this.removeListener && this.removeListener()
            this.data.that.$refs.popupwindow && this.data.that.$refs.popupwindow.removePopupWindow()
        },
        removeLightFeas () {
            this.lightPrimitiveCollection.removeAll()
        },
        // 初始化事件
        initEvent () {
            this.clkHanderIndex = this.handleManage.create('lclick', evt => {
                let { car3, position, pick, rayPoint } = evt
                let data = null, type = ''
                this.data.that.$refs.popupwindow.removePopupWindow()
                if (pick && pick.id) {
                    data = pick.id[this.propertyName]
                    type = data[this.geometryType]
                    this.data.that.$refs.popupwindow.showPopupWindow(rayPoint, pick.id[this.propertyName], type)
                }
                this.removeLightFeas()
                // 高亮
                let fieldText = this.lightFeaText
                if (type === 'line') {
                    this.lightGraphic = this.getPrimity('line', data.lineCar3, { color: this.lightStyle.line, width: 12 }, { [this.lightLayerName]: fieldText })
                    this.lightPrimitiveCollection.add(this.lightGraphic)
                }
            })
            this.removeListener = this.viewer.camera.changed.addEventListener(evt => {
                this.data.that.$refs.popupwindow.movePosition()
            })
        },
        getFeatures(data) {
            const colors = [
                { level: 'Ⅰ', color: 'green' },
                { level: 'Ⅱ', color: 'blue' },
                { level: 'Ⅲ', color: 'pink' },
                { level: 'Ⅳ', color: 'red' }
            ], defaultColor = '#070358'
            let features = { pipeDefectFeatures: [], funcDefectFeatures: [], strucDefectFeatures: [], normal: [] }
            data.forEach(defect => {
                let { endPointXLocation, endPointYLocation, startPointXLocation, startPointYLocation } = defect
                if (startPointXLocation && startPointYLocation && endPointXLocation && endPointYLocation) {
                    let startPoint = this.projUtil.transform([Number(startPointXLocation), Number(startPointYLocation)], this.currentDataProjName, '4326')
                    let endPoint = this.projUtil.transform([Number(endPointXLocation), Number(endPointYLocation)], this.currentDataProjName, '4326')

                    let lineCar3 = CesiumUtil.degreesArray2Car3([startPoint, endPoint].flat())
                    //
                    let findFuncColor = colors.find(colorObj => defect['funcClass'] && defect['funcClass'].includes(colorObj.level))
                    let findStrucColor = colors.find(colorObj => defect['structClass'] && defect['structClass'].includes(colorObj.level))
                    // 结构性
                    // let scolor = findStrucColor ? findStrucColor.color : defaultColor
                    // let sFea = this.getPrimity('line', lineCar3, { color: scolor }, { ...defect, lineCar3 })
                    // sFea && features.strucDefectFeatures.push(sFea)

                    let scolor = findStrucColor ? findStrucColor.color : defaultColor
                    let sFea = this.getEntity('line', lineCar3, { color: scolor }, { ...defect, lineCar3 })
                    sFea && features.strucDefectFeatures.push(sFea)
                    

                    // 功能性
                    let fcolor = findStrucColor ? findStrucColor.color : defaultColor
                    let fFea = this.getEntity('line', lineCar3, { color: fcolor }, { ...defect, lineCar3 })
                    sFea && features.strucDefectFeatures.push(fFea)
                    // 缺陷
                    if (defect.geometry) {
                        let { x, y } = JSON.parse(defect.geometry)
                        let [lon, lat] = this.projUtil.transform([x, y], this.currentDataProjName, '4326')
                        let pointCar3 = CesiumUtil.degrees2Car3(lon, lat, 0)
                        let imgs = [
                            { level: ['一级', '1'], img: defectImg1, index: 0 },
                            { level: ['二级', '2'], img: defectImg2, index: 1 },
                            { level: ['三级', '3'], img: defectImg3, index: 2 },
                            { level: ['四级', '4'], img: defectImg4, index: 3 }
                        ]
                        let findimg = null
                        if (defect.defectLevel) {
                            findimg = imgs.find((colorObj) => colorObj.level.includes(defect['defectLevel']))
                        }
                        if (findimg) {
                            let dFea = this.getEntity('img', pointCar3, { img: findimg.img }, { ...defect, pointCar3 })
                            features.pipeDefectFeatures.push(dFea)
                        }
                    }
                }
            })
            return features

            function isExist (expNo) {
                let feas = [...features.funcDefectFeatures, ...features.strucDefectFeatures]
                return feas.some(f => f.id[this.propertyName].expNo === expNo)
            }
        },
        //  加载管线
        addLines_old (lines) {
            if (!Array.isArray(lines)) {
                lines = [lines]
            }
            lines.forEach(line => {
                this.primitiveCollection.add(line)
            })
        },
        addLines (lines) {
            if (!Array.isArray(lines)) {
                lines = [lines]
            }
            let dataSource = this.getSource(this.pSname)
            lines.forEach(line => {
                dataSource.entities.add(line)
            })
        },
        // 获取图层
        getSource(name) {
            return this.viewer.dataSources.getByName(name)[0]
        },
        // 加载缺陷
        addDefects (defects) {
            if (!Array.isArray(defects)) {
                defects = [defects]
            }
            let dataSource = this.getSource(this.dSname)
            defects.forEach(defect => {
                dataSource.entities.add(defect)
            })
        },
        // 获取图元
        getPrimity (type, positions, style, data = {}) {
            data[this.geometryType] = 'line'
            let primitive = this.graphicUtil.getPrimity(type, positions, style, {[this.propertyName]: data})
            return primitive
        },
        // 获取实体
        getEntity (type, positions, style, data) {
            data[this.geometryType] = type
            let entity = this.graphicUtil.getEntity(type, positions, style)
            entity[this.propertyName] = data
            return entity
        },
        // 移除要素
        removeCesiumGraphics (){
            let pS = this.getSource(this.pSname)
            let dS = this.getSource(this.dSname)
            pS.entities.removeAll()
            dS.entities.removeAll()
        },
        // 高亮并设置相机位置
        // 0: 缺陷 1: 管线 2: 报告
        setViewFromFeas(id, type) {
            this.data.that.$refs.popupwindow.removePopupWindow()
            this.removeLightFeas()
            let idText = ['id', 'expNo', 'wordId'][type], 
                height = [150, 500, 6000],
                center,
                findFeas = [];
            if (type) {
                let pEntities = this.getSource(this.pSname).entities.values
                findFeas = pEntities.filter(e => e[this.propertyName][idText] === id).map(i => i[this.propertyName])
                if (findFeas.length === 0) { return this.$message.error('无位置信息') }
                let features = this.getLightFeatures(findFeas)
                center = this.cesiumUitl.getCenterFormFeas(features.map(f => f.geometryInstances.id[this.propertyName].coors))
                features.forEach(f => this.lightPrimitiveCollection.add(f))
            } else {
                let dEntities = this.getSource(this.dSname).entities.values
                findFeas = dEntities.filter(e => e[this.propertyName][idText] === id).map(i => i[this.propertyName])
                if (findFeas.length === 0) { return this.$message.error('无位置信息') }
                let { x, y } = JSON.parse(findFeas[0]['geometry'])
                let [lon, lat] = this.projUtil.transform([x, y], this.currentDataProjName, '4326')
                center = [lon, lat]
            }

            if (center) {
                if (type !== 2) {
                    this.cesiumUitl.setView(CesiumUtil.degrees2Car3(center[0], center[1], height[type]), () => {
                        let car3 =  CesiumUtil.degrees2Car3(center[0], center[1], 0)
                        let winPos = this.cesiumUitl.car32WindowPosition(car3)
                        let geotype = type ? 'line' : 'point'
                        let rayPoint = this.viewer.scene.globe.pick(this.viewer.scene.camera.getPickRay(winPos), this.viewer.scene);
                        this.data.that.$refs.popupwindow.showPopupWindow(rayPoint, findFeas[0], geotype)
                    })
                }
            } else {
                this.$message.error('该点无位置信息');
            }
        },
        // 获取高亮的要素
        getLightFeatures(data) {
            let that = this
            let features = [], lightColor = 'rgba(0, 255, 255, 0.6)'
            data.forEach(defect => {
                let { endPointXLocation, endPointYLocation, startPointXLocation, startPointYLocation } = defect
                if (startPointXLocation && startPointYLocation && endPointXLocation && endPointYLocation) {
                    let startPoint = this.projUtil.transform([Number(startPointXLocation), Number(startPointYLocation)], this.currentDataProjName, '4326')
                    let endPoint = this.projUtil.transform([Number(endPointXLocation), Number(endPointYLocation)], this.currentDataProjName, '4326')

                    let lineCar3 = CesiumUtil.degreesArray2Car3([startPoint, endPoint].flat())
                    let fea = this.getPrimity('line', lineCar3, { color: lightColor, width: 7 }, { ...defect, coors: [startPoint, endPoint]})
                    if (!isExist(defect.expNo)) {
                        features.push(fea)
                    }
                }
            })
            return features
            function isExist (expNo) {
                return features.some(f => f.geometryInstances.id[that.propertyName].expNo === expNo)
            }
        },
    },
    mounted() {
        const { viewer, Cesium } = <any>window
        this.viewer = viewer
        let dataSources = this.viewer.dataSources
        
        // 公共、事件、图形工具
        this.cesiumUitl = new CesiumUtil(this.viewer)
        this.handleManage = new HandleManage(this.viewer)
        this.graphicUtil = new GraphicUtil()

        // 坐标系工具
        this.projUtil = new projUtil()
        this.projUtil.resgis(this.currentDataProjName)

        // 高亮样式
        this.lightPrimitiveCollection = new Cesium.PrimitiveCollection()
        this.lightPrimitiveCollection.destroyPrimitives = false
        this.viewer.scene.primitives.add(this.lightPrimitiveCollection)
        
        // 缺陷，管道
        if (!this.getSource(this.pSname)) {
            this.pDataSource = new Cesium.CustomDataSource(this.pSname)
            dataSources.add(this.pDataSource)
        }
        if (!this.getSource(this.dSname)) {
            this.dDataSource = new Cesium.CustomDataSource(this.dSname)
            dataSources.add(this.dDataSource)
        }
        
        // 设置相机
        this.setCamera()
        // 加载管线，缺陷
        this.initDefectMap()
        // 点击事件
        this.initEvent()
    },
    destroyed () {
        this.removeEvent()
        // this.setSourceVisible(this.pSname, false)
        // this.setSourceVisible(this.dSname, false)
    },
    watch: {
        '$store.state.app.activeSideItem': function(n, o) {
            if (n === '工程管理') { this.$store.dispatch('map/mapLaoding', false) }
            this.setPipeAndDefectVisible()
        }
    }
}