// API接口地址
const apiUrl = '/'; // api地址
const fileUrl = '/'; // 资源图片访问地址
//let mqttUrl = 'ws://11.11.16.18:8083/mqtt'; // 消息地址
let mqttUrl = 'ws://172.16.10.211:8083/mqtt';
const opts = {
 username: 'super',
 password: 'a123456'
}
const mapId = '448'; // 咸阳机场八公里地图id
// const mapId = '335'; // 大兴机场默认地图id
const mapCenter = {latitude: 34.44057509168785, longitude: 108.75939990930252}; // 咸阳机场地图中心点
// const mapCenter = { latitude: 39.509741556999984, longitude: 116.4128880570  0003 }; // 大兴机场地图中心点
//const mqttCarTopic = 'firecar';
const mqttCarTopic = 'carCoordinates';

if (mqttUrl.startsWith('/')) {
    mqttUrl = `${location.protocol === 'http:' ? 'ws' : 'wss'}://${location.host}${mqtt}`;
}

// 接口地址列表
const apiConsts = {
    alarmListUrl: 'jcs/command/JQ/list', // 即时警情列表 get
    alarmHistoryListUrl: 'jcs/command/history/list?pageNum=1&pageSize=1', // 历史警情 get
    currentAlarmUrl: 'jcs/command/getAlertCalledData', // 获取当前执行的灾情 get
    linkageForceUrl: 'jcs/command/linkageForce/list', // 联动力量列表 get
    rescueTeamUrl: 'jcs/command/ZQ/list', // 救援队伍列表 get
    miniFireStationUrl: 'jcs/command/WX/list', // 微型消防站列表 get
    sy500Url: 'jcs/command/SY500/list', // 500m水源列表 get
    sy1000Url: 'jcs/command/SY1000/list', // 1000m水源列表 get
    professionalTeamUrl: 'jcs/command/DW/list', // 志愿救援列表 get
    defendTargetUrl: 'jcs/command/ZDDW/list', // 重点单位列表 get
    videoUrl: 'jcs/command/video/list', // 视频列表 get
    fireCarUrl: 'jcs/command/fireCar/list', // 消防车辆列表 get
    assemblyPointListUrl: 'jcs/rally-point/list', // 集结点列表 get
    assemblyPointAddUrl: 'jcs/rally-point/save', // 集结点添加 post
    assemblyPointUpdateUrl: 'jcs/rally-point', // 集结点更新 put
    alarmLocationUpdateUrl: 'jcs/alert-called/reLocate', // 灾情经纬度更新 put
}

const resourceImgUrl = `${fileUrl}upload/jcs/common/map/`;
// 水源子类型
const waterChildResource = {
    hydrant: {title: '消火栓', img: `${resourceImgUrl}消火栓.png`},
    crane: {title: '消防水鹤', img: `${resourceImgUrl}消防水鹤.png`},
    pool: {title: '消防水池', img: `${resourceImgUrl}消防水池.png`},
    natural: {title: '天然水源', img: `${resourceImgUrl}天然水源.png`}
};
// 救援队伍子类型
const rescueTeam = {
    '117': {title: '企（事）业单位医疗救援队（站）', img: `${resourceImgUrl}企（事）业单位医疗救援队（站）.png`},
    '830': {title: '企（事）业单位专职消防救援支队', img: `${resourceImgUrl}企（事）业单位专职消防救援支队.png`},
}
// 消防资源
const resources = {
    'linkageForce': {
        title: '联动力量',
        rowKey: 'sequenceNbr',
        rowName: 'unitName',
        api: apiConsts.linkageForceUrl,
        img: `${resourceImgUrl}联动力量.png`,
        width: '32',
        height: '32'
    },
    'rescueTeam': {
        title: '救援队伍',
        rowKey: 'sequenceNbr',
        rowName: 'name',
        api: apiConsts.rescueTeamUrl,
        img: `${resourceImgUrl}救援队伍.png`,
        width: '32',
        height: '32',
        childName: 'typeCode',
        childType: rescueTeam
    },
    'miniFireStation': {
        title: '微型消防站',
        rowKey: 'sequenceNbr',
        rowName: 'name',
        api: apiConsts.miniFireStationUrl,
        img: `${resourceImgUrl}微型消防站.png`,
        width: '32',
        height: '32'
    },
    'SY500': {
        title: '500m水源',
        rowKey: 'id',
        rowName: 'sequenceNbr',
        api: apiConsts.sy500Url,
        img: `${resourceImgUrl}联动力量.png`,
        width: '32',
        height: '32',
        childName: 'resourceType',
        childType: waterChildResource
    },
    'SY1000': {
        title: '1000m水源',
        rowKey: 'id',
        rowName: 'sequenceNbr',
        api: apiConsts.sy1000Url,
        img: `${resourceImgUrl}联动力量.png`,
        width: '32',
        height: '32',
        childName: 'resourceType',
        childType: waterChildResource
    },
    'professionalTeam': {
        title: '志愿救援',
        rowKey: 'sequenceNbr',
        rowName: 'name',
        api: apiConsts.professionalTeamUrl,
        img: `${resourceImgUrl}志愿救援.png`,
        width: '32',
        height: '32'
    },
    'defendTarget': {
        title: '重点单位',
        rowKey: 'sequenceNbr',
        rowName: 'name',
        api: apiConsts.defendTargetUrl,
        img: `${resourceImgUrl}重点单位.png`,
        width: '32',
        height: '32'
    },
    'video': {
        title: '视频',
        rowKey: 'id',
        rowName: 'name',
        api: apiConsts.videoUrl,
        img: `${resourceImgUrl}视频.png`,
        width: '32',
        height: '32'
    },
};
// 集结定位点配置
const assemblyPointConf = {
    width: 36, height: 61.36, img: `${fileUrl}upload/jcs/common/map/车辆集结区.png`
};
// 灾情定位点配置
const alarmPointConf = {
    width: 36, height: 61.36, img: `${fileUrl}upload/jcs/common/map/警情定位.png`
};

