<template>
    <div id="graphContainer" ref="graphContainer">
        <div v-show="floorKey" v-loading="canvasLoading">
            <el-row class="buttons-box">
                <div>
                    <el-autocomplete popper-class="my-autocomplete" v-model="search" :fetch-suggestions="querySearch"
                        placeholder="输入平面图中已有的业务空间名称进行查找" width="180px" @select="handleSelect">
                        <i class="el-icon-search el-input__icon" slot="suffix"></i>
                        <template slot-scope="{ item }">
                            <div class="name"
                                style="position: relative;padding-right:40px;overflow: hidden;text-overflow:ellipsis;white-space: nowrap;"
                                :title="item.data.RoomLocalName">
                                {{ item.data.RoomLocalName }}
                                <span class="addr" style="position: absolute;right:0;color:#409EFF;">定位</span>
                            </div>
                        </template>
                    </el-autocomplete>
                </div>
                <div class="button-group">
                    <!-- 默认操作模式 -->
                    <div v-if="type==1">
                        <el-dropdown split-button type="primary" @click="editGraphy" @command="handleCommand">
                            创建业务空间
                            <el-dropdown-menu slot="dropdown">
                                <!-- <el-dropdown-item command="groupCreateBSpace">批量创建业务空间</el-dropdown-item> -->
                                <el-dropdown-item command="createWall">创建墙体</el-dropdown-item>
                            </el-dropdown-menu>
                        </el-dropdown>
                        <!-- 点击已经关联的业务空间 -->
                        <el-button plain @click="refactorBSP" :disabled="zoneDisable" style="margin-left:10px;">编辑业务空间</el-button>
                        <!-- <el-button plain :disabled="zoneDisable" style="margin-left:10px;">维护空间信息</el-button> -->
                        <el-button plain @click="cancelGraphy" v-show="!zoneDisable">取 消</el-button>
                    </div>
                    <!-- 点击未关联的业务空间 -->
                    <div v-if="type==3">
                        <el-button plain @click="createNewZone">创建单个全新的业务空间</el-button>
                        <el-button plain @click="cancelGraphy">取 消</el-button>
                    </div>
                    <!-- 重新划分业务空间 -->
                    <div v-if="type==4">
                        <el-button plain @click="cancelGraphy">取 消</el-button>
                        <el-button type="primary" @click="saveRefactorBSP">保存</el-button>
                    </div>
                    <!-- 批量创建所选业务空间 -->
                    <div v-if="type==5">
                        <el-button type="primary" @click="groupCreateZone">批量创建所选业务空间</el-button>
                        <el-button plain @click="cancelGraphy">取 消</el-button>
                    </div>
                    <!-- 保存墙 -->
                    <div v-if="type==6">
                        <el-button plain @click="cancelGraphy">取 消</el-button>
                        <el-button type="primary" @click="saveMap">保存</el-button>
                    </div>
                </div>
            </el-row>

            <canvas id="spaceCanvas" :width="canvasWidth" :height="canvasHeight" tabindex="0"></canvas>

            <el-row class="canvas-actions-box">
                <canvas-fun :config="config" @fit="fit" @savePng="savePng" @saveSvg="saveSvg" @divide="divide" @clearDivide="clearDivide"
                    ref="canvasFun" @saveJson="saveJson" @changeAbsorb="changeAbsorb" @scale="scale" @groupSelect="groupSelect" @drawWall="drawWall"
                    @clearWall="clearWall" />
            </el-row>
        </div>
        <div v-show="!floorKey">
            <p style="text-align:center;margin-top:199px;">
                暂无数据
            </p>
        </div>
        <!-- 创建新的业务空间 -->
        <createBSP ref="createBSP" @createRoom="createRoom"></createBSP>
    </div>
</template>
<script lang="ts">
import { Vue, Component, Watch } from "vue-property-decorator";
import { FloorView } from "@/utils/graph/FloorView";
import { DivideFloorScene } from "@/utils/graph/DivideFloorScene";
import canvasFun from "./canvasFun.vue";
import {
    queryZone,
    queryIspace,
    createZone,
    updateZone,
} from "@/api/datacenter";
import createBSP from "./createBSP";
import colorArr from "@/utils/graph/config/zoneColor";
import { SObject } from "@persagy-web/base/lib";
import { ItemColor } from "@persagy-web/big/lib";
import { SSpaceItem } from "@persagy-web/big/lib/items/floor/SSpaceItem";
import { SZoneItem } from "@persagy-web/big/lib/items/floor/ZoneItem";
import { AppModule } from "@/store/modules/app";
import { watch } from "fs";
import { SWallItem } from "@persagy-web/big/lib/items/floor/SWallItem";
import { CustomWall } from "@/utils/graph/CustomWall";

