import * as KMap from "@/utils/ol-map/KMap";
import { Vector as VectorSource, Cluster } from "ol/source.js";
import { Feature } from "ol";
import { WKT } from "ol/format";
import { Circle, Fill, Stroke, Style, Text, Icon, RegularShape } from "ol/style.js";
import Photo from "ol-ext/style/Photo";
import { newPoint, newPolymerFeature } from "@/utils/map.js";

import pointBgImg from "@/assets/images/map/point_bg.png";
import eventBus from "@/api/eventBus";

class DistributionLayer {
    constructor(kmap) {
        let that = this;
        this.kmap = kmap
        let vectorStyle = new KMap.VectorStyle()
        this.distributionLayer = new KMap.VectorLayer("distributionLayer", 99, {
            source: new VectorSource({}),
            style: function (f) {
                let style2 = vectorStyle.getPolygonStyle(f.get("color")+'4d', f.get("color"), 2)
                return [style2]
            }
        });
        this.kmap.addLayer(this.distributionLayer.layer)

        // 创建聚合数据源（必须提供一个非空的 VectorSource，避免内部调用 loadFeatures 时 source 为空报错）
        this.clusterSource = new Cluster({
            distance: 80, // 聚合距离（像素）
            minDistance: 50, // 最小聚合距离
            source: new VectorSource({}), // 给一个空的数据源即可，目前我们不再使用点位图层
        });

        // 提取单个点样式函数
        const getPointStyle = (feature, isCluster = false, clusterSize = 1) => {
            const label = feature.get("label") || "";
            const baseColor = feature.get("color") || "#2199F8";
            const farmName = feature.get("farmName") || "";
            const imgName = feature.get("imgName") || "";
            const speciesIcon = feature.get("speciesIcon");

            // 方块填充色背景（在白色描边 PNG 底图下方，参考 UI）
            const squareBgStyle = new Style({
                image: new RegularShape({
                    points: 4,
                    radius: 34, // 控制方块大小
                    angle: Math.PI / 4, // 旋转 45°，让正方形对齐
                    fill: new Fill({
                        color: baseColor,
                    }),
                    imgSize: [34, 34],
                    // 向上平移一点，让方块主要位于指针上方
                    displacement: [0, 4],
                }),
            });

            const iconAndTextStyle = new Style({
                image: new Icon({
                    src: pointBgImg,
                    scale: 0.45,
                }),
                // 文字 + 背景（参考 UI：白色圆角矩形 + 彩色文字）
                text: new Text({
                    text: label,
                    font: "normal 14px sans-serif",
                    offsetY: -46, // 文字整体上移，避免和图片重叠
                    textAlign: "center",
                    fill: new Fill({
                        color: baseColor,
                    }),
                    backgroundFill: new Fill({
                        color: "rgba(255,255,255,1)",
                    }),
                    backgroundStroke: new Stroke({
                        color: baseColor,
                        width: 1,
                    }),
                    padding: [2, 14, 2, 14],
                }),
            });

            // 聚合点数量徽章（红色圆形，白色文字，图片右上角）
            // 图片 scale 0.45，假设原始图片约 100x100，实际显示约 45x45
            // 右上角位置：offsetX 约 22-25，offsetY 约 -22-25（相对于图片中心）
            const badgeStyle = isCluster && clusterSize > 1
                ? new Style({
                    image: new Circle({
                        radius: 10,
                        fill: new Fill({
                            color: "#FF0000", // 红色
                        }),
                        // 定位到图片右上角
                        displacement: [22, 25], // 相对于图片中心，向右上偏移
                    }),
                    text: new Text({
                        text: clusterSize > 99 ? "99+" : clusterSize.toString(),
                        font: "bold 11px sans-serif",
                        fill: new Fill({
                            color: "#FFFFFF", // 白色文字
                        }),
                        // 文字位置与圆形位置一致
                        offsetX: 22,
                        offsetY: -25,
                        textAlign: "center",
                        textBaseline: "middle",
                    }),
                })
                : null;

            // 农场名称（显示在点位下方，白色文字）
            // 聚合点显示第一个点的农场名称
            const farmNameStyle = farmName
                ? new Style({
                    text: new Text({
                        text: farmName,
                        font: "normal 18px sans-serif",
                        offsetY: 45, // 向下偏移，位于点位下方
                        textAlign: "center",
                        fill: new Fill({
                            color: "#FFFFFF",
                        }),
                        stroke: new Stroke({
                            color: "rgba(0,0,0,0.6)",
                            width: 2,
                        }),
                    }),
                })
                : null;
            const typeImgStyle = new Style({
                image: new Icon({
                    // src: imgUrl,
                    src: speciesIcon,
                    scale: 0.8,
                    displacement: [0, 4],
                }),
            });

            // 先画纯色方块，再画白色描边 PNG 和文字，然后画徽章，最后画农场名称
            const styles = [squareBgStyle, iconAndTextStyle];
            if (speciesIcon) styles.push(typeImgStyle);
            if (badgeStyle) styles.push(badgeStyle);
            if (farmNameStyle) styles.push(farmNameStyle);
            return styles;
        };

        this.distributionPointLayer = new KMap.VectorLayer("distributionPointLayer", 99, {
            source: this.clusterSource,
            style: (f) => {
                // 判断是否为聚合点
                const features = f.get('features');
                if (features && features.length > 1) {
                    // 聚合点：使用第一个点的样式，但添加数量标识
                    const firstFeature = features[0];
                    return getPointStyle(firstFeature, true, features.length);
                }
                // 单个点样式（原有逻辑）
                const singleFeature = features && features.length === 1 ? features[0] : f;
                return getPointStyle(singleFeature, false, 1);
            },
        });
        this.kmap.addLayer(this.distributionPointLayer.layer)

        // 设施图层：只显示图标（冷链冷库 / 加工厂等），不带边框和文字
        this.facilityPointLayer = new KMap.VectorLayer("facilityPointLayer", 100, {
            source: new VectorSource({}),
            style: function (f) {
                const imgName = f.get("imgName") || "";
                return new Style({
                    image: new Icon({
                        src: imgName,
                        imgSize: [45, 45],
                        width: 45,
                        height: 45,
                        scale: 0.9,
                    }),
                });
            },
        });
        this.kmap.addLayer(this.facilityPointLayer.layer)

        // 标志：是否启用农场分布点击处理
        this.enableFarmClick = false;

        // 添加点击事件监听，用于处理农场分布的点击交互
        this.clickHandler = (event) => {
            if (this.enableFarmClick) {
                this.handlePointClick(event);
            }
        };
        this.kmap.on('singleclick', this.clickHandler);
    }