const zbx = 4326; // 经纬度坐标系
const testData = {};
const xy = ({longitude, latitude}) => {
    const value1 = testData[longitude] || 502796 + Math.floor(Math.random() * (10 + 10) + -10) * 150;
    const value2 = testData[latitude] || 505115 + Math.floor(Math.random() * (10 + 10) + -10) * 150;
    testData[longitude] = value1;
    testData[latitude] = value2;
    return {
        x: testData[longitude],
        y: testData[latitude]
    };
};
const latLon = () => {
    const value1 = Math.floor(Math.random() * (10 + 10) + -10) * 0.001;
    const value2 = Math.floor(Math.random() * (10 + 10) + -10) * 0.001;
    return {
        longitude: 116.41288805700003 + value1,
        latitude: 39.509741556999984 + value2
    };
};
const superMapLayers = [
    {key: 'FYA_YJJJD_PT', title: '应急集结地'},
    {key: 'FYA_YJTD_PT', title: '应急通道'},
    {key: 'FYA_JSSGD_PT', title: '假设事故点'},
    {key: 'XF_XFS_PT', title: '消防栓'},
    {key: 'XF_XFSY_PT', title: '消防水源'},
    {key: 'YL_YLSS_PT', title: '医疗设施'},
    {key: 'LJW_LJWM_PG', title: '临建物面'},
    {key: 'DL_DLGD_PT', title: '电力管点'},
    {key: 'DL_DLGX_PL', title: '电力管线'},
    {key: 'DL_XFCKTXDLX_PG', title: '消防车可通行道路线'},
    {key: 'DL_XFCKTXDLM_PG', title: '消防车可通行路面'}
];

/**
 * 博能地图 api操作类
 */
class MapApi {
    constructor() {
        this.layers = {};
        this.init();
    }

    init(callback) {
        this.getLayer('pointcircle')
        this.layerHide(superMapLayers.map(e => e.key));
    }

    /**
     * 实时标点
     */
    streamPoint({data, noLine, hasData, layerName}) {
        const point = this.getLayer(layerName).graphics.find(e => e.id === data.id && e.amostype === data.type);
        if (point && point.data && point.data.speed === 0 && data.speed === 0) {
            return;
        }
        if (hasData && !point) {
            return;
        }
        let {x, y} = data || {};
        if (!x || !y) {
            this.latLonToXyByGaode([data]).then(d => {
                const graphic = this.getLayer(layerName).graphics.find(e => e.id === data.id && e.amostype === data.type);
                this.getLayer(layerName).remove(graphic);
                const _data = {...(point || {}).data || {}, ...data, x: d[0].x, y: d[0].y};
                this.addPoint({..._data, data: data}, this.getLayer(layerName));
                !noLine && this.streamLine(d[0].x, d[0].y, data.id);
            });
        } else {
            const graphic = this.getLayer(layerName).graphics.find(e => e.id === data.id && e.amostype === data.type);
            this.getLayer(layerName).remove(graphic);
            !noLine && this.streamLine(x, y, data.id);
            this.addPoint({...point.data || {}, ...data}, this.getLayer(layerName));
        }
    }

    /**
     * 实时轨迹
     */
    streamLine(x, y, id) {
        const layer = this.getLayer(`轨迹-${id}`);
        let lastXY = [x, y];
        if (layer.graphics.length > 0) {
            lastXY = layer.graphics[layer.graphics.length - 1].endXY;
        }
        const point = window.bnGeometry.createPolyline({
            paths: [[lastXY, [x, y]]],
            spatialReference: window.BNMap.spatialReference
        });
        const simpleLineSymbol = window.bnSymbol.simpleLineSymbol('solid', 'red', 2);
        const graphics = window.BNMap.graphic(point, simpleLineSymbol);
        graphics.objId = id;
        graphics.endXY = [x, y];
        layer.add(graphics);
    }

    /**
     * 切换地图
     * @param {*} mapId
     */
    switchMap(mapId) {
        window.BNMap.switchMap(mapId);
    }

    /**
     * 创建图层
     * @param {*} layerName 图层名称
     */
    createLayer(layerName) {
        const layer = window.BNMap.creatGraphicsLayer({id: layerName});
        if (!this.layers[layerName]) {
            layer.on('mouse-over', (event) => console.log(event.graphic));
            layer.on('click', (event) => {
                event.graphic && event.graphic.pointEvents && event.graphic.pointEvents.click && event.graphic.pointEvents.click(event)
            });
            layer.on('mouse-out', (event) => console.log(event.graphic));
            window.BNMap.addGraphicsLayer(layer);
        }
        this.layers[layerName] = layer;
    }

    /**
     * 获取图层对象
     * @param {*} layerName
     * @returns
     */
    getLayer(layerName) {
        if (!this.layers[layerName]) {
            this.createLayer(layerName);
        }
        return this.layers[layerName];
    }

    /**
     * 设置图层
     * @param {*} data
     */
    setMapLevel(data) {
        window.BNMap.setLevel(data);
    }

    /**
     * 定位
     * @param {*} data
     */
    location({id, type}) {
        Object.values(this.layers).find(layer => {
            if (layer && layer.graphics) {
                const graphic = layer.graphics.find(e => (type ? e.amostype === type : true) && e.id === id);
                if (graphic && graphic.geometry) {
                    window.BNMap.location(graphic);
                    return true;
                }
            }
            return false;
        });
    }

    /**
     * 当前位置定位
     * @param {*} param0
     */
    personLocation({id = 'currentUser', latitude, longitude}, flag) {
        const layerName = 'person';
        const point = this.getLayer(layerName).graphics.find(e => e.id === id);
        this.latLonToXyByGaode([latitude, longitude]).then(d => {
            const graphic = this.getLayer(layerName).graphics.find(e => e.id === id);
            this.getLayer(layerName).remove(graphic);
            const _data = {
                id,
                img: `${fileUrl}upload/jcs/common/resource/当前用户定位.png`,
                width: 24,
                height: 24,
                type: layerName,
                latitude,
                longitude,
                x: d[0].x,
                y: d[0].y
            };
            this.addPoint({..._data}, this.getLayer(layerName), () => {
                flag && this.location({id, type: layerName})
            });
        });
    }

