import Layer from 'ol/layer/Vector'
import Source from 'ol/source/Vector'
import Select from 'ol/interaction/Select.js';
import {singleClick} from 'ol/events/condition'
import * as olEvents from 'ol/events';
import config from "@/api/config.js"
import * as KMap from '@/utils/ol-map/KMap';
import {getRadius} from "./util";
import Style from "ol/style/Style";
import Photo from "ol-ext/style/Photo";
import Icon from "ol/style/Icon";
import {base_img_url2} from "../../api/config";
import Stroke from "ol/style/Stroke";
import * as util from "@/common/ol_common.js"
import {newAreaFeature, newAreaPoint, newPolymerFeature, newPoint, newRegionFeature} from "../zhgl/map";
import { GARDEN_STATUS_ENUM as STATUS_ENUM } from "@/api/enum.js"
import VectorLayer from 'ol/layer/Vector.js';
import Polygon from 'ol/geom/Polygon.js';
import MultiPolygon from 'ol/geom/MultiPolygon.js';
import Point from 'ol/geom/Point.js';
import {Cluster, OSM, Vector as VectorSource} from 'ol/source.js';
import {boundingExtent} from 'ol/extent.js';
import {
    Circle as CircleStyle,
    Fill,
    Text,
  } from 'ol/style.js';
  import {unByKey} from 'ol/Observable';
  import { reactive } from 'vue';
  let resize = '?x-oss-process=image/resize,w_400';
  export const treeItem = reactive({
    treeId: ""
  });

const styleCache = {};

/**
 * @description 智能巡园地图层对象
 */
class ZnxyMap {

    constructor(){
        let that = this
        let vectorStyle = new KMap.VectorStyle()
        this.imgStyleCache = {}

        this.gardenLayer =  new KMap.VectorLayer("gardenLayer",1000,{minZoom:8,maxZoom:15,style:(feature)=> {
                let k = feature.get("organId")
                let name = feature.get("name")
                if(name.length > 5){
                    name = name.substr(0,5)
                }
                let name2 = ""
                for(let i=0;i<name.length;i++){
                    name2+=name[i]+"\n"
                }
                let style = that.imgStyleCache[k];
                if(!style){
                    style = []
                    // let style1 = new Style ({
                    //     image: new Photo ({
                    //         src: require('@/assets/yezi.png'),
                    //         radius: 40,
                    //         shadow: 0,
                    //         crop:true,
                    //         kind:"circle",
                    //         onload: function() { that.gardenLayer.layer.changed(); },
                    //         displacement: [0, 50],
                    //         stroke: new Stroke({
                    //             width: 2,
                    //             color: '#fdfcfc'
                    //         })
                    //     })
                    // });
                    let style2 = new Style ({
                        image: new Icon ({
                            src: config.base_img_url3 + "birdseye-look-mini/foster/gardenNameBox.png",
                            scale: 1,
                            displacement:[0, 80]
                        }),
                        text:new Text({
                            text:name2,
                            font:"bold 14px serif",
                            offsetX:0,
                            offsetY:-70,
                            fill: new Fill({
                                color: "#000000"
                            }),
                            stroke: new Stroke({
                                color: "#000000",
                                width: 1,
                            }),
                        })
                    });
                    style.push(style2)
                    // style.push(vectorStyle.getPointTextStyle(feature.get("organId")+"", "#120046","#FFFFFF",2, 30))
                    // style.push(style1)
                    that.imgStyleCache[k] = style
                }
                return style
            }
        })

        this.gardenPointLayer = new KMap.VectorLayer("gardenLayer",1000,{minZoom:0,maxZoom:8,
            source:new Cluster({
                distance: 5,
                // minDistance: 60,
                source: new VectorSource({})
            }),
            style:(feature)=>{
                let style1 = new Style ({
                    image: new Photo ({
                        src: require('@/assets/star1.png'),
                        radius: 10,
                        shadow: 0,
                        crop:true,
                        onload: function() { that.gardenLayer.layer.changed(); },
                        displacement: [0, 0],
                        stroke: new Stroke({
                            width: 2,
                            color: '#fdfcfc00'
                        })
                    })
                });
                return [style1]
            }
        })

        this.areaLayer = new KMap.VectorLayer("areaLayer",999,{minZoom:15,style:(f)=> vectorStyle.getPolygonStyle("#032833" + "80", "#0BFDF2",3)})
        this.subAreaLayer = new KMap.VectorLayer("subAreaLayer",999,{minZoom:15,style:(f)=> {
            return vectorStyle.getPolygonStyle(f.get("fillColor"), f.get("strokeColor"), 2)
        }})
        this.areaPointLayer =  new KMap.VectorLayer("areaPointLayer",1000,{minZoom:15,style:(f)=> {
                return vectorStyle.getPointTextStyle(f.get("name"), "#120046","#FFFFFF",2, 30)
            }
        })
        this.subAreaLayer.layer.setVisible(false)
        this.afterDayNum = 3
        this.treeCacheStyle = {}
        this.treeStyle= (f)=> {
            let key = f.get("imgSrc");
            if(that.treeCacheStyle[key]){
                return that.treeCacheStyle[key]
            }
            let style = new Style({
                image: new Icon({
                    src: f.get("imgSrc"),
                    scale:1,
                    // anchor:[0.5,1],
                })
            });
            that.treeCacheStyle[key] = style
            return style
        }
        this.statusPointLayer = new KMap.VectorLayer("statusPointLayer",999,{minZoom:15,style:this.treeStyle})


        // this.regionLayer = new KMap.VectorLayer("regionLayer",999,{style:(f)=> {
        //         return vectorStyle.getPolygonStyle("#032833" + "80", "#0BFDF2",3)
        //     }})
    }

