<template>
    <div class="scenePacketListPanel">
        <div class="viewBox">
            <el-button icon="el-icon-view" @click="viewTree" type="primary"
                >模板预览</el-button
            >
        </div>

        <tableList ref="table" :columns="columns" :getDataWay="getDataWay">
            <el-table-column label="操作" slot="cgInfos" align="center" type="">
                <template v-slot="scope">
                    <i
                        v-if="
                            (scope.row.children &&
                                scope.row.children.length > 0) ||
                            (!scope.row.children && scope.row.sceneNum === 0) ||
                            (scope.row.children &&
                                scope.row.children.length === 0 &&
                                scope.row.sceneNum === 0)
                        "
                        @click="addIndicators(scope.row)"
                        class="el-icon-plus elIcon"
                        title="添加"
                    ></i>
                    <i
                        @click="editRow(scope.row)"
                        class="el-icon-edit-outline elIcon"
                        title="编辑"
                    ></i>
                    <i
                        v-if="scope.row.parentId != '0'"
                        @click="delRow(scope.row)"
                        class="el-icon-delete elIcon"
                        title="删除"
                    ></i>
                    <i
                        v-if="
                            !scope.row.children ||
                            scope.row.children.length === 0
                        "
                        @click="addScenario(scope.row)"
                        class="el-icon-document-add elIcon"
                        title="添加场景"
                    ></i>
                </template>
            </el-table-column>
            <el-table-column label="指标名称" slot="sublistName" align="left">
                <template v-slot="scope">
                    <span>{{ scope.row.sublistName }}</span>
                </template>
            </el-table-column>
            <el-table-column label="权重%" slot="weight" align="center">
                <template v-slot="scope">
                    <span v-if="scope.row.weightErr" style="color: red">{{
                        scope.row.weight
                    }}</span>
                    <span v-else>{{ scope.row.weight }}</span>
                </template>
            </el-table-column>
        </tableList>

        <div class="btns">
            <el-button
                type="primary"
                v-if="share === '0' || share === ''"
                @click="save(false)"
                >保存</el-button
            >
            <el-button
                type="primary"
                v-if="share === '0' || share === '1'"
                @click="save(true)"
                >另存为</el-button
            >
            <el-button type="primary" plain @click="cancel">取消</el-button>
        </div>

        <el-dialog
            :title="nameDiaTitle"
            :visible.sync="indicatorsVisible"
            width="690px"
            :close-on-click-modal="false"
            :close-on-press-escape="false"
            :before-close="indicatorsCancel"
        >
            <el-form
                ref="form"
                :model="form"
                :rules="rules"
                label-width="108px"
            >
                <el-form-item label="指标名称:" prop="sublistName">
                    <el-input
                        placeholder="请输入"
                        maxlength="20"
                        v-autoTrim="{ obj: form, key: 'sublistName' }"
                        v-model="form.sublistName"
                    >
                    </el-input>
                </el-form-item>
                <el-form-item label="权重%:" prop="weight">
                    <el-input
                        placeholder="请输入"
                        maxlength="6"
                        v-autoTrim="{ obj: form, key: 'weight' }"
                        v-model="form.weight"
                        :disabled="editType === 'edit' && isRoot"
                    >
                    </el-input>
                </el-form-item>
                <el-form-item label="备注:" prop="remarks">
                    <el-input
                        v-autoTrim="{
                            obj: form,
                            key: 'remarks',
                        }"
                        v-model="form.remarks"
                        type="textarea"
                        placeholder="请输入"
                        :autosize="{ minRows: 4, maxRows: 4 }"
                        maxlength="300"
                    ></el-input>
                </el-form-item>
            </el-form>
            <span slot="footer">
                <el-button type="primary" @click="indicatorsConfirm"
                    >确 定</el-button
                >
                <el-button @click="indicatorsCancel">取 消</el-button>
            </span>
        </el-dialog>

        <el-dialog
            title="场景分类"
            :visible.sync="scenarioVisible"
            width="690px"
            :close-on-click-modal="false"
            :close-on-press-escape="false"
            :before-close="scenarioCancel"
        >
            <el-form
                ref="formA"
                :model="formA"
                :rules="rulesA"
                label-width="108px"
            >
                <el-form-item label="场景分类:" prop="sceneType">
                    <el-select v-model="formA.sceneType">
                        <el-option
                            v-for="item in sceneTypeList"
                            :label="item.caption"
                            :value="item.code"
                            :key="item.code"
                        ></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="评分规则:" prop="rulesId">
                    <el-select v-model="formA.rulesId" @change="ruleSelChange">
                        <el-option
                            v-for="item in ruleList"
                            :label="item.ruleName"
                            :value="item.rulesId"
                            :key="item.rulesId"
                        ></el-option>
                    </el-select>
                </el-form-item>
            </el-form>
            <div class="tips">
                解释：基于不同环境要素，在前述主题场景及两条路径的框架下进行场景的精确细分。细分维度包括天气、季节、温度、路况、车况等多种元素，所采纳元素的广度和深度既与需求有关，也与汽车智能化程度（感知能力）相关
            </div>
            <span slot="footer">
                <el-button type="primary" @click="scenarioConfirm"
                    >下一步</el-button
                >
                <el-button @click="scenarioCancel">取 消</el-button>
            </span>
        </el-dialog>

        <el-dialog
            title="真实场景"
            :visible.sync="scenarioListsVisible"
            width="90%"
            class="scenarioListsDia"
            :close-on-click-modal="false"
            :close-on-press-escape="false"
            :before-close="scenarioListsCancel"
        >
            <real-scene-list ref="realScene"></real-scene-list>
            <span slot="footer">
                <el-button type="primary" @click="scenarioListsConfirm"
                    >确 定</el-button
                >
                <el-button @click="scenarioListsCancel">取 消</el-button>
            </span>
        </el-dialog>

        <el-dialog
            title="模板预览"
            :visible.sync="templateViewVisible"
            width="90%"
            class="templateViewDia"
            :close-on-click-modal="false"
            :close-on-press-escape="false"
            :before-close="templateViewClose"
        >
            <view-tree :data="treeData"></view-tree>
            <span slot="footer">
                <el-button type="primary" @click="templateViewClose"
                    >关 闭</el-button
                >
            </span>
        </el-dialog>
    </div>