    /**
     * 批量删除点
     * @param {list}} data
     */
    batchDeletePoint(list) {
        window.model && window.model.hide();
        Object.values(this.layers).forEach(layer => {
            if (layer && layer.graphics) {
                const deletegraphics = layer.graphics.filter(e => list.some(item => item.id === e.id && item.type === e.amostype));
                deletegraphics.forEach(e => layer.remove(e));
            }
        });
    }

    /**
     * 清除所有点
     * @param {Array} noDeletes 不需要清除的点数据
     */
    clearAll(noDeletes = []) {
        window.model && window.model.hide();
        Object.values(this.layers).forEach(layer => {
            const list = [];
            if (layer && layer.graphics) {
                layer.graphics.forEach((e, index) => {
                    if (noDeletes.find(item => item.type === e.amostype && item.id === e.id)) {
                        list.push(e);
                    }
                });
            }
            layer.clear();
            list.map(e => this.layers.add(e));
        });
    }

    /**
     * 地图标点周围画圈
     * @param {*} param
     */
    createPointCircle({id, type, radius, border = {}, polygon = {}}, flag) {
        Object.values(this.layers).find(layer => {
            if (layer && layer.graphics) {
                const graphic = layer.graphics.find(e => e.amostype === type && e.id === id);
                if (graphic) {
                    const circlelayer = this.getLayer('pointcircle');
                    const circle = window.bnGeometry.createCircle(graphic.geometry, {radius});
                    const simpleLineSymbol = window.bnSymbol.simpleLineSymbol(border.style || 'solid', border.color || 'red', border.width || '2');
                    const polygonsymbols = window.bnSymbol.polygonSymbol(polygon.style || 'solid', simpleLineSymbol, polygon.color || 'rgba(255, 0, 0, 0.2)');
                    const graphics = window.BNMap.graphic(circle, polygonsymbols);
                    graphics.id = `pointcircle_${id}`;
                    graphics.amostype = `pointcircle_${type}`;
                    graphics.attributes = {OBJECTID: graphics.id};
                    circlelayer.add(graphics);
                    // flag && layer.remove(graphic);
                    // // flag && layer.add(graphic);
                    return true;
                }
            }
            return false;
        });
    }

    /**
     * 清除地图标点周围的圈
     * @param {*} param
     */
    clearPointCircle({id, type, radius}) {
        if (!id) {
            this.getLayer('pointcircle').clear();
        }
        const circlelayer = this.getLayer('pointcircle');
        const pointcircle = circlelayer.graphics.find(e => e.id === `pointcircle_${id}` && e.amostype === `pointcircle_${type}`);
        if (pointcircle) {
            circlelayer.remove(pointcircle);
        }
    }

    /**
     * 设置中心点
     * @param {*} data
     */
    setMapCenter({latitude, longitude}) {
        this.latLonToXyByGaode([{latitude, longitude}]).then(data => {
            window.BNMap.setCenter && window.mapCenter && window.BNMap.setCenter(window.bnGeometry.createPoint(data[0].x, data[0].y, window.BNMap.spatialReference));
            window.BNMap.setPointCenter && window.BNMap.setPointCenter();
        });
    }

    addPoint({id, type, img, width, height, title, x, y, direction, directionOffset = 93, data, offset = [0, 0], hoverDetails, clickDetails, pointEvents}, layer, callback) {
        const symbols = window.bnSymbol.PictureMarkerSymbol(img, width, height).setOffset(...offset);
        if (direction === undefined) {
            symbols.angle = 0;
        } else {
            symbols.angle = parseInt(direction) - directionOffset; // 方向
        }
        const point = window.bnGeometry.createPoint(x, y, window.BNMap.spatialReference)
        const graphics = window.BNMap.graphic(point, symbols);
        graphics.id = id;
        graphics.data = data;
        graphics.amostype = type;
        graphics.title = title;
        graphics.attributes = {OBJECTID: id};
        graphics.hoverDetails = hoverDetails;
        graphics.clickDetails = clickDetails;
        graphics.pointEvents = pointEvents;
        layer.add(graphics);
        callback && callback();
    }

    /**
     * 鼠标点击获取地图点的经纬度
     * @param {*} data 为true时开始否则结束
     */
    setGetLatLon(data) {
        this.getlatlon = data;
    }

    /**
     * 点定位
     * @param {*} param0
     */
    pointLocation({latitude, longitude, x, y, img, width, height}) {
        this.getLayer('mapSdk_point_location').clear();
        const addRedPoint = (_x, _y) => {
            const point = window.bnGeometry.createPoint(_x, _y, window.BNMap.spatialReference);
            // 设置点样式
            let pointSymbols = !img ? window.bnSymbol.pointSymbol('red', '10') : window.bnSymbol.PictureMarkerSymbol(img, width, height);
            let graphics = window.BNMap.graphic(point, pointSymbols);
            this.getLayer('mapSdk_point_location').add(graphics);
            // 根据x、y输入框坐标定位点
            window.BNMap.location(graphics);
        };
        if (x && y) {
            addRedPoint(x, y);
        }
        if (latitude && longitude) {
            this.latLonToXyByGaode([{latitude, longitude}]).then(d => {
                addRedPoint(d[0].x, d[0].y);
            });
        }
    }

    /**
     * 关闭点定位
     */
    closePointLoction() {
        this.getLayer('mapSdk_point_location').clear();
    }

    /**
     * 图层清除
     * @param {*} layerName //图层名称
     */
    layerClear(layerName, like) {
        if (like) {
            Object.keys(this.layers).forEach(e => {
                if (e.includes(layerName)) {
                    this.getLayer(e).clear();
                }
            })
        } else {
            layerName && this.getLayer(layerName).clear();
        }
    }