    initMap(location,target)  {
        let level = 18
        let coordinate = util.wktCastGeom(location).getFirstCoordinate()
        this.kmap = new KMap.Map(target,level,coordinate[0], coordinate[1],null,5,22);
        let xyz = config.base_img_url + 'map/lby/{z}/{x}/{y}.png';
        this.kmap.addXYZLayer(xyz,{minZoom:15,maxZoom:22});
        let xyz2 = config.base_img_url3 + 'map/lby/{z}/{x}/{y}.png';
        this.kmap.addXYZLayer(xyz2,{minZoom:15,maxZoom:22});
        this.kmap.addLayer(this.areaLayer.layer)
        this.kmap.addLayer(this.subAreaLayer.layer)
        this.kmap.addLayer(this.areaPointLayer.layer)
        this.kmap.addLayer(this.statusPointLayer.layer)
        this.kmap.addLayer(this.gardenLayer.layer)
        this.kmap.addLayer(this.gardenPointLayer.layer)
    }

    resetPx(item){
        let organId = item.organId
        let pointWkt = item.pointWkt
        let left = pointWkt.indexOf("(")
        let right = pointWkt.indexOf(")")
        let xy = pointWkt.substring(left + 1,right).split(" ")
        let x = parseFloat(xy[0])
        let y = parseFloat(xy[1])
        if(organId === 768){
            x -= 1
        }
        if(organId === 42134){
            x += 1
        }
        if(organId === 25862){
            x += 1
        }
        if(organId === 80866){
            x += 1
        }
        if(organId === 80863){
            x -= 1
        }
        if(organId === 26072){
            y += 1
        }
        item.pointWkt = "POINT(" + x + " " + y+ ")"
    }

    initGarden(){
        let that = this
        this.gardenLayer.refresh()
        VE_API.organ.gardenData().then(({data,code})=>{
            let features = []
            for(let item of data){
                that.resetPx(item)
                let point = newAreaPoint(item)
                that.gardenLayer.addFeature(point)
                features.push(point)
            }
            const source = new VectorSource({
                features: features,
            });

            // const clusterSource = new Cluster({
            //     // distance: 5,
            //     minDistance: 20,
            //     source: source,
            // });
            that.gardenPointLayer.layer.setSource(source)
        })
    }