</template>

<script>
import searchLayout from "@/components/grid/searchLayout";
import tableList from "@/components/grid/TableList";
import toolbarTab from "@/components/toolbar/toolbarTab";
import realSceneList from "./components/realSceneList";
import viewTree from "./components/elTree";

export default {
    name: "scenePacketList", // 场景数据包
    components: {
        searchLayout,
        tableList,
        toolbarTab,
        realSceneList,
        viewTree,
    },
    data() {
        let validateNum = (rule, value, callback) => {
            // 修改一级指标时，权重值为number类型，其余为string
            if (typeof value === "number") {
                value = value + "";
            }
            if (value == 0 || value > 100) {
                callback(new Error(rule.message));
                return;
            }
            if (value.startsWith("0")) {
                callback(new Error(rule.message));
                return;
            }
            if (value.includes(".")) {
                callback(new Error(rule.message));
                return;
            }
            !/^[1-9][0-9]*$/.test(value) && callback(new Error(rule.message));
            callback();
        };

        let validateSublistName = (rule, value, callback) => {
            this.nodeList = [];
            this.deepFirstSearch(this.getDataWay.data[0], this.nodeList);

            let names = this.nodeList
                .filter((i) => i.id != this.form.id)
                .map((i) => i.sublistName);
            if (names.includes(value)) {
                callback(new Error(rule.message));
                return;
            } else {
                callback();
            }
        };

        return {
            packageId: "",
            share: "",
            columns: [
                {
                    label: "操作",
                    prop: "cgInfos",
                    template: true,
                },
                {
                    label: "指标名称",
                    prop: "sublistName",
                    template: true,
                },
                {
                    label: "权重%",
                    prop: "weight",
                    template: true,
                },
                {
                    label: "场景数量",
                    prop: "sceneNum",
                },
                {
                    label: "规则名称",
                    prop: "ruleName",
                },
                {
                    label: "备注",
                    prop: "remarks",
                },
            ],
            getDataWay: {
                //加载表格数据
                dataType: "data",
                // 给出根节点
                data: [
                    {
                        children: null,
                        id: "1",
                        packageAndRules: "",
                        packageLevel: 1,
                        parentId: "0",
                        remarks: "",
                        rootId: null,
                        ruleName: "",
                        sceneGeneralizationIds: null,
                        sceneNaturalIds: "",
                        sceneNum: 0,
                        sceneStatueIds: null,
                        sceneTrafficIds: null,
                        seq: 0,
                        sublistName: "一级指标",
                        weight: 100,
                        treeNode: "一级指标" + " (" + 100 + "%)",
                    },
                ],
            },
            idIndex: 1, // 用做新增加点id自加，因为id为空会报错
            nameDiaTitle: "", // 编辑该级节点信息的dialog的title
            indicatorsVisible: false, // 编辑指标
            scenarioVisible: false, // 选择场景
            scenarioListsVisible: false, // 真实场景列表
            form: {
                sublistName: "",
                weight: "",
                remarks: "",
                id: "",
            },
            rules: {
                sublistName: [
                    { required: true, message: "请输入", trigger: "blur" },
                    {
                        validator: validateSublistName,
                        message: "指标名称重复",
                        trigger: ["blur"],
                    },
                ],
                weight: [
                    { required: true, message: "请输入", trigger: "blur" },
                    {
                        validator: validateNum,
                        message: "请输入大不于100的正整数",
                        trigger: ["blur"],
                    },
                ],
            },
            ruleList: [],
            formA: {
                sceneType: "1",
                ruleName: "",
                rulesId: "",
            },
            rulesA: {
                sceneType: [
                    { required: true, message: "请选择", trigger: "change" },
                ],
                rulesId: [
                    { required: true, message: "请选择", trigger: "change" },
                ],
            },
            sceneTypeList: [{ caption: "真实场景", code: "1" }],
            nodeList: [], // 把当前所有节点遍历到一个扁平数组
            curNode: {}, // 当前操作的节点
            editType: "", // 点操作编辑的类型 新增or编辑
            checkedIdsA: [], // 交通事故列表已选
            checkedIdsB: [], // 自然驾驶列表已选
            checkedIdsC: [], // 标准法规列表已选
            isRoot: false, // 是否是根节点
            templateViewVisible: false,
            treeData: [],
        };
    },

    computed: {},

    methods: {
        viewTree() {
            this.templateViewVisible = true;
            this.treeData = this.getDataWay.data;
        },
        delRow(row) {
            this.$confirm("确认是否删除？", "提示", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: "warning",
            }).then(() => {
                this.nodeList = [];
                this.deepFirstSearch(
                    this.getDataWay.data[0],
                    this.nodeList,
                    row.parentId
                );

                let index = this.curNode.children.findIndex(
                    (i) => i.id === row.id
                );
                this.curNode.children.splice(index, 1);

                this.checkWeightValidate();
            });
        },
        // 编辑该级节点信息
        editRow(row) {
            this.nameDiaTitle = "编辑指标";
            this.editType = "edit";
            this.indicatorsVisible = true;

            if (row.parentId === "0") {
                this.isRoot = true;
            } else {
                this.isRoot = false;
            }

            this.form.sublistName = row.sublistName;
            this.form.weight = row.weight;
            this.form.remarks = row.remarks;
            this.form.id = row.id;

            this.curNode = row;
        },
        // 增加该级节点的子节点
        addIndicators(row) {
            this.nameDiaTitle = "添加指标";
            this.editType = "add";

            this.indicatorsVisible = true;

            this.curNode = row;
        },
        // 添加场景
        addScenario(row) {
            this.curNode = row;

            if (row.packageAndRules) {
                this.formA.rulesId = row.packageAndRules;
                this.formA.ruleName = this.ruleList.find(
                    (i) => i.rulesId === row.packageAndRules
                ).ruleName;
            }

            this.scenarioVisible = true;
        },
        // 操作节点dialog的确定
        indicatorsConfirm() {
            this.$refs.form.validate((valid) => {
                if (valid) {
                    if (this.editType == "edit") {
                        // 编辑节点
                        this.curNode.sublistName = this.form.sublistName;
                        this.curNode.weight = this.form.weight;
                        this.curNode.remarks = this.form.remarks;
                        // 为了预览展示
                        this.curNode.treeNode =
                            this.form.sublistName +
                            " (" +
                            this.form.weight +
                            "%)";
                    } else {
                        // 新增节点
                        ++this.idIndex;
                        let node = {
                            children: null,
                            id: this.idIndex + "",
                            packageAndRules: "",
                            packageLevel: 1,
                            parentId: this.curNode.id || "",
                            remarks: this.form.remarks || "",
                            rootId: this.packageId,
                            ruleName: "",
                            sceneGeneralizationIds: null,
                            sceneNaturalIds: "",
                            sceneNum: 0,
                            sceneStatueIds: null,
                            sceneTrafficIds: null,
                            seq: 0,
                            sublistName: this.form.sublistName,
                            weight: this.form.weight,
                            treeNode:
                                this.form.sublistName +
                                " (" +
                                this.form.weight +
                                "%)",
                        };
                        if (!this.curNode.children) {
                            this.curNode.children = [];
                        }
                        this.curNode.children.push(node);
                    }

                    this.nodeList = [];
                    // 遍历当前树 拿到所有节点的平行展开数组
                    this.deepFirstSearch(
                        this.getDataWay.data[0],
                        this.nodeList
                    );

                    // console.log(this.getDataWay.data[0]);

                    this.checkWeightValidate();

                    this.indicatorsCancel();
                }
            });
        },
        // 操作节点dialog的取消
        indicatorsCancel() {
            this.$refs.form.resetFields();
            this.form.sublistName = "";
            this.form.weight = "";
            this.form.remarks = "";
            this.form.id = "";
            this.curNode = {};
            this.indicatorsVisible = false;
        },
        // 场景分类dialog的确定 下一步
        scenarioConfirm() {
            this.$refs.formA.validate((valid) => {
                if (valid) {
                    this.scenarioVisible = false;
                    this.scenarioListsVisible = true;

                    // 切换到第一个tab页并清空所有tab页中查询条件
                    this.$nextTick(() => {
                        this.$refs.realScene.activeName = "1";

                        this.$refs.realScene.doResetA();
                        this.$refs.realScene.doResetB();
                        this.$refs.realScene.doResetC();

                        // 把选中数据对应的ids组分别传入tabs中，用于后续操作数据进行存储
                        if (this.curNode.sceneTrafficIds) {
                            this.$refs.realScene.checkedIdsA =
                                this.curNode.sceneTrafficIds.split(",");
                        }
                        if (this.curNode.sceneNaturalIds) {
                            this.$refs.realScene.checkedIdsB =
                                this.curNode.sceneNaturalIds.split(",");
                        }
                        if (this.curNode.sceneStatueIds) {
                            this.$refs.realScene.checkedIdsC =
                                this.curNode.sceneStatueIds.split(",");
                        }
                    });
                }
            });
        },
        // 场景分类dialog的取消
        scenarioCancel() {
            this.$refs.formA.resetFields();
            this.formA.sceneType = "1";
            this.formA.ruleName = "";
            this.formA.rulesId = "";
            this.scenarioVisible = false;
            this.curNode = {};
        },
        // 选择真实场景dialog的确定
        scenarioListsConfirm() {
            // 获取选中的数据
            this.checkedIdsA = this.$refs.realScene.checkedIdsA;
            this.checkedIdsB = this.$refs.realScene.checkedIdsB;
            this.checkedIdsC = this.$refs.realScene.checkedIdsC;

            this.curNode.packageAndRules = this.formA.rulesId;
            this.curNode.ruleName = this.formA.ruleName;

            this.curNode.sceneNum =
                this.checkedIdsA.length +
                this.checkedIdsB.length +
                this.checkedIdsC.length;

            // 选择场景总数为0 则去掉对应的规则名称和id
            if (this.curNode.sceneNum === 0) {
                this.curNode.packageAndRules = "";
                this.curNode.ruleName = "";
            } else {
                this.curNode.packageAndRules = this.formA.rulesId;
                this.curNode.ruleName = this.formA.ruleName;
            }

            // 选中数据分别传入对应的ids组
            this.curNode.sceneTrafficIds = this.checkedIdsA.join(",");
            this.curNode.sceneNaturalIds = this.checkedIdsB.join(",");
            this.curNode.sceneStatueIds = this.checkedIdsC.join(",");

            this.nodeList = [];
            // 遍历当前树 拿到所有节点的平行展开数组
            this.deepFirstSearch(this.getDataWay.data[0], this.nodeList);

            if (this.curNode.parentId != "0") {
                this.sceneNumUpdate(this.curNode);
            }

            this.scenarioListsCancel();
        },
        // 选择真实场景dialog的取消
        scenarioListsCancel() {
            this.scenarioCancel();

            // 清空选中行数据
            this.$refs.realScene.$refs.tableA.$refs.ListTable.clearSelection();
            this.$refs.realScene.$refs.tableB.$refs.ListTable.clearSelection();
            this.$refs.realScene.$refs.tableC.$refs.ListTable.clearSelection();

            this.$refs.realScene.checkedIdsA = [];
            this.$refs.realScene.checkedIdsB = [];
            this.$refs.realScene.checkedIdsC = [];

            this.$refs.realScene.checkedArrA = [];
            this.$refs.realScene.checkedArrB = [];
            this.$refs.realScene.checkedArrC = [];

            this.$refs.realScene.selectedA = false;
            this.$refs.realScene.selectedB = false;
            this.$refs.realScene.selectedC = false;

            this.scenarioListsVisible = false;
        },
        // 校验权重
        checkWeightValidate() {
            this.allRowWeightErrFalse(this.getDataWay.data[0]);

            let ids = [];

            for (let index = 0; index < this.nodeList.length; index++) {
                const element = this.nodeList[index];
                if (element.children && element.children.length > 0) {
                    let total = 0;
                    let arr = [];
                    element.children.forEach((item) => {
                        // console.log(this.nodeList);
                        total += +this.nodeList.find((i) => i.id === item.id)
                            .weight;
                        arr.push(item.id);
                    });
                    if (total != 100) {
                        ids.push(...arr);
                    }
                }
            }
            this.rowWeightErrTrue(this.getDataWay.data[0], ids);
            // console.log(this.getDataWay.data[0]);
        },
        // 深度优先遍历
        /* deepFirstSearch(node, nodeList) {
            if (node) {
                nodeList.push(node);
                var children = node.children;
                if (children) {
                    for (var i = 0; i < children.length; i++)
                        //每次递归的时候将 需要遍历的节点 和 节点所存储的数组传下去
                        this.deepFirstSearch(children[i], nodeList);
                }
            }
            return nodeList;
        }, */
        // 通过深度优先找节点
        deepFirstSearch(node, nodeList, id) {
            if (node) {
                // 有id则把对应节点赋给当前操作节点
                if (id && node.id === id) {
                    this.curNode = node;
                }
                nodeList.push(node);
                var children = node.children;
                if (children) {
                    for (var i = 0; i < children.length; i++)
                        //每次递归的时候将 需要遍历的节点 和 节点所存储的数组传下去
                        this.deepFirstSearch(children[i], nodeList, id);
                }
            }
            return nodeList;
        },
        // 使全部节点 weightErr 为 false
        allRowWeightErrFalse(node) {
            if (node) {
                node.weightErr = false;
                var children = node.children;
                if (children) {
                    for (var i = 0; i < children.length; i++)
                        this.allRowWeightErrFalse(children[i]);
                }
            }
        },
        // 使部分节点 weightErr 为 true
        rowWeightErrTrue(node, arr) {
            if (node) {
                if (arr.includes(node.id)) {
                    node.weightErr = true;
                }
                var children = node.children;
                if (children) {
                    for (var i = 0; i < children.length; i++)
                        this.rowWeightErrTrue(children[i], arr);
                }
            }
        },
        save(isAdd) {
            this.nodeList = [];
            this.deepFirstSearch(this.getDataWay.data[0], this.nodeList);

            for (let index = 0; index < this.nodeList.length; index++) {
                const element = this.nodeList[index];
                if (element.children && element.children.length > 0) {
                    let total = 0;
                    let arr = [];
                    element.children.forEach((item) => {
                        total += +this.nodeList.find((i) => i.id === item.id)
                            .weight;
                        arr.push(item.sublistName);
                    });
                    if (total != 100) {
                        this.$message.error(
                            `${arr.join(",")}等权重相加应为100`
                        );
                        return;
                    }
                }
            }

            if (isAdd || !this.$route.query.packageId) {
                // 另存为或新增页面
                this.getDataWay.data[0].packageLevel = 1;
            } else {
                this.getDataWay.data[0].packageLevel = 0;
            }

            this.$axios({
                method: "post",
                url: this.$api.sceneLibrary.saveScenePackage,
                data: {
                    params: this.getDataWay.data,
                },
            }).then((res) => {
                if (res.code == 200) {
                    this.$message.success("保存成功");
                    this.cancel();
                } else {
                    this.$message.error(res.message || "保存失败");
                }
            });
        },
        cancel() {
            this.$router.replace({
                path: "/scenarioTestPackageManagementList",
            });
        },
        async getRuleList() {
            await this.$axios({
                method: "post",
                url: this.$api.sceneLibrary.queryCsb,
                data: {},
            }).then((res) => {
                if (res.code == 200 && res.info) {
                    this.ruleList = res.info;
                } else {
                    this.$message.error(res.message || "获取评分规则列表失败");
                }
            });
        },
        ruleSelChange(val) {
            this.formA.ruleName = this.ruleList.find(
                (i) => i.rulesId === val
            ).ruleName;
        },
        // 场景数量更新
        sceneNumUpdate(curNode) {
            let node = this.nodeList.find((i) => i.id === curNode.parentId);
            let sceneNum = 0;
            node.children.forEach((i) => {
                sceneNum += i.sceneNum;
            });

            node.sceneNum = sceneNum;

            if (node.parentId === "0") {
                return;
            }
            this.sceneNumUpdate(node);
        },
        templateViewClose() {
            this.templateViewVisible = false;
            this.treeData = [];
        },
    },

    mounted() {
        if (this.$route.query.packageId) {
            this.packageId = this.$route.query.packageId;
            this.share = this.$route.query.share;

            if (this.packageId) {
                this.$axios({
                    method: "post",
                    url: this.$api.sceneLibrary.queryScenePackageSublistList,
                    data: {
                        packageId: this.packageId,
                    },
                }).then((res) => {
                    if (res.code == 200 && res.info) {
                        this.getDataWay.data = res.info;
                    } else {
                        this.$message.error(res.message || "获取信息失败");
                    }
                });
            }
        }

        this.getRuleList();
    },
};
</script>

<style lang='less' scoped>
.scenePacketListPanel {
    padding: 30px;

    .viewBox {
        padding: 0 10px 10px;
    }

    .tips {
        padding: 10px 0 10px 18px;
        font-size: 12px;
        color: @gray;
    }

    .scenarioListsDia {
        /deep/ .el-dialog__body {
            padding: 20px 60px;
        }
    }

    .btns {
        padding: 30px 0;
        text-align: center;
    }

    .templateViewDia {
        /deep/ .el-dialog {
            max-height: 80%;
            overflow: auto;

            .el-dialog__body {
                max-height: calc(100%-130px);
                overflow: auto;
            }
        }
    }
}
</style>