    /**
     * 批量添加标点
     * @param {*} list
     */
    batchAddPoint({list, layerName}) {
        const points = list.filter(e => e.latitude && e.longitude);
        this.latLonToXyByGaode(list.filter(e => e.latitude && e.longitude)).then(data => {
            data.forEach((item, index) => {
                const point = points[index];
                const delPoint = this.getLayer(layerName).graphics.find(e => e.id === point.id && e.amostype === point.type);
                delPoint && this.getLayer(layerName).remove(delPoint);
                this.addPoint({...item, ...points[index]}, this.getLayer(layerName));
            });
            if (this.aggregation && layerName && layerName === this.aggregation.layerName) {
                this.pointAggregation(this.aggregation);
            }
        });
    }

    /**
     * 显示指定图层
     * @param {*} layerNames
     */
    layerShow(layerNames) {
        if (utils.isArray(layerNames)) {
            layerNames.forEach(e => {
                try {
                    const layer = window.BNMap.getLayer(e);
                    layer && !layer.visible && layer.show();
                } catch (error) {
                    console.log(error);
                }
            });
        }
    }

    /**
     * 隐藏指定图层
     * @param {*} layerNames
     */
    layerHide(layerNames) {
        if (utils.isArray(layerNames)) {
            layerNames.forEach(e => {
                try {
                    const layer = window.BNMap.getLayer(e);
                    layer && layer.visible && layer.hide();
                } catch (error) {
                    console.log(error);
                }
            });
        }
    }

    /**
     * 获取屏幕中心点对应的经纬度
     */
    getScreenCenterLatLon() {
        const mapWidth = window.BNMap.InnerMap.width;
        const mapHeight = window.BNMap.InnerMap.height;
        const data = window.BNMap.InnerMap.toMap(window.bnGeometry.createPoint(mapWidth / 2, mapHeight / 2, window.BNMap.spatialReference));
        return this.xyToLatLon(data.x, data.y);
    }

    measureByCoordinate(start, end, callback) {
        this.latLonToXyByGaode([start, end]).then((data) => {
            window.BNMap.measureByCoordinate({
                type: 'distance',
                paths: [[[data[0].x, data[0].y], [data[1].x, data[1].y]]]
            }, function (data) {
                data.lengths && callback(data.lengths[0]);
            }, null)
        })
    }

    /**
     * 经纬度转地图坐标
     */
    latLonToXyByGaode(list) {
        return new Promise((resolve, reject) => {
            try {
                window.bnUtil.doLatLngTransformMapXY(
                    list.map(e => [Number(e.longitude), Number(e.latitude)]),
                    zbx,
                    window.BNMap.spatialReference,
                    d => {
                        console.log('经纬度转地图坐标-成功==>', d, list);
                        resolve(d.map(b => ({x: b.x, y: b.y})));
                    },
                    error => {
                        resolve(list.map(e => xy(e)));
                    }
                );
            } catch (error) {
                resolve(list.map(e => xy(e)));
            }
        });
    }

    /**
     * 地图坐标转经纬度
     * @param x x轴
     * @param y y轴
     * @returns {Promise<unknown>}
     */
    xyToLatLon(x, y) {
        // 把xy地图坐标转化成经纬度
        return new Promise((resolve, reject) => {
            // 4326写死 指wgs84
            window.bnUtil.toLatLngTransformMapXY(
                [[Number(x), Number(y)]],
                window.BNMap.spatialReference,
                zbx,
                (data) => {
                    console.log('地图坐标转经纬度-成功==>', data);
                    // 获取坐标
                    resolve({longitude: data[0].x, latitude: data[0].y});
                },
                (e) => {
                    resolve(latLon());
                }
            );
        });
    };
}

/** 系统通用通信脚本 */
function H5ToNative(params) {
    const {channel, ...rest} = params;
    channel.postMessage(JSON.stringify(rest));
}

/** 调用native toast */
function toast(msg) {
    H5ToNative({
        data: msg,
        channel: CommonChanel,
        method: "showToast",
    });
}

/** 向 native 端发送推送数据 */
function toNativeMessage(msg) {
    H5ToNative({
        data: msg,
        channel: CommonChanel,
        method: "messageReceive",
    });
}

/**
 * 调用当前页面的指定方法
 * @param {*} method
 * @param {*} data
 * @param {String} success 执行成功后native调用h5 success方法
 */
function dispatchNativeMethod(method, data, success) {
    H5ToNative({
        data,
        channel: CommonChanel,
        method,
        success
    });
}

/**
 * 跳转具体的页面
 * @param {Object} params
 */
function goPage(params) {
    H5ToNative({
        ...params,
        channel: PageChange,
        method: "routeChange",
    });
}

/**
 * 通用通道
 * @param {Object} params
 * @example
 *  // 发送确认框
 * publicMessage({
 *   method: 'confirm',
 *   data: '切换火灾？'
 * });
 */
function publicMessage(params) {
    H5ToNative({
        ...params,
        channel: CommonChanel
    });
}

const utils = {
    isString(value) {
        return Object.prototype.toString.call(value) === '[object String]';
    },
    isFunction(value) {
        return Object.prototype.toString.call(value) === '[object Function]';
    },
    isUndefined(value) {
        return Object.prototype.toString.call(value) === '[object Undefined]';
    },
    isArray(value) {
        return Object.prototype.toString.call(value) === '[object Array]';
    }
};
/**
 * http 状态
 */
const HTTP_STATUS = {
    SUCCESS: 200,
    /** 未包含认证信息,如：未携带 token 信息 */
    NO_AUTH: 401,
    /** 认证已重置，如：其它地点登录 */
    RESET_AUTH: 409
};
const payload = (data) => {
    return new Promise((resolve, reject) => {
        if (data.state) {
            resolve(data);
        } else {
            if (data && data.status === HTTP_STATUS.SUCCESS) {
                resolve(data.result);
            } else {
                if (data && data.message) {
                    reject(data.message);
                } else if (data && data.devMessage) {
                    reject(data.devMessage);
                } else {
                    reject(data);
                }
            }
        }
    });
}