    addGardenClick(callback){
        let that = this
        this.kmap.map.on("click", function (e) {
            that.gardenLayer.layer.getFeatures(e.pixel).then((features)=>{
                if(features.length > 0 && features[0].get("nodeType") == "area"){
                    callback && callback(features[0])
                }
            })

        })
    }

    initArea(organId){
        let that = this
        this.areaLayer.refresh()
        VE_API.area.list({organId}).then(({data,code})=>{
            for(let item of data){
                that.areaLayer.addFeature(newAreaFeature(item))
                that.areaPointLayer.addFeature(newAreaPoint(item))
            }
        })
    }

    initSubArea(organId){
        let that = this
        this.subAreaLayer.refresh()
        VE_API.sub_area.list({organId}).then(({data,code})=>{
            for(let item of data){
                const result = that.handleStatusColor(item.status)
                item.fillColor = result.fillColor
                item.strokeColor = result.strokeColor
                that.subAreaLayer.addFeature(newPolymerFeature(item))
            }
        })

    }

    async initTree(organId,isBoolean){
        console.log('isBoolean',isBoolean);
        if(!isBoolean) return this.clearCluster()
        let that = this
        // 树状态
        this.statusPointLayer.refresh()
        await VE_API.sub_area.treeList({gardenId: organId}).then(({data}) => {
            this.treeListData = data
        })
        this.addCluster()
    }

    // --------聚合-----------
    addCluster() {
        this.clearCluster()
        let that = this
        let features = []
        // 根据状态加上对应的图标
        for(let item of this.treeListData){
            let result = that.handleStatusIcon(item)
            // if (result.hasStatus) {
                item.imgSrc = result.imgSrc
                item.clusterIcon = result.clusterIcon
                let point = newPoint(item);
                features.push(point)
            // }
        }
        const source = new VectorSource({
            features: features,
        });

        const clusterSource = new Cluster({
            distance: 15,
            // minDistance: 60,
            source: source,
        });


        this.treeClusterLayer = new KMap.VectorLayer("tree-cluster",999,{
            minZoom:15,
            source:clusterSource,
            style:(feature)=> {
                const size = feature.get('features').length;
                // 只有一个数据，不需要聚合，直接使用第一项数据的图标
                if (size == 1) {
                    feature = feature.get('features')[0]
                    let style = styleCache[feature.get('imgSrc')];
                    if(!style){
                        style = new Style({
                            image: new Icon({
                                src: feature.get('imgSrc'),
                                // src: require('@/assets/yezi.png'),
                                scale:1,
                                // anchor:[0.5,1],
                            })
                        });
                        styleCache[feature.get('imgSrc')] = style;
                    }
                    return style
                }
                // 多个点位聚合，循环处理得到图标
                const featureObj = that.getFeaturesIcon(feature.get("features"))
                let imgSrc = featureObj.get('imgSrc')
                let style = styleCache[imgSrc];
                if (!style) {
                    style = new Style({
                        image: new Icon({
                            src: imgSrc,
                            scale:1,
                            // anchor:[0.5,1],
                        })
                    });
                    styleCache[imgSrc] = style;
                }
                return style;
        }})



        that.kmap.addLayer(this.treeClusterLayer.layer)
        // this.fit(this.treeClusterLayer.getSource().getSource().getExtent())
        that.kmap.getView().fit(this.treeClusterLayer.layer.getSource().getSource().getExtent(), { duration: 1000, padding: [120, 120, 200, 120] });
        // 监听聚合点位的点击，点击后缩放到范围内
        this.listenKey = that.kmap.on('click', (e) => {
            if (that.treeClusterLayer) {
                that.treeClusterLayer.layer.getFeatures(e.pixel).then((clickedFeatures) => {
                    if (clickedFeatures.length && clickedFeatures[0].get("nodeType") == "tree") {
                        const features = clickedFeatures[0].get('features');
                        if (features.length > 1) {
                            const extent = boundingExtent(
                                features.map((r) => r.getGeometry().getCoordinates()),
                            );
                            that.kmap.getView().fit(extent, { duration: 1000, padding: [150, 150, 150, 150] });
                        }
                    }
                });
            }
        });
    }