@Component({
    components: { canvasFun, createBSP },
})
export default class spaceGraph extends Vue {
    canvasWidth = 800;
    canvasHeight = 800;
    view: FloorView | null = null;
    scene: DivideFloorScene | null = null;
    canvasLoading = false;
    type = 1;
    config = {
        isEdit: false,
        divide: true,
        groupSelect: false,
        drawWall: false,
    };
    search = ""; //搜索
    zoneDisable = true;
    curZoneItem = {};
    zoneList = [];
    buildFloor: string[] = [];
    floor = {}; // 当前楼层对象
    floorKey = ""; // 当前楼层底图请求完整url
    curZoneType = "";
    allzone = [];
    BSPRelaISPList = [];
    businessSpaceList = [];
    BIMIDToSID = {};
    BIMIDToSIName = {};
    sourceIdToISP = {};
    localFun = [];

    get mapBaseUrl() {
        return AppModule.mapBaseUrl;
    }

    // 挂载
    mounted(): void {
        this.canvasWidth = this.$refs.graphContainer.offsetWidth;
        this.canvasHeight = this.$refs.graphContainer.offsetHeight;
        // this.getGraph();
    }
    // 父组件调用查询楼层底图
    getData(floor: any, zoneType: any) {
        this.curZoneType = zoneType[zoneType.length - 1];
        this.canvasLoading = true;
        if (floor.infos && floor.infos.floorMap) {
            this.floor = floor;
            if (floor.infos.floorMap == this.floorKey) {
                this.init(2);
            } else {
                this.floorKey = floor.infos.floorMap;
                this.init(1);
            }
        } else {
            this.noMap();
        }
    }
    // 无底图时操作
    noMap() {
        this.floorKey = "";
        this.canvasLoading = false;
    }
    // 初始化
    init(initType: number): void {
        this.type = 1;
        if (this.scene) {
            this.scene.selectContainer.clear();
            this.scene.initSpaceColor();
            this.scene.clearCut();
            this.scene.clearWalls()
            this.zoneDisable = true;
            this.scene.isZoneSelectable = true;
            this.scene.isSpaceSelectable = false;
        }
        if (
            this.buildFloor.indexOf("all") > -1 ||
            this.buildFloor.indexOf("noKnow") > -1
        ) {
            return;
        }

        if (initType == 1) {
            // 底图
            this.getGraph();
        } else {
            // 业务空间
            this.getBussiness();
        }
        this.config = {
            isEdit: false,
            divide: true,
            groupSelect: true,
            drawWall: false,
        };
        if (this.$refs.canvasFun) {
            // @ts-ignore
            this.$refs.canvasFun.active = "";
        }
        // 获取当前楼层的元空间
        this.getFloorISpace();
    }
    // 获取底图
    getGraph(): void {
        const scene = new DivideFloorScene();
        this.canvasLoading = true;
        this.clearGraphy();
        this.scene = null;
        console.log(this.floorKey);
        scene.loadUrl(this.mapBaseUrl + this.floorKey).then((res) => {
            if (this.view) {
                this.view.scene = scene;
            }
            this.scene = scene;
            this.getGraphSuc(res);
        });
    }
    // 获取底图成功
    getGraphSuc(res: any): void {
        this.canvasLoading = false;
        if (res == "error") {
            this.noMap();
            this.$message.warning("数据解析异常");
            return;
        }
        if (this.view) {
            this.view.fitSceneToView();
            this.view.minScale = this.view.scale;
        }
        if (this.$refs.canvasFun) {
            // @ts-ignore
            this.$refs.canvasFun.everyScale = this.view.scale;
        }
        if (this.scene) {
            this.scene.changeSelect = this.changeSelect;
            this.scene.isSpaceSelectable = false;
        }
        this.getBussiness();
    }
    // 清除canvas
    clearGraphy() {
        if (this.view) {
            this.view.scene = null;
            return;
        }
        this.view = new FloorView("spaceCanvas");
    }
    // 搜索
    querySearch(queryString: string, cb: Function) {
        let restaurants = this.zoneList;
        let results = queryString
            ? restaurants.filter(this.createFilter(queryString))
            : restaurants;
        // 调用 callback 返回建议列表的数据
        cb(results);
    }
    // 过滤器
    createFilter(queryString: any) {
        return (restaurant: any) => {
            return restaurant.data.RoomLocalName.indexOf(queryString) > -1;
        };
    }
    // 查询选中,定位
    handleSelect(zone) {
        // 清空选中
        this.scene?.selectContainer.clear();
        this.curZoneItem = zone;
        this.scene?.selectContainer.setItem(zone);
        this.zoneDisable = false;
        this.view.fitSelectedToView();
    }
    // 点击创建业务空间
    editGraphy() {
        this.type = 3;
        this.config.isEdit = true;
        this.config.groupSelect = false;
        this.config.divide = true;
        this.config.drawWall = false;
        if (this.scene) {
            this.scene.isSpaceSelectable = true;
            this.scene.isZoneSelectable = false;
            this.scene.selectContainer.clear();
        }
        this.view?.update();
    }
    // 创建新的业务空间
    createNewZone() {
        if (this.scene) {
            let arr = this.scene.selectContainer.itemList;
            if (arr.length || this.scene.drawItem) {
                // 手绘的空间只有轮廓线可用
                let tempArr = [];
                this.localFun = [];
                arr.map((t) => {
                    tempArr.push(this.BIMIDToSIName[t.data.SourceId]);
                    if (
                        this.sourceIdToISP[t.data.SourceId] &&
                        this.sourceIdToISP[t.data.SourceId].infos
                    ) {
                        this.localFun.push(
                            this.sourceIdToISP[t.data.SourceId].infos
                        );
                    }
                });
                this.$refs.createBSP.showDialog(tempArr.toString());
            } else {
                this.$message.warning("请至少选择一个空间");
            }
        }
    }
    // 下拉菜单
    handleCommand(command: string) {
        if (command == "createWall") {
            // 绘制墙
            this.config.isEdit = true;
            this.config.groupSelect = false;
            this.config.divide = false;
            this.config.drawWall = true;
            this.type = 6;
            if (this.scene) {
                this.scene.isSpaceSelectable = false;
                this.scene.isZoneSelectable = false;
            }
        }
    }
    // 编辑业务空间
    refactorBSP() {
        this.config.isEdit = true;
        this.config.groupSelect = false;
        this.config.divide = true;
        this.config.drawWall = false;
        if (this.scene) {
            this.scene.isZoneSelectable = false;
            this.scene.isSpaceSelectable = true;
            this.scene.selectContainer.clear();
        }
        this.type = 4;
        this.curZoneItem.visible = false;
    }
    editeSpaceDetail() {}
    // 获取元空间
    getFloorISpace() {
        const pa = {
            floorId: this.floor.id,
            buildingId: this.floor.buildingId,
            pageSize: 2000,
        };
        queryIspace(pa).then((res) => {
            if (res.message == this.floor.id) {
                this.BIMIDToSID = {};
                this.BIMIDToSIName = {};
                this.sourceIdToISP = {};
                res.content.map((t) => {
                    let key = t.bimId.split(":")[1];
                    this.BIMIDToSID[key] = t.id;
                    this.BIMIDToSIName[key] = t.localName || t.name;
                    this.sourceIdToISP[key] = t;
                });
            }
        });
    }
    // 获取业务空间
    getBussiness() {
        const pa = {
            filters: `classCode='${this.curZoneType}';floorId='${this.floor.id}';buildingId='${this.floor.buildingId}'`,
            pageSize: 2000,
        };
        this.canvasLoading = true;
        queryZone(pa).then((res) => {
            // if (res.FloorId == this.buildFloor[1] && res.ZoneType == tempType) {
            // 所有业务空间
            this.businessSpaceList = res.content;
            // 已关联元空间的业务空间
            this.BSPRelaISPList = [];
            res.content.map((t) => {
                if (t.outline && t.outline.length) {
                    this.BSPRelaISPList.push(t);
                }
            });
            // 绘制业务空间
            let tempArr = this.BSPRelaISPList.map((t, i) => {
                return {
                    RoomLocalName: t.localName || t.name,
                    OutLine: t.outline,
                    RoomID: t.id,
                    Color: colorArr[i % colorArr.length],
                };
            }).filter((item) => item);
            console.log(this.scene);
            this.scene.removeAllZone();
            this.scene.addZoneList(tempArr);
            this.zoneList = this.scene.zoneList;
            this.view.update();
            this.canvasLoading = false;
            // }
        });
    }
    // 取消(所有取消公用)
    cancelGraphy() {
        this.init(2);
    }
    // 重新划分业务空间保存
    saveRefactorBSP() {
        let zoneObj = {
            id: this.curZoneItem.data.RoomID,
            classCode: this.curZoneType,
            outline: [],
        };
        // 没有业务空间,也没有绘制切割区域
        let arr = this.scene?.selectContainer.itemList;
        let temp = arr
            ?.map((t) => {
                return this.sourceIdToISP[t.data.SourceId]
                    ? this.sourceIdToISP[t.data.SourceId].infos
                    : undefined;
            })
            .filter((item) => item);
        if (temp?.length) {
            zoneObj.infos = temp[0];
        }
        if (this.scene) {
            zoneObj = this.setZoneOutline(zoneObj);
            this.handleUpdateZone(zoneObj);
        }
    }