const request = {
    getHeaders() {

        return {
            "Content-Type": "application/json; charset=utf-8",
            token: getQueryVariable().token ? getQueryVariable().token : 'f4fcf0c5-590b-4ac2-bf4f-b5bcbecc819a',
            appKey: 'AMOS_ADMIN',
            product: getQueryVariable().token ? 'AMOS-APP-ADMIN' : 'AMOS_STUDIO_WEB',
        }
    },
    get(url) {
        const headers = this.getHeaders();
        return fetch(`${apiUrl}${url}`, {
            headers
        }).then(response => {
            return response.json();  // 先将结果转换为 JSON 对象
        }).then(payload);
    },
    post(url, data) {
        return fetch(`${apiUrl}${url}`, {
            method: 'POST',
            body: JSON.stringify(data || {}),
            headers: this.getHeaders()
        }).then(response => {
            return response.json();  // 先将结果转换为 JSON 对象
        }).then(payload);
    },
    put(url, data) {
        return fetch(`${apiUrl}${url}`, {
            method: 'PUT',
            body: JSON.stringify(data || {}),
            headers: this.getHeaders()
        }).then(response => {
            return response.json();  // 先将结果转换为 JSON 对象
        }).then(payload);
    }
}

/** 打印日志 */
function tipConsole(data) {
    const dom = document.getElementById('console');
    dom.innerHTML = `${dom.innerHTML}<div>${JSON.stringify({log: data})}</div>`;
    dom.style.display = 'block';
    dom.addEventListener('dblclick', function () {
        dom.innerHTML = '';
        dom.style.display = 'none';
    }, false)
}

/** 获取url参数 */
function getQueryVariable() {
    const query = window.location.search.substring(1);
    const vars = query.split("&");
    const result = {};
    for (let i = 0; i < vars.length; i++) {
        const pair = vars[i].split("=");
        result[pair[0]] = pair[1];
    }
    return result;
}

let pages = {
    battlemap: 'battlemap', // 作战地图页面
    assemblyPoint: 'assemblyPoint', // 集结点设置页面
    alarmPoint: 'alarmPoint', // 灾情定位页面,
    chooseLocation: 'chooseLocation', // 隐患定位页面,
}
let pageType = pages.battlemap; // 页面类型
let mapapi = null; // 地图操作API类
let _activeAlarm = null; // 当前警情对象
let alarmList = []; // 警情列表
let showCar = false; // 当前是否显示消防车辆
let mqttClient = null; // mqtt客户端对象
let _assemblyPointId = null; // 集结点Id
let _newAlarmLocation = {}; // 灾情新经纬度
let _newAssemblyLocation = {}; // 新集结点地址
/** 初始化作战地图页面 */
function mapinit(activeAlarmId, defalutActive) {
//    tipConsole('加载上>>>>');
    mapapi.setMapLevel(3);
    mapapi.setMapCenter(mapCenter);
    realTimeMessage();
    request.get(apiConsts.currentAlarmUrl).then(carAlarm => {
        if (!activeAlarmId && carAlarm) {
            activeAlarmId = carAlarm.sequenceNbr;
        }
        request.get(apiConsts.alarmListUrl).then(d => {
            alarmList = d || [];
            if (d && d.length > 0) {
                batchAlarmPoint(d);
                const activeAlarm = d.find(e => e.sequenceNbr === activeAlarmId);
                _activeAlarm = activeAlarm ? activeAlarm : (defalutActive ? d[0] : null);
                addAssemblyPoint();
                toNativeMessage({type: 'AlarmDisaster', content: _activeAlarm});
                fireCarPoint();
                setTimeout(() => {
                    locationAlarm();
                    alarmCircle(true);
                }, 500);
            }
        });
    })

}

function testFunc() {
    tipConsole('aaaaaaa');
}

function autoSwitchAlarm(alarm) {
    let alarmId = alarm.sequenceNbr || alarm;
    request.get(apiConsts.alarmListUrl).then(d => {
        if (alarmId) {
            const _alarm = (d || []).find(e => e.sequenceNbr === alarmId);
            // 该警情id为历史警情
            if (!_alarm) {
                request.get(`${apiConsts.alarmHistoryListUrl}&alertId=${alarmId}`).then(alarms => {
                    const historyAlarm = alarms.records[0];
                    if (historyAlarm) {
                        const list = [...d || [], historyAlarm];
                        _activeAlarm = historyAlarm;
                        swotchAlarms(list)
                    }
                });
            } else {
                _activeAlarm = _alarm;
                swotchAlarms(d)
            }
        } else {
            const _alarm = (d || []).find(e => e.sequenceNbr === activeAlarmId);
            // 当前警情变为历史警情
            if (!_alarm) {
                // 切换到第一个警情
            } else {
                batchAlarmPoint(d);
            }
        }
    });
}

function swotchAlarms(d) {
    batchAlarmPoint(d);
    toNativeMessage({type: 'AlarmDisaster', content: _activeAlarm});
    mapapi.layerClear('command_assemblyPoint');
    addAssemblyPoint();
    fireCarPoint();
    setTimeout(() => {
        locationAlarm();
        alarmCircle(true);
    }, 500);
}

/** 初始化集结点页面 */
function assemblyPointInit(activeAlarmId) {
    _assemblyPointId = getQueryVariable().assemblyPointId
    eventInit();
    mapapi.setMapLevel(3);
    mapapi.setMapCenter(mapCenter);
    initAssemblyPoint();
    request.get(apiConsts.alarmListUrl).then(d => {
        if (d && d.length > 0) {
            const activeAlarm = d.find(e => e.sequenceNbr === activeAlarmId);
            batchAlarmPoint([activeAlarm]);
            _activeAlarm = activeAlarm ? activeAlarm : null;
            setTimeout(() => {
                _assemblyPointId || locationAlarm();
                alarmCircle(true);
            }, 500);
            addAssemblyPoint(_assemblyPointId);
        }
    });
}