    /**
     * 启用/禁用农场分布点击处理
     * @param {boolean} enable - 是否启用
     */
    setFarmClickEnabled(enable) {
        this.enableFarmClick = enable;
    }

    /**
     * 处理点位点击事件
     * 如果是聚合点，放大地图；如果是单个农场，打印提示
     */
    handlePointClick(event) {
        const pixel = event.pixel;
        const coordinate = event.coordinate;
        
        // 检查是否点击到了 distributionPointLayer
        const clickedFeature = this.kmap.map.forEachFeatureAtPixel(pixel, (feature, layer) => {
            if (layer === this.distributionPointLayer.layer) {
                return feature;
            }
            return null;
        });

        if (!clickedFeature) {
            return;
        }

        // 获取聚合点内的所有 features
        const features = clickedFeature.get('features');
        
        if (features && features.length > 1) {
            // 是聚合点，放大地图
            const view = this.kmap.map.getView();
            const currentZoom = view.getZoom();
            const newZoom = Math.min(currentZoom + 2, view.getMaxZoom() || 22);
            
            view.animate({
                center: coordinate,
                zoom: newZoom,
                duration: 300
            });
        } else if (features && features.length === 1) {
            // 是单个农场，通过事件总线发送事件
            const farmFeature = features[0];
            const farmData = farmFeature.getProperties();
            // 通过事件总线发送农场点击事件
            eventBus.emit('distributionLayer:farmClick', farmData);
        }
    }

    /**
     * 清空当前图层上的所有数据
     */
    clear() {
        if (this.distributionLayer && this.distributionLayer.source) {
            this.distributionLayer.source.clear();
        }
        if (this.clusterSource) {
            const source = this.clusterSource.getSource();
            if (source) {
                source.clear();
            }
        }
        if (this.facilityPointLayer && this.facilityPointLayer.source) {
            this.facilityPointLayer.source.clear();
        }
    }

    initData(data, field = 'speciesName') {
        // 每次加载前先清空旧数据（多用于"作物分布 / 物候期分布 / 农场分布"）
        this.clear();
        if(!data || data.length === 0) return;

        for (let item of data) {
            // 面数据（区域多边形）
            if (item.geom) {
                item.color = item.color || "#2199F8";
                this.distributionLayer.source.addFeature(newPolymerFeature(item));
            }
        }

        // 地块面渲染完成后，按照面要素自适应地图范围（不再根据点位来缩放）
        const extent = this.distributionLayer.source.getExtent();
        if (extent && !isNaN(extent[0])) {
            this.kmap.map.getView().fit(extent, {
                padding: [50, 50, 50, 50],
                duration: 500,
            });
        }
    }

    /**
     * 设施数据加载（冷链冷库 / 加工厂）
     * 只操作 facilityPointLayer，不影响作物分布图层
     */
    initFacilityData(list = []) {
        if (!this.facilityPointLayer || !this.facilityPointLayer.source) return;
        this.facilityPointLayer.source.clear();

        const extentSource = new VectorSource({});

        for (let item of list) {
            if (!item.wktArr) continue;
            for (let wkt of item.wktArr) {
                const f = new Feature({
                    geometry: new WKT().readGeometry(wkt),
                });
                f.set("imgName", item.imgName);
                this.facilityPointLayer.source.addFeature(f);
                extentSource.addFeature(f);
            }
        }

        const extent = extentSource.getExtent();
        if (extent && !isNaN(extent[0])) {
            this.kmap.map.getView().fit(extent, {
                padding: [280, 400, 200, 150],
                duration: 500,
            });
        }
    }
}



export default DistributionLayer;