    groupCreateZone() {}

    // 点击平面图事件
    changeSelect(selectContainer: SObject, data: any[]) {
        if (data.length) {
            console.log(data[0]);
            if (data[0].length) {
                if (data[0][0] instanceof SSpaceItem) {
                    this.scene?.initSpaceColor();
                } else if (data[0][0] instanceof SZoneItem) {
                    this.scene?.initZoneColor();
                    this.zoneDisable = false;
                    this.curZoneItem = data[0][0];
                }
            } else {
                this.scene?.initSpaceColor();
                if (this.type == 3) {
                    console.log(3);
                } else {
                    this.scene?.initZoneColor();
                    this.zoneDisable = true;
                }
            }
            data[0].forEach((t) => {
                t.fillColor = ItemColor.selectColor;
            });
        } else {
            this.scene?.initSpaceColor();
            this.scene?.initZoneColor();
            this.zoneDisable = true;
        }
    }

    // 根据图创建新的业务空间-弹窗返回确认创建
    createRoom(val) {
        let zoneObj = {
            outline: [],
            localName: val,
            buildingId: this.floor.buildingId,
            floorId: this.floor.id,
            classCode: this.curZoneType,
        };
        if (this.localFun.length) {
            zoneObj.infos = this.localFun[0];
        }
        if (this.scene) {
            // 旧逻辑--计算区域交集--
            // zoneObj = this.calIntersect(zoneObj);

            // 设置业务空间轮廓线
            zoneObj = this.setZoneOutline(zoneObj);
            this.handleCreateZone(zoneObj);
        }
    }