/** 初始化灾情定位页面 */
function alarmPointInit(activeAlarmId) {
    eventInit();
    mapapi.setMapLevel(3);
    mapapi.setMapCenter(mapCenter);
    initAlarmPoint();
    request.get(apiConsts.alarmListUrl).then(d => {
        if (d && d.length > 0) {
            _activeAlarm = d.find(e => e.sequenceNbr === activeAlarmId);
            batchAlarmPoint([_activeAlarm]);
            setTimeout(() => {
                locationAlarm();
                mapapi.batchDeletePoint([{id: activeAlarmId, type: _activeAlarm.alarmTypeCode}]);
                // alarmCircle(true);
            }, 500);
        }
    });
}

/**
 * 初始化隐患定位页面
 */
function initChooseLocation(longitude, latitude) {
    const lo = longitude ? longitude : mapCenter.longitude;
    const la = latitude ? latitude : mapCenter.latitude;
    const point = {longitude: lo, latitude: la};
    mapapi.setMapLevel(3);
    mapapi.setMapCenter(point);
    if (longitude && latitude) {
        mapapi.pointLocation(point);
    }
    window.BNMap.bindEvent(null, 'click', (evt) => {
        const {mapPoint} = evt || {};
        // 点击地图抓取经纬度
        mapapi.xyToLatLon(mapPoint.x, mapPoint.y).then(d => {
            mapapi.pointLocation({...this.getlatlon, x: mapPoint.x, y: mapPoint.y});
            toNativeMessage({type: 'chooseLocation', content: d});
        });
    });
}

/** 监听地图事件 */
function eventInit() {
    window.BNMap.bindEvent(null, 'pan-end', (evt) => {
        pageType === pages.assemblyPoint && signAssemblyPoint(evt);
        pageType === pages.alarmPoint && signAlarmPoint(evt);
    });
}

/** 批量标记灾点 */
function batchAlarmPoint(data) {
    const imgurl = `${fileUrl}upload/jcs/common/map/`
    const alarmTypeEmuns = {
        '229': `${imgurl}灾点-一般火灾.png`,
        '230': `${imgurl}灾点-航空器救援.png`,
        '235': `${imgurl}灾点-突发事件救援.png`,
        '237': `${imgurl}灾点-漏油现场安全保障.png`,
        '238': `${imgurl}灾点-专机保障.png`,
        '1214': `${imgurl}灾点-专机保障.png`,
        '242': `${imgurl}灾点-其他.png`
    };
    mapapi.batchAddPoint({
        list: data.map(e => {
            return {
                id: e.sequenceNbr,
                type: `${e.alarmTypeCode}`,
                title: e.alertType,
                img: alarmTypeEmuns[e.alarmTypeCode] || `${imgurl}灾点-一般火灾.png`,
                width: 46, height: 46,
                latitude: e.latitude, longitude: e.longitude,
                pointEvents: {
                    click: (event) => pageType === pages.battlemap && alarmClick(event, e)
                },
                data: e
            }
        }),
        layerName: 'command_alarm'
    });
}

/** 定位 */
function geoLocation(currentLngLat) {
    currentLngLat && mapapi.personLocation({latitude: currentLngLat.lat, longitude: currentLngLat.lng}, true);
}

/** 开启关闭灾圈 */
function alarmCircle(flag) {
    if (!_activeAlarm.sequenceNbr) return;
    mapapi.clearPointCircle({})
    const border = {style: 'solid', color: 'rgba(255, 0, 0, 0.1)', width: '0'};
    const polygon = {style: 'solid', color: 'rgba(255, 0, 0, 0.1)'};
    const innerBorder = {style: 'solid', color: 'rgba(255, 10, 0, 0.38)', width: '0'};
    const innerPolygon = {style: 'solid', color: 'rgba(255, 10, 0, 0.38)'};
    if (flag && _activeAlarm) {
        mapapi.createPointCircle({
            id: _activeAlarm.sequenceNbr,
            type: _activeAlarm.alarmTypeCode,
            radius: 200,
            border,
            polygon
        });
        mapapi.createPointCircle({
            id: _activeAlarm.sequenceNbr,
            type: _activeAlarm.alarmTypeCode,
            radius: 100,
            border: innerBorder,
            polygon: innerPolygon
        }, true);
    } else {
        mapapi.clearPointCircle({})
    }
}

/** 回到灾点 */
function locationAlarm(alarm) {
    if (!_activeAlarm.sequenceNbr) return;
    const _alarm = alarm || _activeAlarm;
    _alarm && mapapi.location({id: _alarm.sequenceNbr, type: _alarm.alarmTypeCode});
}

/** 清除 */
function mapClear() {
    [
        ...Object.keys(resources).map(type => `command_${type}`)
    ].map(e => mapapi.layerClear(e))
}

/** 添加消防资源 */
function addResources(types = []) {
    if (!_activeAlarm.sequenceNbr) return;
    types = types.find(e => e === 'all') ? Object.keys(resources) : types;
    const clearTypes = Object.keys(resources).filter(e => !types.some(item => item === e));
    removeResources(clearTypes);
    _activeAlarm && types.map(type => {
        const typeData = resources[type];
        request.get(`${typeData.api}?latitude=${_activeAlarm.latitude}&longitude=${_activeAlarm.longitude}&pageNum=1&pageSize=10000000`).then(data => {
            mapapi.batchAddPoint({
                list: (data.records ? (data.records || []) : data || []).map(e => {
                    return {
                        id: e[typeData.rowKey],
                        type: typeData.childType ? e[typeData.childName] : type,
                        title: e[typeData.rowName],
                        img: typeData.childType ? typeData.childType[e[typeData.childName]].img : typeData.img,
                        width: typeData.width, height: typeData.height,
                        latitude: e.latitude, longitude: e.longitude,
                        pointEvents: {
                            // click: (event) => alarmClick(event, e)
                        },
                        data: e
                    }
                }),
                layerName: `command_${type}`
            });
        })
    });
}

/** 删除消防资源 */
function removeResources(types = []) {
    if (!_activeAlarm.sequenceNbr) return;
    types.map(type => {
        mapapi.layerClear(`command_${type}`)
    });
}