    // 清除聚合图层，解除绑定
    clearCluster() {
        if (this.treeClusterLayer) {
            this.treeClusterLayer.layer.getSource().getSource().clear()
            this.treeClusterLayer = null
            unByKey(this.listenKey)
        }
    }

    addMapClick(){
        let that = this
        that.kmap.on('click', (evt) => {
            that.kmap.map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) {
                if (layer instanceof VectorLayer && layer.get('name') === 'tree-cluster') {
                    // 当前hover的features点位
                    const featureItem = feature.getProperties().features[0]
                    // 获取要素的几何形状
                    let geometry = feature.getGeometry();
                    if (geometry instanceof Point) {
                        treeItem.treeId =  featureItem.get("id")
                        return true
                    }
                    return true;
                }
            });
        });
    }

    // 二级分区鼠标悬停弹框
    addHoverTooltips(infoRef, imgInfo) {
        let that = this
        that.kmap.on('pointermove', (evt) => {
            if (!that.kmap.map.hasFeatureAtPixel(evt.pixel)) {
                that.clearTooltip(infoRef, imgInfo);
                return;
            }
            // 清除之前的定时器
            that.clearTooltip(infoRef, imgInfo);
            that.tooltipTimeout = setTimeout(function () {
                that.kmap.map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) {
                    // 点击的图层是否是VectorLayer
                    if (layer instanceof VectorLayer && layer.get('name') === 'subAreaLayer') {
                        // 获取要素的几何形状
                        let geometry = feature.getGeometry();
                        // 检查几何形状是否为Polygon
                        if (geometry instanceof Polygon || geometry instanceof MultiPolygon) {
                            // 使用geometry.intersectsCoordinate方法来检查点击的坐标是否在Polygon内
                            if (geometry.intersectsCoordinate(evt.coordinate)) {
                                infoRef.style.left = (evt.pixel[0] + 8) + 'px'
                                infoRef.style.top = (evt.pixel[1] + 8) + 'px'
                                infoRef.style.visibility = 'visible'
                                infoRef.innerHTML = `
                            <div style="color: #FF7E15;">病虫异常: ${feature.get("virusTreeCount")}/${feature.get("treeCount")}</div>
                            <div style="color: #FFE614;">生长异常: ${feature.get("growAbnormalTreeCount")}/${feature.get("treeCount")}</div>
                        `
                                return true;
                            }
                        }
                    }
                    if (layer instanceof VectorLayer && layer.get('name') === 'tree-cluster') {
                        // 获取要素的几何形状
                        let geometry = feature.getGeometry();
                        // 检查几何形状是否为Polygon
                        // 当前hover的features点位
                        const featureItem = feature.getProperties().features[0]
                        if (geometry instanceof Point && (featureItem.get("imgFilename") || featureItem.get("resFilename"))) {
                            // 使用geometry.intersectsCoordinate方法来检查点击的坐标是否在Polygon内
                            // imgInfo.style.left = (evt.pixel[0] - 250) + 'px'
                            // imgInfo.style.top = (evt.pixel[1] - 500) + 'px'
                            let img = featureItem.get("resFilename") ? featureItem.get("resFilename") : base_img_url2 + featureItem.get("imgFilename")
                            imgInfo.innerHTML = `
                            <img class="close-btn yse-events" src="${img}?x-oss-process=image/resize,m_fill,w_400" />
                        `
                            imgInfo.style.visibility = 'visible'
                            return true;
                        }
                    }
                });
            }, 500)
        });
        // that.kmap.on('pointerleave', that.clearTooltip(infoRef, imgInfo));
    }
    // 清除tooltip和定时器的函数
    clearTooltip(infoRef, imgInfo) {
        infoRef.style.visibility = 'hidden';
        infoRef.innerHTML = '';
        imgInfo.style.visibility = 'hidden';
        imgInfo.innerHTML = '';
        if (this.tooltipTimeout) {
            clearTimeout(this.tooltipTimeout);
            this.tooltipTimeout = null;
        }
    }

    fit(geomOrExtent){
        this.kmap.fit(geomOrExtent)
    }
    // 区级颜色
    handleStatusColor(key) {
        let fillColor = '#ffffff00'
        let strokeColor = '#ffffff00'
        switch (key) {
            case STATUS_ENUM.DONE:
                fillColor = 'rgba(95,255,197,0)'
                strokeColor = '#ffffff'
                break;
            case STATUS_ENUM.ABNORMAL_GROWTH:
                fillColor = 'rgba(255,189,5,0.2)'
                strokeColor = '#FFE44E'
                break;
            case STATUS_ENUM.ABNORMAL_Pest:
                fillColor = 'rgba(51,11,3,0.52)'
                strokeColor = '#F55A5A'
                break;
            case STATUS_ENUM.PENDING_REVIEW:
                fillColor = 'rgba(3,40,51,0.2)'
                strokeColor = '#032833'
                break;
            case STATUS_ENUM.REVIEWED:
                fillColor = 'rgba(95,255,197,0.1)'
                strokeColor = '#5FFFC5'
                break;
            default:
                break;
        }
        return {fillColor, strokeColor}
    }
    // 多个feature
    getFeaturesIcon(features) {
        let result = features.find(item => {
            // 获取Feature的属性
            let obj = item.getProperties();
            // 检查clusterIcon属性是否为1
            return obj.clusterIcon === 0;
        });
        // 如果没有找到，则尝试找到status为2的项
        if (!result) {
            result = features.find(item => {
                let obj = item.getProperties();
                // 检查clusterIcon属性是否为2
                return obj.clusterIcon === 1;
            });
        }
        // 如果没有找到，则尝试找到status为2的项
        if (!result) {
            result = features.find(item => {
                let obj = item.getProperties();
                // 检查clusterIcon属性是否为2
                return obj.clusterIcon === 2;
            });
        }
        if (!result) {
            result = features.find(item => {
                let obj = item.getProperties();
                // 检查clusterIcon属性是否为3
                return obj.clusterIcon === 3;
            });
        }
        if (!result) {
            result = features.find(item => {
                let obj = item.getProperties();
                // 检查clusterIcon属性是否为4
                return obj.clusterIcon === 4;
            });
        }
        if (!result) {
            result = features.find(item => {
                let obj = item.getProperties();
                // 检查clusterIcon属性是否为5
                return obj.clusterIcon === 5;
            });
        }
        if(!result){
            result = features[0]
        }
        return result;
    }
    // 状态图例
    handleStatusIcon(obj) {
        let key = null;
        switch (this.afterDayNum){
            case 0:
                key = 'ycStatus'
                break
            case 3:
                key = 'ycStatus'
                break
            case 5:
                key = 'ycStatus5d'
                break
            case 7:
                key = 'ycStatus7d'
                break
            case 15:
                key = 'ycStatus15d'
                break
            case 30:
                key = 'ycStatus30d'
                break
        }
        let hasStatus = false
        let imgSrc = require('@/assets/status/status_bcyc.png')
        if (obj[key] == 1) {
            hasStatus = true
            imgSrc = require('@/assets/status/status_szyc.png')
            return {hasStatus, imgSrc, clusterIcon: 1}
        }
        if (obj[key] == 2) {
            hasStatus = true
            imgSrc = require('@/assets/status/status_bcyc.png')
            return {hasStatus, imgSrc, clusterIcon: 2}
        }
        if (obj.review) {
            hasStatus = true
            imgSrc = require('@/assets/status/status_dfh.png')
            return {hasStatus, imgSrc, clusterIcon: 3}
        }
        if (obj.fly) {
            hasStatus = true
            imgSrc = require('@/assets/status/status_xfdw.png')
            return {hasStatus, imgSrc, clusterIcon: 4}
        }
        if (obj[key] == 0) {
            hasStatus = true
            imgSrc = require('@/assets/status/status_dfh.png')
            return {hasStatus, imgSrc, clusterIcon: 5}
        }
        return {hasStatus, imgSrc, clusterIcon: 0}

    }

    refreshTree(organId,day){
        this.afterDayNum = day
        this.initTree(organId)
    }
}

export default ZnxyMap