    /**
     * 生成底图json
     */
    saveMap() {
        if (this.scene) {
            const json = this.scene.getMapObject()
            console.log(json);
        }
    }

    /**
     * 画墙
     */
    drawWall() {
        if (this.scene) {
            this.scene.drawCmd = "wallDraw";
        }
    }

    /**
     * 单个计算交集
     */
    calIntersect(zoneObj: any) {
        // 画了切割区域
        if (this.scene.cutItem && this.scene.cutItem.closeFlag) {
            const seg = this.scene.getCurInZone();
            const poly = this.scene.getSpaceCutIntersect(seg);
            for (let key in poly) {
                for (let i = 0; i < poly[key].length; i++) {
                    const arr = poly[key][i].map((t) => {
                        return t.map((it) => {
                            return {
                                X: Number(it.x.toFixed(2)),
                                Y: -Number(it.y.toFixed(2)),
                                Z: 0,
                            };
                        });
                    });
                    zoneObj.outline.push(arr);
                }
            }
        } else if (this.scene.zoneList.length) {
            // 没画切割区域,但是有业务空间
            const poly = this.scene.getSpaceZoneIntersect();
            // 与已有业务空间的外接矩阵有交集
            if (poly) {
                for (let key in poly) {
                    for (let i = 0; i < poly[key].length; i++) {
                        const arr = poly[key][i].map((t) => {
                            return t.map((it) => {
                                return {
                                    X: Number(it.x.toFixed(2)),
                                    Y: -Number(it.y.toFixed(2)),
                                    Z: 0,
                                };
                            });
                        });
                        zoneObj.outline.push(arr);
                    }
                }
            } else {
                let arr = this.scene?.selectContainer.itemList;
                arr?.forEach((t) => {
                    zoneObj.outline.push(t.data.OutLine);
                });
            }
        } else {
            // 没有业务空间,也没有绘制切割区域
            let arr = this.scene?.selectContainer.itemList;
            arr?.forEach((t) => {
                zoneObj.outline.push(t.data.OutLine);
            });
        }
        return zoneObj;
    }