/** 添加集结点资源 */
function addAssemblyPoint(hideId) {
    if (!_activeAlarm.sequenceNbr) return;
    request.get(`${apiConsts.assemblyPointListUrl}?alertId=${_activeAlarm.sequenceNbr}`).then(data => {
        mapapi.batchAddPoint({
            list: (data || []).map(e => {
                return {
                    id: e.sequenceNbr,
                    type: 'assemblyPoint',
                    title: e.title,
                    img: assemblyPointConf.img,
                    width: assemblyPointConf.width, height: assemblyPointConf.height,
                    latitude: e.latitude, longitude: e.longitude,
                    offset: [0, assemblyPointConf.height / 2],
                    pointEvents: {
                        click: (event) => pageType === pages.battlemap && clickAssemblyPoint(event, e)
                    },
                    data: e
                }
            }),
            layerName: 'command_assemblyPoint'
        });
        hideId && setTimeout(() => {
            mapapi.location({id: hideId});
            mapapi.batchDeletePoint([{id: hideId, type: 'assemblyPoint'}]);
        }, 500);
    })
}

/** 灾情点点击 */
function alarmClick(event, alarm) {
    if (_activeAlarm.sequenceNbr !== alarm.sequenceNbr) {
        // 调用 native 切换提示
        publicMessage({
            method: 'confirm',
            data: {
                msg: `确认要加入${alarm.address || ''}${alarm.alertType}灾情并退出当前灾情吗？`,
                // 点击 ok 的回调
                ok: 'switchAlarm',
                okCallbackArgs: JSON.stringify(alarm)
            }
        });
    }
}

/** 切换灾情 */
function switchAlarm(alarm, method) {
    _activeAlarm = alarm;
    mapClear();
    locationAlarm();
    alarmCircle(true);
    mapapi.layerClear('command_assemblyPoint');
    addAssemblyPoint();
    toNativeMessage({type: 'AlarmDisaster', content: _activeAlarm});
}

/** 初始化集结定位点 */
function initAssemblyPoint() {
    const dom = document.getElementById('setPointImg');
    dom.style.width = `${assemblyPointConf.width}px`;
    dom.style.height = `${assemblyPointConf.height}px`;
    dom.style.left = `calc(50% - ${assemblyPointConf.width / 2}px)`;
    dom.style.top = `calc(50% - ${assemblyPointConf.height}px)`;
    dom.src = assemblyPointConf.img;
    dom.style.display = 'inline-block';
}

/** 设置地图标记集结点 */
function signAssemblyPoint(event) {
    const dom = document.getElementById('setPointImg');
    dom.style.top = `calc(50% - ${assemblyPointConf.height + 20}px)`;
    setTimeout(() => {
        dom.style.top = `calc(50% - ${assemblyPointConf.height}px)`;
    }, 500);
    // mapapi.getScreenCenterLatLon().then(d => {
    //   _newAssemblyLocation = d;
    // });
}

/** 保存集结点数据 */
function assemblyPointSave(method) {
    if (!_activeAlarm.sequenceNbr) return;
    mapapi.getScreenCenterLatLon().then(d => {
        _newAssemblyLocation = d;
        const data = {
            name: '车辆集结区',
            latitude: _newAssemblyLocation.latitude,
            longitude: _newAssemblyLocation.longitude,
            alertId: _activeAlarm.sequenceNbr
        };
        if (_assemblyPointId) {
            request.put(`${apiConsts.assemblyPointUpdateUrl}/${_assemblyPointId}`, {sequenceNbr: _assemblyPointId, ...data}).then(data => {
                dispatchNativeMethod(method, null, 'refreshAssemblyPoint')
            });
        } else {
            request.post(apiConsts.assemblyPointAddUrl, {...data}).then(d => {
                dispatchNativeMethod(method, null, 'refreshAssemblyPoint')
            });
        }
    });
}

function refreshAssemblyPoint() {
    mapapi.layerClear('command_assemblyPoint');
    addAssemblyPoint();
}

function refreshAlarmPoint() {
    mapapi.layerClear('command_alarm');
    request.get(apiConsts.alarmListUrl).then(d => {
        if (d && d.length > 0) {
            batchAlarmPoint(d);
            const activeAlarm = d.find(e => e.sequenceNbr === _activeAlarm.sequenceNbr);
            _activeAlarm = activeAlarm ? activeAlarm : null;
            setTimeout(() => {
                locationAlarm();
                alarmCircle(true);
            }, 500);
            toNativeMessage({type: 'AlarmDisaster', content: _activeAlarm});
        }
    });
}

function getDistanceData(data) {
    if (!_activeAlarm.sequenceNbr) return;
    if (data.currentLngLat && data.targetLanLat) {

        // mapapi.measureByCoordinate(
        //   { latitude: data.currentLngLat.lat, longitude: data.currentLngLat.lng },
        //   { latitude: data.targetLanLat.latitude, longitude: data.targetLanLat.longitude },
        //   (distance) => {
        //     if (distance < 1000) {
        //       toNativeMessage({ type: data.msgType, content: `${distance}米` });
        //     } else {
        //       toNativeMessage({ type: data.msgType, content: `${(distance / 1000).toFixed}公里` });
        //     }
        //   }
        // )
    }
}

/** 点击集结点 */
function clickAssemblyPoint(event) {
    // 发送集结点数据
    toNativeMessage({type: 'editAssemblyPoint', content: event.graphic.data});
}

/** 初始化灾情定位点 */
function initAlarmPoint() {
    console.log('111111111111111111111111111111111111111')
    const dom = document.getElementById('setPointImg');
    dom.style.width = `${alarmPointConf.width}px`;
    dom.style.height = `${alarmPointConf.height}px`;
    dom.style.left = `calc(50% - ${alarmPointConf.width / 2}px)`;
    dom.style.top = `calc(50% - ${alarmPointConf.height}px)`;
    dom.src = alarmPointConf.img;
    dom.style.display = 'inline-block';
}

/** 设置地图标记灾情点 */
function signAlarmPoint(event) {
    const dom = document.getElementById('setPointImg');
    dom.style.top = `calc(50% - ${alarmPointConf.height + 20}px)`;
    setTimeout(() => {
        dom.style.top = `calc(50% - ${alarmPointConf.height}px)`;
    }, 500);
    // mapapi.getScreenCenterLatLon().then(d => {
    //   _newAlarmLocation = d;
    // });
}

/** 保存灾情位置 */
function alarmPointSave(method) {
    if (!_activeAlarm.sequenceNbr) return;
    mapapi.getScreenCenterLatLon().then(d => {
        _newAlarmLocation = d;
        request.put(`${apiConsts.alarmLocationUpdateUrl}?alertCalled=${_activeAlarm.sequenceNbr}&latitude=${_newAlarmLocation.latitude}&longitude=${_newAlarmLocation.longitude}`).then(data => {
            dispatchNativeMethod(method, null, 'refreshAlarmPoint')
        });
    });
}

/** 显示隐藏车辆 */
function fireCarPoint() {
    if (!_activeAlarm.sequenceNbr) return;
    if (!showCar) {
        request.get(apiConsts.fireCarUrl).then(data => {
            mapapi.batchAddPoint({
                list: data.map(e => {
                    return {
                        id: e.sequenceNbr,
                        type: 'fireCar',
                        title: `${e.name}${e.carNum}`,
                        img: `${fileUrl}upload/jcs/common/map/消防车.png`,
                        width: 44, height: 16,
                        latitude: e.latitude || e.sequenceNbr,
                        longitude: e.longitude || e.sequenceNbr,
                        pointEvents: {
                            // click: (event) => pageType === pages.battlemap && alarmClick(event, e)
                        },
                        data: {title: `${e.name}${e.carNum}`, ...e}
                    }
                }),
                layerName: 'command_firecar'
            });
        });
    } else {
        mapapi.layerClear('command_firecar');
        mapapi.layerClear('轨迹', true);
    }
    showCar = !showCar;
}

/** 实时车辆 */
function realTimeFireCar(message) {
//    console.log(message);
//    console.log(message,'接收到的经纬度',message.latitude,message.longitude);
//    tipConsole('打印经纬度>>>> :');
//    tipConsole(message.latitude);
//    tipConsole(message.longitude);
    if (showCar) {
        mapapi.streamPoint({
            data: {
                id: message.sequenceNbr, // 消防车id
                type: 'fireCar',
                speed: message.SPEED || 20, // 速度
                latitude: message.latitude, // 精度
                longitude: message.longitude, // 维度
                direction: message.DIRECTION || 90, // 方向角度
                directionOffset: 93, // 方向偏移角度
                img: `${fileUrl}upload/jcs/common/map/消防车.png`,
                width: 52, height: 20,
                pointEvents: {
                    // click: (event) => pageType === pages.battlemap && alarmClick(event, e)
                },
            }, noLine: false, hasData: true, layerName: 'command_firecar'
        });
    }
}

function Uint8ArrayToString(fileData) {
    let dataString = "";
    for (var i = 0; i < fileData.length; i++) {
        dataString += String.fromCharCode(fileData[i]);
    }
    return dataString
}

/** 实时消息 */
function realTimeMessage() {
//    tipConsole('mqtt加载>>>>');
    mqttClient = mqtt.connect(mqttUrl,opts);
    mqttClient.on('connect', () => {
        mqttClient.subscribe(mqttCarTopic, (error) => console.log(error));
    });
    mqttClient.on('error', () => mqttClient.end())
    mqttClient.on('message', (topic, message) => {
        if (topic.startsWith(mqttCarTopic)) {
          realTimeFireCar(JSON.parse(Uint8ArrayToString(message)));
        }
    })
}

require(["js/BNUtil", "js/BNFactory", "js/BNDirectorys", "js/jquery-3.2.1.min", "js/BNGeometry", "js/BNSymbol", "js/BNSymbolLibrary"],
    function (util, BNFactory, BNDirectorys, jquery, BNGeometry, BNSymbol, BNSymbolLibrary) {
        window.BNFactory = BNFactory;
        window.BNGeometry = BNGeometry;
        window.BNSymbol = BNSymbol;
        window.BNSymbolLibrary = BNSymbolLibrary;
        window.BNmapUtil = util;
        // window.BNMap = new window.BNFactory('448', {
        window.BNMap = new window.BNFactory(mapId, {
            'id': 'app',
            'options': {
                showLabels: true,
                logo: false,
                slider: false
            }
        });
        window.map = document.getElementById('app');
        window.bnUtil = new window.BNFactory('BNmapUtil', window.BNMap);
        window.bnGeometry = new window.BNGeometry();
        window.bnSymbol = new window.BNSymbol();
        window.BNMapExport = new BNFactory("BNMapExport", BNMap);
        // window.model = new window.BNFactory("BNWindow");
        window.BNCustomStreamLayer = new BNFactory("BNCustomStreamLayer", BNMap);
        window.BNPointAggregation = new window.BNFactory("BNPointAggregation", window.BNMap);
        window.BNMap.bindEvent(null, 'load', () => {
            mapapi = new MapApi();
            pageType = getQueryVariable().page || pages.battlemap;
            // window.BNMap.bindEvent(null, 'click', (evt) => {
            //   const graphic = evt.graphic;
            //   if (!graphic || !graphic.id) {
            //     // evt.stopPropagation();
            //     toNativeMessage({ type: 'mapClickEmpty', content: {} })
            //   }
            // });
            pageType === pages.battlemap && mapinit(getQueryVariable().alarmId, true);
            pageType === pages.assemblyPoint && assemblyPointInit(getQueryVariable().alarmId);
            pageType === pages.alarmPoint && alarmPointInit(getQueryVariable().alarmId);
            pageType === pages.chooseLocation && initChooseLocation(getQueryVariable().longitude, getQueryVariable().latitude);
        })
    }
)