    /**
     * 新逻辑添加业务空间轮廓线
     */
    setZoneOutline(zoneObj: any) {
        if (this.scene) {
            if (this.scene.drawItem) {
                if (
                    this.scene.drawItem.pointList.length &&
                    this.scene.drawItem.pointList.length > 2
                ) {
                    const temp = this.scene.drawItem.pointList.map((t) => {
                        return {
                            X: t.x,
                            Y: -t.y,
                            Z: 0,
                        };
                    });
                    zoneObj.outline.push([temp]);
                }
            }
            let arr = this.scene.selectContainer.itemList;
            if (arr.length) {
                arr.forEach((t) => {
                    if (t instanceof SSpaceItem)
                        zoneObj.outline.push(t.data.OutLine);
                });
            }
        }
        return zoneObj;
    }

    /**
     * 创建业务空间接口
     */
    handleCreateZone(zoneObj: any) {
        const pa = {
            content: [zoneObj],
        };
        if (Array.isArray(zoneObj)) {
            pa.content = zoneObj;
        }
        this.canvasLoading = true;
        createZone(pa).then((res) => {
            this.$message.success("创建成功");
            this.init(2);
        });
    }

    /**
     * 更新业务空间接口
     */
    handleUpdateZone(zoneObj: any) {
        const pa = {
            content: [zoneObj],
        };
        if (Array.isArray(zoneObj)) {
            pa.content = zoneObj;
        }
        this.canvasLoading = true;
        updateZone(pa).then((res) => {
            this.$message.success("更新成功");
            this.init(2);
        });
    }

    // 适配底图到窗口
    fit() {
        this.view?.fitSceneToView();
    }
    // 保存为png
    savePng() {
        this.view?.saveImage(`1.png`, "png");
    }
    // 保存为svg
    saveSvg() {
        this.view?.saveSceneSvg(`1.svg`, 6400, 4800);
    }
    // 保存json
    saveJson() {
        try {
            this.view?.saveFloorJson(
                `${this.floor.build}-${this.floor.localName}.json`
            );
        } catch (err) {
            console.log(err);
            this.view?.saveFloorJson(`1.json`);
        }
    }
    // 切割划分
    divide() {
        if (this.scene) {
            this.scene.drawCmd = "zoneDraw";
        }
    }
    // 清除切割划分
    clearDivide() {
        // @ts-ignore
        this.view!.scene.clearCut();
    }
    // 缩放
    scale(val: number) {
        if (!this.view) {
            return;
        }
        let scale = this.view.scale;
        this.view.scaleByPoint(
            val / scale,
            this.canvasWidth / 2,
            this.canvasHeight / 2
        );
    }

    groupSelect() {
        console.log("groupSelect");
    }

    changeAbsorb() {
        console.log("changeAbsorb");
    }

    /**
     * 删除墙
     */
    clearWall() {
        if (this.scene) {
            if (this.scene.selectContainer.itemList.length) {
                const item = this.scene.selectContainer.itemList[0];
                if (item instanceof SWallItem || item instanceof CustomWall) {
                    this.scene.deleteItem(item)
                }
            }
        }
    }

    @Watch("view.scale", { immediate: true, deep: true })
    onScaleChange(n: number) {
        if (this.$refs.canvasFun) {
            // @ts-ignore
            let s = (n * 10) / this.view.minScale;
            // @ts-ignore
            this.$refs.canvasFun.sliderVal = s > 1000 ? 1000 : s;
        }
    }

    @Watch("scene.drawCmd", { immediate: true, deep: true })
    onCmdChange(n: string) {
        if (!n) {
            if (this.$refs.canvasFun) {
                this.$refs.canvasFun.active = "";
                this.$refs.canvasFun.isSwitch = false;
            }
        }
    }
}
</script>
<style lang="scss">
#graphContainer {
    position: relative;
    width: 100%;
    height: 100%;
    .canvas-actions-box {
        position: absolute;
        bottom: 14px;
        left: 50%;
        transform: translateX(-50%);
        z-index: 99;
    }
    .buttons-box {
        position: absolute;
        top: 16px;
        left: 0;
        padding: 0 16px;
        width: 100%;
        z-index: 999;
        & > div {
            float: left;
        }
        .el-autocomplete {
            display: inline-block;
            width: 320px;
            margin-right: 10px;
        }
        .button-group button,
        .button-group .el-dropdown {
            display: block;
            float: left;
        }
        .my-autocomplete {
            li {
                line-height: normal;
                padding: 7px;
                .name {
                    text-overflow: ellipsis;
                    overflow: hidden;
                }
                .addr {
                    font-size: 12px;
                    color: #b4b4b4;
                }
                .highlighted .addr {
                    color: #ddd;
                }
            }
        }
    }
}
</style>
