<template>
    <div class="Segmentations" v-loading="loading">
        <h3 style="color: #fff;margin: 0;padding: 15px 10px 5px" v-if="series.TaskInfo">
            <span>{{ series.TaskInfo.SubjectCode }} </span>
            <span style="margin-left:5px;">{{ series.TaskInfo.TaskBlindName }}</span>
        </h3>
        <el-collapse v-model="activeNames">
            <el-collapse-item name="tools">
                <template slot="title">
                    {{ $t('trials:reading:Segmentations:title:tools') }}
                </template>
                <div class="tool-frame">
                    <div :title="$t('trials:Segmentations:tools:contour')"
                        :class="['tool-item', activeTool === 'LabelMapEditWithContour' && segmentList.length > 0 ? 'tool-item-active' : '']"
                        :style="{ cursor: isMPR || segmentList.length <= 0 || (curSegment && curSegment.lock) || ['viewport-MPR-1', 'viewport-MPR-2'].includes(`${viewportKey}-${activeViewportIndex}`) ? 'not-allowed' : 'pointer' }"
                        @click.prevent="setToolActive('LabelMapEditWithContour')">
                        <svg-icon icon-class="contour" class="svg-icon" />
                    </div>
                    <div :title="$t('trials:Segmentations:tools:thresholecircle')"
                        :class="['tool-item', ThresholdTools.includes(activeTool) && segmentList.length > 0 ? 'tool-item-active' : '']"
                        :style="{ cursor: isMPR || segmentList.length <= 0 || (curSegment && curSegment.lock) || ['viewport-MPR-1', 'viewport-MPR-2'].includes(`${viewportKey}-${activeViewportIndex}`) ? 'not-allowed' : 'pointer' }"
                        @click.prevent="initThreshold()">
                        <svg-icon icon-class="thresholecircle" class="svg-icon" />
                    </div>
                    <div :title="$t('trials:Segmentations:tools:circularbrush')"
                        :class="['tool-item', activeTool === 'CircularBrush' && segmentList.length > 0 ? 'tool-item-active' : '']"
                        :style="{ cursor: isMPR || segmentList.length <= 0 || (curSegment && curSegment.lock) || ['viewport-MPR-1', 'viewport-MPR-2'].includes(`${viewportKey}-${activeViewportIndex}`) ? 'not-allowed' : 'pointer' }"
                        @click.prevent="setToolActive('CircularBrush')">
                        <svg-icon icon-class="circularbrush" class="svg-icon" />
                    </div>
                    <div :title="$t('trials:Segmentations:tools:SphericalBrush')"
                        :class="['tool-item', activeTool === 'SphericalBrush' && segmentList.length > 0 ? 'tool-item-active' : '']"
                        :style="{ cursor: isMPR || segmentList.length <= 0 || (curSegment && curSegment.lock) || ['viewport-MPR-1', 'viewport-MPR-2'].includes(`${viewportKey}-${activeViewportIndex}`) ? 'not-allowed' : 'pointer' }"
                        @click.prevent="initThreshold('SphericalBrush')">
                        <svg-icon icon-class="sphericalBrush" class="svg-icon" />
                    </div>
                    <div :class="['tool-item', activeTool === 'CircularEraser' && segmentList.length > 0 ? 'tool-item-active' : '']"
                        :style="{ cursor: isMPR || segmentList.length <= 0 || (curSegment && curSegment.lock) || ['viewport-MPR-1', 'viewport-MPR-2'].includes(`${viewportKey}-${activeViewportIndex}`) ? 'not-allowed' : 'pointer' }"
                        :title="$t('trials:Segmentations:tools:Eraser')"
                        @click.prevent="setToolActive('CircularEraser')">
                        <svg-icon icon-class="clear" class="svg-icon" />
                    </div>
                    <!-- <div :class="['tool-item']"> 
                        <input type="file" @change="beginScanFiles($event)">
                    </div> -->
                </div>
                <div class="ConfigBox">
                    <div class="EraserConfig"
                        v-if="activeTool === 'SphericalBrush' || activeTool === 'CircularEraser' || activeTool === 'CircularBrush' || ThresholdTools.includes(activeTool)">
                        <span>{{ $t('trials:reading:Segmentations:title:EraserConfigSection') }}</span>
                        <el-select v-model="sliderMax" placeholder="" size="small" @change="handleSliderChange">
                            <el-option v-for="item in sliderSection" :key="item.id" :label="item.label"
                                :value="item.max">
                            </el-option>
                        </el-select>
                    </div>
                    <div class="EraserConfig RadiusConfig"
                        v-if="activeTool === 'SphericalBrush' || activeTool === 'CircularEraser' || activeTool === 'CircularBrush' || ThresholdTools.includes(activeTool)">
                        <span>{{ $t('trials:reading:Segmentations:title:EraserConfig') }}</span>
                        <el-slider v-model="brushSize" show-input :step="sliderStep" :max="sliderMax" input-size="mini"
                            :show-input-controls="false" />
                    </div>
                    <div class="EraserConfig" v-if="ThresholdTools.includes(activeTool)">
                        <span>{{ $t('trials:reading:Segmentations:title:thresholdType') }}</span>
                        <el-radio-group v-model="thresholdType" @input="(key) => setToolActive(key)">
                            <el-radio-button :label="tool" v-for="tool of ThresholdTools" :key="tool" size="mini">
                                {{ $t(`trials:reading:Segmentations:radioButton:${tool}`) }}
                            </el-radio-button>
                        </el-radio-group>
                    </div>
                    <div class="EraserConfig" v-if="ThresholdTools.includes(activeTool)">
                        <span>{{ $t('trials:reading:Segmentations:title:isDynamic') }}</span>
                        <el-radio-group v-model="brushThreshold.isDynamic">
                            <el-radio-button :label="true" size="mini">
                                {{ $t('trials:reading:Segmentations:radioButton:Dynamic') }}
                            </el-radio-button>
                            <el-radio-button :label="false" size="mini">
                                {{ $t('trials:reading:Segmentations:radioButton:Rang') }}
                            </el-radio-button>
                        </el-radio-group>
                    </div>
                    <div class="EraserConfig" v-if="ThresholdTools.includes(activeTool) && !brushThreshold.isDynamic">
                        <span>{{ $t('trials:reading:Segmentations:title:range') }}</span>
                        <div style="display: flex;align-items: center;">
                            <el-input-number v-model="brushThreshold.range[0]" :controls="false" :step="1"
                                :max="brushThreshold.range[1]" size="small" />
                            <span style="margin: 0 10px;">--</span>
                            <el-input-number v-model="brushThreshold.range[1]" :controls="false" :step="1"
                                :min="brushThreshold.range[0]" size="small" />
                        </div>
                    </div>
                </div>
            </el-collapse-item>
            <el-collapse-item name="Segment">
                <template slot="title">
                    <div class="SegmentTitle">
                        {{ $t('trials:reading:Segmentations:title:Segment') }}
                        <svg-icon icon-class="individuation" class="svg-icon" style="margin-right: 10px;"
                            @click.stop="changeShowSegmentConfig" />
                    </div>
                </template>
                <div class="addSegmentBox viewHover" @click.stop="addSegment"
                    v-if="segmentList.length <= 0 && readingTaskState < 2">
                    <span><i class="el-icon-plus"></i>
                        {{ $t('trials:reading:Segmentations:button:addSegmention') }}
                    </span>
                </div>
                <div class="SegmentConfigBox" v-if="showSegmentConfig && segmentList.length > 0">
                    <div class="SegmentConfig">
                        <span>{{ $t('trials:reading:Segmentations:title:Show:Fill&Outline') }}</span>
                        <div style="display: flex;">
                            <div :class="['tool-item', SegmentConfig.renderOutline && SegmentConfig.renderFill ? 'tool-item-active' : '']"
                                :title="$t('trials:dicom-show:fill_outline')"
                                @click.stop="changeSegmentConfig(true, true)">
                                <svg-icon icon-class="fill_outline" class="svg-icon" />
                            </div>
                            <div :class="['tool-item', SegmentConfig.renderOutline && !SegmentConfig.renderFill ? 'tool-item-active' : '']"
                                :title="$t('trials:dicom-show:outline')" @click.stop="changeSegmentConfig(true, false)">
                                <svg-icon icon-class="outline" class="svg-icon" />
                            </div>
                            <div :class="['tool-item', !SegmentConfig.renderOutline && SegmentConfig.renderFill ? 'tool-item-active' : '']"
                                :title="$t('trials:dicom-show:fill')" @click.stop="changeSegmentConfig(false, true)">
                                <svg-icon icon-class="fill" class="svg-icon" />
                            </div>


                        </div>
                    </div>
                    <div class="SegmentConfig">
                        <span>{{ $t('trials:reading:Segmentations:title:Opacity') }}</span>
                        <el-slider v-model="SegmentConfig.fillAlpha" show-input :step="0.1" :max="1" input-size="mini"
                            :show-input-controls="false" />
                    </div>
                    <div class="SegmentConfig">
                        <span>{{ $t('trials:reading:Segmentations:title:Border') }}</span>
                        <el-slider v-model="SegmentConfig.outlineWidth" show-input :step="1" :max="10" input-size="mini"
                            :show-input-controls="false" />
                    </div>
                    <span class="line" />
                    <div class="SegmentConfig" style="justify-content: flex-start;">
                        <el-switch v-model="SegmentConfig.InactiveSegmentations.show" :active-value="true"
                            :inactive-value="false">
                        </el-switch>
                        <span style="margin-left: 5px;">{{
                            $t('trials:reading:Segmentations:title:InactiveSegmentationsShow')
                        }}</span>
                    </div>
                </div>
                <template v-if="segmentList.length > 0">
                    <div class="SegmentGroupBox">
                        <div style="display: flex;align-items: center;">
                            <el-popover placement="left" width="200px" trigger="click"
                                v-if="readingTaskState < 2 && !isMPR" v-model="popoverVisible" :teleported="true">
                                <div class="SegmentGroupBtnBox">
                                    <div class="SegmentGroupBtn" @click.stop="addSegmentGroup">
                                        {{ $t('trials:reading:Segmentations:button:addSegmentGroup') }}
                                    </div>
                                    <div class="SegmentGroupBtn" @click.stop="rename('segmentGroup')">
                                        {{ $t('trials:reading:Segmentations:button:renameSegmentGroup') }}
                                    </div>
                                    <div class="SegmentGroupBtn" @click.stop="exportSegmentGroup">
                                        {{ $t('trials:reading:Segmentations:button:exportSegmentGroup') }}
                                    </div>
                                    <div class="SegmentGroupBtn" @click.stop="recoverySegmentGroup">
                                        {{ $t('trials:reading:Segmentations:button:recoverySegmentGroup') }}
                                    </div>
                                    <div class="SegmentGroupBtn" @click.stop="delSegmentGroup">
                                        {{ $t('trials:reading:Segmentations:button:deleteSegmentGroup') }}
                                    </div>
                                </div>
                                <i slot="reference" class="el-icon-more" style="cursor: pointer;color:#fff" />
                            </el-popover>
                            <i class="el-icon-more" style="cursor: not-allowed;color: #fff;" v-if="isMPR"></i>
                            <el-select v-model="segmentationId" placeholder="" @change="selectSegmentGroup()"
                                :disabled="saveLoading">
                                <el-option v-for="item in segmentList" :key="`${item.segmentationId}`"
                                    :label="item.name" :value="item.segmentationId">
                                </el-option>
                            </el-select>
                        </div>
                        <div style="display: flex;align-items: center;" v-if="readingTaskState < 2">
                            <i class="el-icon-warning-outline" style="color:red;margin-right: 5px;"
                                :title="$t('trials:reading:Segmentations:tip:segmentationIsNotSave')"
                                v-if="!curSegmentGroup.isSaved"></i>
                            <el-button type="success" size="small"
                                :disabled="saveLoading || isMPR || curSegmentGroup.isSaved"
                                @click="saveSegmentGroup([curSegmentGroup])">
                                {{ $t("trials:reading:Segmentations:button:save") }}
                            </el-button>
                        </div>
                    </div>
                    <div class="addSegmentBox"
                        style="display: flex;align-items: center;justify-content: space-between;">
                        <span v-if="readingTaskState < 2" @click.stop="addSegment"><i class="el-icon-plus"></i>
                            {{ $t('trials:reading:Segmentations:button:addSegment') }}
                        </span>
                        <span style="width: 10px;" v-else></span>
                        <svg-icon :icon-class="!curSegmentGroup.view ? 'eye' : 'eye-open'"
                            @click.stop="viewSegmentGroup(segmentList.find(i => i.segmentationId === segmentationId))" />
                    </div>
                    <div
                        :style="`overflow-y: auto;max-height:${showSegmentConfig ? (SegmentHight - 220) : SegmentHight}px;`">
                        <div :class="['SegmentBox', item && item.segmentIndex === segmentIndex ? 'SegmentBox_active' : '']"
                            v-for="(item, index) in curSegmentGroup.segments"
                            :key="`${item.segmentationId}_${item.segmentIndex}`" @click.stop="selectSegment(item)">
                            <div class="messageBox">
                                <el-popover placement="left" :title="item.SegmentLabel" width="200" trigger="hover">
                                    <div class="Bidirectionalbox">
                                        <!-- <div class="BidirectionalBtn" @click.stop="addTip(item)"
                                            v-if="!item.bidirectional">
                                            {{ $t('trials:reading:Segmentations:button:getBidirectional') }}
                                        </div> -->
                                        <template>
                                            <div class="num">
                                                <span>L: {{
                                                    item.bidirectional && item.bidirectional.maxMajor
                                                        ? `${Number(item.bidirectional.maxMajor).toFixed(2)} mm` : ' '
                                                }}</span>
                                                <span>S: {{
                                                    item.bidirectional && item.bidirectional.maxMinor
                                                        ? `${Number(item.bidirectional.maxMinor).toFixed(2)} mm` : ' '
                                                }}</span>
                                            </div>
                                            <div class="btnBox">
                                                <div
                                                    :title="!item.bidirectionalView ? $t('trials:reading:Segmentations:button:eye') : $t('trials:reading:Segmentations:button:eye-open')">
                                                    <svg-icon :icon-class="!item.bidirectionalView ? 'eye' : 'eye-open'"
                                                        style="color:#000;margin-right: 5px;cursor: pointer;"
                                                        @click.stop="viewBidirectional([item], !item.bidirectionalView)"
                                                        v-if="item.bidirectional" />
                                                </div>
                                                <div :title="$t('trials:reading:Segmentations:button:jumpto')">
                                                    <svg-icon icon-class="jumpto" style="color:#000;cursor: pointer;"
                                                        @click.stop="jumpBidirectional(item)"
                                                        v-if="item.bidirectional" />
                                                </div>

                                                <i class="el-icon-plus" style="color:#000;cursor: pointer;"
                                                    v-if="!item.bidirectional"
                                                    :title="$t('trials:reading:Segmentations:button:getBidirectional')"
                                                    @click.stop="addTip(item)" />
                                            </div>
                                        </template>
                                    </div>
                                    <template v-if="item.stats">
                                        <div v-for="k in statsKey" :key="k" class="statsBox">
                                            <span>{{ k }}</span>
                                            <span v-if="item.stats[k]">{{ JSON.stringify(item.stats[k].value) !== 'null'
                                                ?
                                                k === 'count' ? Number(item.stats[k].value).toFixed(0) :
                                                    Number(item.stats[k].value).toFixed(digitPlaces)
                                                : null
                                            }}<i>{{ item.stats[k].unit }}</i></span>
                                        </div>
                                    </template>
                                    <div class="serialNum" slot="reference">{{ index + 1 }}</div>
                                </el-popover>

                                <el-color-picker v-model="item.color" size="mini"
                                    @change="(e) => changeColor(e, item)"></el-color-picker>
                                <div
                                    style="width: 100%;display: flex;align-items: center;justify-content: space-between;">
                                    <div class="SegmentName">{{ item.SegmentLabel }}</div>
                                    <div v-if="item.stats && item.stats['volume']"
                                        style="text-align: left;width: 100px;">{{
                                            Number(item.stats['volume'].value).toFixed(digitPlaces) }}{{
                                            item.stats['volume'].unit }}</div>
                                </div>

                            </div>
                            <div class="btnBox">
                                <svg-icon :icon-class="item && !item.view ? 'eye' : 'eye-open'"
                                    @click.stop="viewSegment(item, !item.view)" class="docShow" />
                                <i class="el-icon-lock" v-if="item.lock" @click.stop="lockSegment(item, false)"></i>
                                <el-popover placement="bottom" width="40" trigger="click" class="docShow"
                                    :value="popoverId === `popover-${item.segmentationId}_${item.segmentIndex}`"
                                    @show="handleClickPopover(item)" v-if="readingTaskState < 2 && !isMPR">
                                    <div class="SegmentGroupBtnBox">
                                        <div class="SegmentGroupBtn" @click.stop="rename('segment', item)">
                                            {{ $t('trials:reading:Segmentations:button:renameSegmentGroup') }}
                                        </div>
                                        <div class="SegmentGroupBtn" @click.stop="delSegment(item)">
                                            {{ $t('trials:reading:Segmentations:button:deleteSegmentGroup') }}
                                        </div>
                                        <div class="SegmentGroupBtn" v-if="!item.lock"
                                            @click.stop="lockSegment(item, true)">
                                            {{ $t('trials:reading:Segmentations:button:lockSegment') }}
                                        </div>
                                        <div class="SegmentGroupBtn" v-if="item.lock"
                                            @click.stop="lockSegment(item, false)">
                                            {{ $t('trials:reading:Segmentations:button:unlockSegment') }}
                                        </div>
                                    </div>
                                    <i slot="reference" class="el-icon-more" style="cursor: pointer;color:#fff" />
                                </el-popover>
                                <i class="el-icon-more" style="cursor: not-allowed;color: #fff;" v-if="isMPR"></i>
                            </div>
                        </div>
                    </div>
                </template>
            </el-collapse-item>
        </el-collapse>
        <div class="saveBtnBox" v-if="readingTaskState < 2 && segmentList && segmentList.length > 1">
            <el-button type="success" size="small" :disabled="saveLoading || isMPR || curSegmentGroup.isSaved"
                @click="saveSegmentGroup()">
                {{ $t("trials:reading:Segmentations:button:saveAll") }}
            </el-button>
        </div>
        <el-dialog :visible.sync="visible" :close-on-click-modal="false"
            :title="$t('trials:reading:Segmentations:recovery')" width="850px">
            <el-table :data="recoveryList" style="width: 100%;background-color: #1e1e1e;">
                <!-- <el-table-column type="index" width="50" :label="$t('dictionary:template:globalConfig:order')">
                </el-table-column> -->
                <el-table-column property="Version" :label="$t('trials:reading:Segmentations:table:Version')">
                </el-table-column>
                <el-table-column property="FileSize" :label="$t('trials:reading:Segmentations:table:FileSize')">
                    <template slot-scope="scope">
                        {{ fileSizeFormatter(scope.row.FileSize) }}
                    </template>
                </el-table-column>
                <el-table-column property="StartTime" :label="$t('trials:reading:Segmentations:table:StartTime')">
                </el-table-column>
                <el-table-column property="CreateTime" :label="$t('trials:reading:Segmentations:table:CreateTime')">
                </el-table-column>
                <el-table-column :label="$t('common:action:action')" align="left" fixed="right">
                    <template slot-scope="scope">
                        <el-button type="text" @click.stop="restoreSegmentationVersion(scope.row)">{{
                            $t('trials:reading:Segmentations:button:recovery')
                        }}</el-button>
                    </template>
                </el-table-column>
            </el-table>
            <!-- 分页组件 -->
            <pagination style="text-align: right;margin-top: 5px;" class="page" :total="total"
                :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
                @pagination="getSegmentationVersionList(segmentationId)" />
        </el-dialog>
    </div>
</template>
<script>
import { changeSegmentationSavedStatus, getSegmentationList, addOrUpdateSegmentation, deleteSegmentation, getSegmentList, addOrUpdateSegment, deleteSegment, getSegmentBindingList, saveSegmentBindingAndAnswer, getReadingTableQuestionTrialById, getReadingQuestionTrialById, lockOrUnLockSegment, restoreSegmentationVersion, getSegmentationVersionList } from '@/api/reading'
import * as cornerstoneTools from '@cornerstonejs/tools';
import * as cornerstone from "@cornerstonejs/core";
import dcmjs from '@/utils/dcmUpload/dcmjs'
import * as cornerstoneAdapters from "@cornerstonejs/adapters";
import cornerstoneDICOMImageLoader from '@cornerstonejs/dicom-image-loader'
import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent'
import { getCustomizeStandardsSegmentDicomTools } from './toolConfig'
import * as polySeg from '@cornerstonejs/polymorphic-segmentation'
import Pagination from '@/components/Pagination'
cornerstoneTools.init({ addons: { polySeg } })
const {
    ToolGroupManager,
    Enums: csToolsEnums,
    segmentation,
    annotation,
    LabelMapEditWithContourTool,
    SegmentBidirectionalTool,
    CrosshairsTool,
    BrushTool,
    utilities: CStUtils,
} = cornerstoneTools;

const { MouseBindings, Events: toolsEvents } = csToolsEnums
const { segmentation: segmentationUtils } = CStUtils;
const { cache, getRenderingEngine, imageLoader, eventTarget, metaData, utilities: csUtils, volumeLoader } = cornerstone;
// const { downloadDICOMData } = cornerstoneAdapters.helpers;
const { Cornerstone3D } = cornerstoneAdapters.adaptersSEG;

const searchDataDefault = () => {
    return {
        SegmentationId: null,
        PageIndex: 1,
        PageSize: 20,
        Asc: false,
        SortField: '',
    }
}
export default {
    name: "Segmentations",
    components: {
        Pagination,
    },
    props: {
        isMPR: {
            type: Boolean,
            default: false
        },
        volumeToolGroupId: {
            type: String,
            default: ''
        },
        viewportKey: {
            type: String,
            default: 'viewport'
        },
        activeViewportIndex: {
            type: Number,
            default: 0
        },
        activeTool: {
            type: String,
            default: ''
        },
        visitInfo: {
            type: Object,
            default: () => {
                return {}
            }
        },
        SegmentConfig: {
            type: Object,
            default: () => {
                return {}
            }
        },
        actionConfiguration: {
            type: Object,
            default: () => {
                return {}
            }
        },
        curSegSeries: {
            type: Object,
            default: () => {
                return {}
            }
        },
        trialCriterion: {
            type: Object,
            default: () => {
                return {}
            }
        },
        segId: {
            type: String,
            default: ''
        },
        segIndex: {
            type: Number,
            default: 0
        },
        renderingEngineId: {
            type: String,
            required: true
        },
        loadingText: {
            type: String,
            default: ''
        },
        globalLoading: {
            type: Boolean,
            default: false
        },
        histogramVisible: {
            type: Boolean,
            default: false
        }
    },
    data() {
        return {
            sliderMax: 50,
            sliderStep: 1,
            sliderSection: [{
                id: `sliderSection1`,
                max: 5,
                step: 0.1,
                label: '0~5mm'
            }, {
                id: `sliderSection2`,
                max: 10,
                step: 0.1,
                label: '0~10mm'
            }, {
                id: `sliderSection3`,
                max: 50,
                step: 1,
                label: '0~50mm'
            }, {
                id: `sliderSection4`,
                max: 100,
                step: 1,
                label: '0~100mm'
            }],
            visible: false,
            recoveryList: [],
            searchData: searchDataDefault(),
            total: 0,
            loading: false,
            series: {},
            activeNames: ['tools', 'Segment'],
            brushSize: 10,
            brushThreshold: {
                dynamicRadius: 0,
                isDynamic: false,
                range: [200, 1000]
            },
            tools: ['LabelMapEditWithContour', 'CircularBrush', 'CircularEraser'],
            ThresholdTools: ['ThresholdCircle', 'ThresholdSphere'],
            thresholdType: null,
            showSegmentConfig: false,
            segmentList: [],
            segmentationId: "",
            segmentIndex: null,
            SegmentHight: 100,
            colors: [
                '#0ca8df',
                '#ffd10a',
                '#b6d634',
                '#3fbe95',
                '#785db0',
                '#5070dd',
                '#505372',
                '#ff994d',
                '#fb628b',
            ],
            viewportIds: [], // 
            statsKey: [],
            drawing: false, // 是否正在分割
            // isDel: false,
            digitPlaces: 2,
            isloaded: false,
            popoverId: null,
            saveLoading: false,
            popoverVisible: false,
            timer: null
        }
    },
    mounted() {
        this.SegmentHight = window.innerHeight > 900 ? window.innerHeight * 0.45 : window.innerHeight * 0.35;
        this.statsKey = getCustomizeStandardsSegmentDicomTools('Labelmap')[0].props.filter(item => item !== 'width' && item !== 'length')
        // console.log(segmentation, 'segmentation')
        // console.log(annotation, 'annotation')
        // console.log(cache, 'cache')
        eventTarget.addEventListener(
            'CORNERSTONE_TOOLS_SEGMENTATION_DATA_MODIFIED',
            this.segmentationModifiedCallback
        );
        DicomEvent.$on('activeSeries', (series) => {
            let { TaskInfo = {}, Id } = series
            if (this.isMPR) return false
            if (Id === this.series.Id && TaskInfo.VisitTaskId === this.visitInfo.VisitTaskId) return false
            this.series = series
            this.$emit("update:curSegSeries", Object.assign({}, series))
            this.popoverId = null
            this.segmentIndex = null
            this.segmentationId = null
            if (this.timer) {
                clearInterval(this.timer)
                this.timer = null
            }
            this.getSegmentationList()
        })
        DicomEvent.$on('isloaded', (data) => {
            let { segment, isChange = true, viewportId, series } = data
            DicomEvent.$emit('renderSegmentation', viewportId)
        })
        DicomEvent.$on('SegmentationLoading', (viewportId) => {
            if (viewportId !== `${this.viewportKey}-${this.activeViewportIndex}`) return false
            this.loading = false
        })
        DicomEvent.$on('changeMPR', () => {
            if (this.loading) return false
            // if (viewportId !== `${this.viewportKey}-${this.activeViewportIndex}`) return false
            if (this.segmentList && this.segmentList.length > 0) {
                this.segmentationId = this.segmentList[0].segmentationId
                this.segmentIndex = this.segmentList[0] ? this.segmentList[0].segments[0].segmentIndex : null
            }

        })
        const digitPlaces = Number(localStorage.getItem('digitPlaces'))
        this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
        this.getSegmentConfig()
        // document.addEventListener("click", () => {
        //     this.popoverId = null
        // });
    },
    computed: {
        curSegmentGroup() {
            let s = this.segmentList.find(item => item.segmentationId === this.segmentationId)
            return s ? s : {}
        },
        curSegment() {
            let s = {}
            if (this.curSegmentGroup.segments && this.curSegmentGroup.segments.length) {
                s = this.curSegmentGroup.segments.find(item => item.segmentIndex === this.segmentIndex)
            }
            return s
        },
        readingTaskState() {
            return this.series.TaskInfo ? this.series.TaskInfo.ReadingTaskState : 0
        }
    },
    watch: {
        SegmentConfig: {
            handler() {
                // this.readingSegmentByConfig()
                this.setSegmentConfig()
            },
            deep: true
        },
        brushSize: {
            handler() {
                this.setBrushSize(this.activeTool)
                this.setSegmentConfig()
            },
            deep: true
        },
        brushThreshold: {
            handler() {
                this.setBrushThreshold()
            },
            deep: true
        },
        segmentIndex() {
            this.$emit('update:segIndex', this.segmentIndex)
        },
        segmentationId() {
            this.$emit('update:segId', this.segmentationId)
        }
    },
    methods: {
        getSegmentConfig() {
            if (!localStorage.getItem('SegmentConfig')) return false
            let obj = JSON.parse(localStorage.getItem('SegmentConfig'))
            this.sliderStep = obj.sliderStep
            this.sliderMax = obj.sliderMax
        },
        setSegmentConfig() {
            let obj = {
                sliderStep: this.sliderStep,
                sliderMax: this.sliderMax,
                renderOutline: this.SegmentConfig.renderOutline,
                renderFill: this.SegmentConfig.renderFill,
                fillAlpha: this.SegmentConfig.fillAlpha,
                outlineWidth: this.SegmentConfig.outlineWidth,
            }
            localStorage.setItem('SegmentConfig', JSON.stringify(obj))
        },
        handleSliderChange(value) {
            // console.log(value, 'value')
            let data = this.sliderSection.find(item => item.max === value)
            if (data) {
                this.sliderStep = data.step
            }
            if (this.brushSize >= data.max) {
                this.brushSize = data.max
            }
            this.setSegmentConfig()
        },
        fileSizeFormatter(size) {
            if (!size) return
            return (size / Math.pow(1024, 2)).toFixed(3) + 'MB'
        },
        showSurface(item) {
            this.$emit("showSurface", {
                segmentationId: item.segmentationId,
                segmentIndex: item.segmentIndex,
                volumeId: this.series.SeriesInstanceUid,
                segmentations: this.curSegmentGroup
            })
        },
        handleClickPopover(item) {
            this.popoverId = `popover-${item.segmentationId}_${item.segmentIndex}`
        },
        initThreshold(key = null) {
            if (this.isMPR) return false
            if (key === 'SphericalBrush') {
                this.setToolActive(this.ThresholdTools[1], 'SphericalBrush')
                this.setSphericalBrushConfig()
                return false
            }
            if (!this.ThresholdTools.includes(this.activeTool)) {
                this.setToolActive(this.ThresholdTools[0])
                this.thresholdType = this.ThresholdTools[0]
            }
        },
        createSegmentConfiguration(segmentIndex, segmentationId, otherSegments) {
            const containedSegmentIndices = otherSegments
                ? { has: (segmentIndex) => otherSegments.indexOf(segmentIndex) !== -1 }
                : undefined;
            const colorConfig = segmentation.config.color.getSegmentIndexColor(
                `${this.viewportKey}-${this.activeViewportIndex}`,
                segmentationId,
                segmentIndex
            );
            // Allow null style to skip style set
            let color, activeColor;
            if (colorConfig?.length) {
                color = `rgb(${colorConfig.join(',')})`;
                activeColor = color;
            }
            const style = {
                color,
                colorHighlightedActive: activeColor,
                colorActive: activeColor,
                textBoxColor: color,
                textBoxColorActive: activeColor,
                textBoxColorHighlightedActive: activeColor,
            };
            const label = otherSegments
                ? `Combined ${segmentIndex} with ${otherSegments.join(', ')}`
                : `Segment ${segmentIndex}`;

            this.actionConfiguration.contourBidirectional.data.segmentData.set(segmentIndex, {
                containedSegmentIndices,
                label,
                style,
            });
            this.actionConfiguration.contourBidirectional.data.segmentationId = segmentationId
            this.actionConfiguration.contourBidirectional.data.segmentIndex = segmentIndex
        },
        async addTip(item) {
            let segmentGroup = this.segmentList.filter(i => item.segmentationId === i.segmentationId)
            await this.saveSegmentGroup(segmentGroup, false)
            this.calculateStatistics([item.segmentIndex], item.segmentationId, 'individual');
            this.getBidirectional([item])

        },
        getBidirectional(list, DATA = null, isCompute = true) {
            list.forEach(item => {
                this.createSegmentConfiguration(item.segmentIndex, item.segmentationId);
            })

            const renderingEngine = getRenderingEngine(this.renderingEngineId)
            const viewportId = `${this.viewportKey}-${this.activeViewportIndex}`
            const viewport = renderingEngine.getViewport(viewportId);
            if (isCompute) {
                [viewport.element].forEach(async (element) => {
                    const bidirectionalData =
                        await CStUtils.segmentation.getSegmentLargestBidirectional({
                            segmentationId: list[0].segmentationId,
                            segmentIndices: list.map(item => item.segmentIndex),
                        });
                    if (bidirectionalData.length <= 0) {
                        list.forEach(item => {
                            let annotations = annotation.state.getAllAnnotations().filter(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === item.segmentIndex);
                            annotations.forEach(i => {
                                annotation.state.removeAnnotation(i.annotationUID)
                            })
                            item.bidirectional = null
                        })

                        this.resetViewport(false)

                        if (DATA) {
                            this.segmentationId = DATA.SegmentationId;
                            this.segmentIndex = DATA.SegmentNumber;
                            setTimeout(() => {
                                this.selectSegment(DATA)
                            })
                        }
                    }
                    bidirectionalData.forEach((bidirectional) => {
                        const { segmentIndex } = bidirectional;
                        const { majorAxis, minorAxis, maxMajor, maxMinor } = bidirectional;
                        let item = list.find(i => i.segmentIndex === segmentIndex)
                        SegmentBidirectionalTool.hydrate(viewportId, [majorAxis, minorAxis], {
                            segmentIndex,
                            segmentationId: item.segmentationId,
                        })
                        let an = annotation.state.getAllAnnotations().find(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === bidirectional.segmentIndex && i.metadata.toolName === "SegmentBidirectional");
                        if (an) {
                            annotation.locking.setAnnotationLocked(an.annotationUID, true)
                            annotation.visibility.setAnnotationVisibility(an.annotationUID, item.bidirectionalView)
                        }
                        item.bidirectional = bidirectional
                        if (DATA) {
                            this.segmentationId = DATA.SegmentationId;
                            this.segmentIndex = DATA.SegmentNumber;
                            setTimeout(() => {
                                this.selectSegment(DATA)
                            })
                        }
                        // render the bidirectional tool data
                    });

                });
            } else {
                list.forEach(item => {
                    if (item.bidirectional) {
                        let { majorAxis, minorAxis } = item.bidirectional
                        SegmentBidirectionalTool.hydrate(viewportId, [majorAxis, minorAxis], {
                            segmentIndex: item.segmentIndex,
                            segmentationId: item.segmentationId,
                        })
                    }
                })
            }

        },
        setToolActive(toolName, name = null) {
            if (this.segmentList.length <= 0) return false
            if (this.curSegment.lock) return false
            if (this.isMPR) return false
            if (this.histogramVisible && !this.ThresholdTools.includes(toolName)) return false
            if (['viewport-MPR-1', 'viewport-MPR-2'].includes(`${this.viewportKey}-${this.activeViewportIndex}`)) return false
            const toolGroupId = this.isMPR ? this.volumeToolGroupId : `${this.viewportKey}-${this.activeViewportIndex}`
            const toolGroup = ToolGroupManager.getToolGroup(toolGroupId)
            if (this.activeTool === toolName) {
                if (toolName === CrosshairsTool.toolName) {
                    toolGroup.setToolDisabled(this.activeTool)
                } else {
                    toolGroup.setToolPassive(this.activeTool)
                }
                this.$emit('update:activeTool', '')
            } else if (this.activeTool === name) {
                toolGroup.setToolPassive(this.ThresholdTools[1])
                this.$emit('update:activeTool', '')
            } else {
                if (this.activeTool) {
                    if (toolName === CrosshairsTool.toolName) {
                        toolGroup.setToolDisabled(this.activeTool)
                    } else {
                        toolGroup.setToolPassive(this.activeTool)
                        toolGroup.setToolPassive(this.ThresholdTools[1])
                    }
                }
                toolGroup.setToolActive(toolName, {
                    bindings: [{ mouseButton: MouseBindings.Primary }]
                })
                // if (toolName === 'CircularEraser') {
                //     console.log(toolGroup.getToolInstance(toolName))
                // }
                if (name) {
                    this.$emit('update:activeTool', name)
                    this.setBrushSize(name)
                } else {
                    this.$emit('update:activeTool', toolName)
                    this.setBrushSize(toolName)
                    if (this.ThresholdTools.includes(toolName)) {
                        this.setBrushThreshold()
                    }
                }

            }
        },
        changeShowSegmentConfig() {
            if (this.segmentList.length > 0) {
                this.showSegmentConfig = !this.showSegmentConfig
            }
        },
        viewBidirectional(arr, view) {
            for (let j = 0; j < arr.length; j++) {
                let item = arr[j]
                item.bidirectionalView = view
            }
            DicomEvent.$emit('viewBidirectional', arr)
        },
        async jumpBidirectional(item) {
            DicomEvent.$emit('jumpBidirectional', item)
        },
        viewSegmentGroup(item) {
            item.view = !item.view
            item.segments.forEach(i => {
                i.view = item.view
                i.bidirectionalView = item.view
            })
            DicomEvent.$emit('viewSegmentation', item)
            // this.viewBidirectional(item.segments, view)
        },
        viewSegment(item, view) {
            item.bidirectionalView = view
            item.view = view
            this.$emit('setToolsPassive')
            DicomEvent.$emit('viewSegment', item)
        },
        lockSegment(item, lock) {
            if (this.readingTaskState >= 2) return false
            if (this.isMPR) return false
            this.$emit('setToolsPassive')
            segmentation.segmentLocking.setSegmentIndexLocked(item.segmentationId, item.segmentIndex, lock)
            item.lock = lock
            if (!lock) this.changeSegmentationSavedStatus(item.segmentationId, lock)
            this.lockOrUnLockSegment(item.id, lock)
        },
        selectSegment(item, isChange = true) {
            if (isChange) {
                this.segmentationId = item.segmentationId;
                this.segmentIndex = item.segmentIndex;
            }
            // segmentation.segmentIndex.setActiveSegmentIndex(item.segmentationId, item.segmentIndex);
            if (isChange) { this.jumpBidirectional(item) }

            if (item.lock) {
                this.$emit('setToolsPassive')
            }
            // this.resetViewport()
        },
        async restoreSegmentationVersion(row) {
            try {
                this.popoverId = null
                let message = this.$t('trials:reading:Segmentations:confirm:CurrentDataIsLoss').replace("xxx", row.Version)
                let confirm = await this.$confirm(message)
                if (!confirm) return false
                let data = {
                    SegmentationId: this.segmentationId,
                    VersionId: row.Id
                }
                let res = await restoreSegmentationVersion(data)
                if (res.IsSuccess) {
                    let annotations = annotation.state.getAllAnnotations().filter(item => item.metadata.segmentationId && this.segmentationId === item.metadata.segmentationId && item.metadata.toolName === "SegmentBidirectional");
                    annotations.forEach(item => {
                        annotation.state.removeAnnotation(item.annotationUID)
                    })
                    // 只需要将分割数据清空，分割所需的蒙版volume可以复用不需要清除
                    // 1.清除分割所需的蒙版volume(弃用)
                    // let volume = cache.getVolume(this.segmentationId)
                    // // 1. 销毁 Volume 实例
                    // volume.destroy();
                    // // 2. 从缓存中移除
                    // volume.removeFromCache();
                    // 2.清除分割数据及文件缓存
                    segmentation.removeSegmentation(this.segmentationId)
                    let imageId = null
                    if (this.curSegmentGroup.oldSegUrl) {
                        imageId = `wadouri:${this.OSSclientConfig.basePath}${this.curSegmentGroup.oldSegUrl}`
                        this.curSegmentGroup.oldSegUrl = null
                    } else {
                        imageId = `wadouri:${this.OSSclientConfig.basePath}${this.curSegmentGroup.segUrl}`

                    }
                    if (imageId && cache.getImage(imageId)) {
                        cache.removeImageLoadObject(imageId)
                    }

                    let r = await this.getSegmentation(this.segmentationId)
                    if (!r) return false
                    this.visible = false
                    this.$message.success(this.$t("trials:reading:Segmentations:message:restoreSuccess"))
                    this.resetViewport()
                    this.$nextTick(() => {
                        DicomEvent.$emit('renderSegmentationBychangeSegmention')
                    })
                }
                return false
            } catch (err) {
                console.log(err)
                return false
            }
        },
        async getSegmentationVersionList(segmentationId) {
            try {
                this.searchData.SegmentationId = segmentationId || this.segmentationId
                let res = await getSegmentationVersionList(this.searchData)
                if (res.IsSuccess) {
                    this.recoveryList = res.Result.CurrentPageData
                    // this.visible = true
                    this.total = res.Result.TotalCount
                    return true
                }
                return false
            } catch (err) {
                console.log(err)
                return false
            }
        },
        async recoverySegmentGroup() {
            try {
                this.popoverId = null
                let res = await this.getSegmentationVersionList(this.segmentationId)
                if (!res) return this.$message.warning(this.$t("trials:reading:Segmentations:message:getSegmentationVersionFail"))
                this.visible = true
            } catch (err) {
                console.log(err)
            }
        },
        selectSegmentGroup(s) {
            this.$emit('setToolsPassive')
            this.segmentIndex = null;
            let segment = s ? s : this.segmentList.find(item => item.segmentationId === this.segmentationId).segments[0]
            this.$nextTick(() => {
                this.selectSegment(segment)
            })
        },
        getSegmentationName(num = 1) {
            let defaultSegmentationName = this.trialCriterion.DefaultSegmentName.SegmentationName
            let name = defaultSegmentationName
            let has = this.segmentList.find(item => item.name === name)
            if (has) {
                name = defaultSegmentationName + num
                has = this.segmentList.find(item => item.name === name)
                num++
                if (has) name = this.getSegmentationName(num)
            }
            return name
        },
        getSegmentName(arr, num = 1) {
            let defaultSegmentName = this.trialCriterion && this.trialCriterion.DefaultSegmentName && this.trialCriterion.DefaultSegmentName.SegmentNameList && this.trialCriterion.DefaultSegmentName.SegmentNameList.length > 0 ? this.trialCriterion.DefaultSegmentName.SegmentNameList[0] : arr[0].SegmentLabel
            let name = defaultSegmentName + num
            let has = arr.find(item => item.SegmentLabel === name)
            num++
            if (has) name = this.getSegmentName(arr, num)
            return name
        },
        async addSegmentGroup() {
            // let segmentationId = this.$guid();
            this.popoverVisible = false
            let obj = {
                name: this.getSegmentationName(),
                view: true,
                segmentationId: null,
                isSaved: false,
                segments: []
            }
            this.segmentIndex = null
            let segmentationId = await this.addOrUpdateSegmentation({ name: obj.name })
            obj.segmentationId = segmentationId
            await this.createSegmentation(obj.segmentationId)
            this.createSegmentationRepresentation(obj.segmentationId)
            this.trialCriterion.DefaultSegmentName.SegmentNameList.forEach(async (SegmentName, index) => {
                let o = {
                    segmentIndex: index + 1,
                    segmentationId,
                    SegmentLabel: SegmentName,
                    color: this.colors[index],
                    stats: null,
                    bidirectional: null,
                    bidirectionalView: true,
                    view: true,
                    lock: false
                }
                let id = await this.addOrUpdateSegment({ name: o.SegmentLabel, color: o.color, segmentIndex: o.segmentIndex, segmentationId: o.segmentationId })
                o.id = id
                obj.segments.splice(index, 0, o);
                segmentation.segmentIndex.setActiveSegmentIndex(obj.segmentationId, index + 1);
                this.changeColor(this.colors[index], { segmentationId: obj.segmentationId, segmentIndex: index + 1, color: this.colors[index] })
                if (index === this.trialCriterion.DefaultSegmentName.SegmentNameList.length - 1) {
                    segmentation.segmentIndex.setActiveSegmentIndex(obj.segmentationId, 1);
                }
            })
            this.segmentList.push(obj);
            this.segmentationId = obj.segmentationId;
            this.segmentIndex = 1

        },
        async addSegment() {
            if (this.saveLoading) return false
            if (this.isMPR) return false
            if (this.segmentList.length <= 0) {
                let obj = {
                    name: this.getSegmentationName(),
                    view: true,
                    isSaved: false,
                    segments: []
                }
                this.segmentIndex = null
                let segmentationId = await this.addOrUpdateSegmentation({ name: obj.name })
                obj.segmentationId = segmentationId
                await this.createSegmentation(segmentationId)
                this.createSegmentationRepresentation(segmentationId)
                this.trialCriterion.DefaultSegmentName.SegmentNameList.forEach(async (SegmentName, index) => {
                    let o = {
                        segmentIndex: index + 1,
                        segmentationId,
                        SegmentLabel: SegmentName,
                        color: this.colors[index],
                        stats: null,
                        bidirectional: null,
                        bidirectionalView: true,
                        view: true,
                        lock: false
                    }
                    let id = await this.addOrUpdateSegment({ name: o.SegmentLabel, color: o.color, segmentIndex: o.segmentIndex, segmentationId: o.segmentationId })
                    o.id = id
                    obj.segments.splice(index, 0, o);
                    segmentation.segmentIndex.setActiveSegmentIndex(obj.segmentationId, index + 1);
                    this.changeColor(this.colors[index], { segmentationId: obj.segmentationId, segmentIndex: index + 1, color: this.colors[index] })
                    if (index === this.trialCriterion.DefaultSegmentName.SegmentNameList.length - 1) {
                        segmentation.segmentIndex.setActiveSegmentIndex(obj.segmentationId, 1);
                    }
                })
                this.segmentList.push(obj);
                this.segmentationId = segmentationId;
                this.segmentIndex = 1
                // segmentation.segmentIndex.setActiveSegmentIndex(this.segmentList[0].segmentationId, 1);
                // this.changeColor(this.colors[0], { segmentationId: this.segmentList[0].segmentationId, segmentIndex: 1, color: this.colors[0] })
                // viewportIds.forEach(id => {
                //     segmentation.config.color.setSegmentIndexColor(id, this.segmentList[0].segmentationId, 1, this.hex2Rgb(this.colors[0]))
                // })
                // this.readingSegmentByConfig()

            } else {
                this.changeSegmentationSavedStatus(this.segmentationId, false)
                let item = this.segmentList.find(i => i.segmentationId === this.segmentationId)
                let arr = item.segments.sort((a, b) => a.segmentIndex - b.segmentIndex)
                let segmentIndex = arr[item.segments.length - 1].segmentIndex + 1
                let obj = {
                    segmentIndex: segmentIndex,
                    segmentationId: this.segmentationId,
                    SegmentLabel: this.getSegmentName(item.segments),
                    color: segmentIndex >= this.colors.length ? this.colors[0] : this.colors[segmentIndex],
                    stats: null,
                    bidirectional: null,
                    bidirectionalView: true,
                    view: true,
                    lock: false
                }
                if (segmentIndex >= this.colors.length) {
                    let index = segmentIndex % this.colors.length
                    let color = this.randomNearColor(this.colors[index], 4)
                    obj.color = color
                }
                let id = await this.addOrUpdateSegment({ name: obj.SegmentLabel, color: obj.color, segmentIndex: obj.segmentIndex, segmentationId: obj.segmentationId })
                obj.id = id
                item.segments.push(obj)
                this.segmentIndex = obj.segmentIndex
                // segmentation.segmentIndex.setActiveSegmentIndex(obj.segmentationId, obj.segmentIndex);
                this.changeColor(obj.color, { segmentationId: obj.segmentationId, segmentIndex: obj.segmentIndex, color: obj.color })
                // viewportIds.forEach(id => {
                //     segmentation.config.color.setSegmentIndexColor(id, obj.segmentationId, obj.segmentIndex, this.hex2Rgb(obj.color))
                // })

            }


        },
        changeColor(e, item) {
            DicomEvent.$emit('changeColor', item)
        },
        // 清空所有分割
        delAllSegment(isChange) {
            segmentation.removeAllSegmentations()
            segmentation.state.removeAllSegmentations()
            let annotations = annotation.state.getAllAnnotations().filter(item => item.metadata.segmentationId && item.metadata.segmentIndex && item.metadata.toolName === "SegmentBidirectional");
            annotations.forEach(item => {
                annotation.state.removeAnnotation(item.annotationUID)
            })
            if (isChange) {
                this.segmentationId = ''
                this.segmentIndex = null
            }
            this.segmentList = []
            this.resetViewport()
        },
        // 删除分割分组
        async delSegmentGroup() {
            this.popoverId = null
            let confirm = await this.$confirm(this.$t('trials:reading:Segmentations:confirm:delSegmentions'))
            if (!confirm) return false
            let res = await this.deleteSegmentation(this.segmentationId)
            if (!res) return false
            segmentation.removeSegmentation(this.segmentationId)
            segmentation.state.removeSegmentation(this.segmentationId)
            let volume = cache.getVolume(this.segmentationId)
            // 1. 销毁 Volume 实例
            volume.destroy();
            // 2. 从缓存中移除
            volume.removeFromCache();
            let groupIndex = this.segmentList.findIndex(item => item.segmentationId === this.segmentationId)
            this.segmentList.splice(groupIndex, 1)
            let annotations = annotation.state.getAllAnnotations().filter(item => item.metadata.segmentationId === this.segmentationId);
            annotations.forEach(item => {
                annotation.state.removeAnnotation(item.annotationUID)
            })
            let f = this.segmentList.some(item => item.segUrl)
            DicomEvent.$emit("IsBeSegment", { StudyId: this.series.StudyId, Id: this.series.Id, IsBeSegment: f })
            if (this.segmentList.length > 0) {
                this.segmentationId = this.segmentList[0].segmentationId;
                this.selectSegmentGroup()
            } else {
                this.segmentationId = null
            }
            this.resetViewport()
            this.$emit('resetQuestion')
        },
        // 删除分割片段
        async delSegment(data) {
            this.popoverId = null;
            let segmentIndex = data.segmentIndex
            let confirm = await this.$confirm(this.$t('trials:reading:Segmentations:confirm:delSegment'))
            if (!confirm) return false
            let groupIndex = this.segmentList.findIndex(item => item.segmentationId === this.segmentationId)
            if (this.segmentList[groupIndex].segments.length <= 1) return this.$confirm(this.$t('trials:reading:Segmentations:confirm:hasOneSegment'))
            let s = this.segmentList[groupIndex].segments.find(item => item.segmentIndex === segmentIndex)
            let res = await this.deleteSegment(s.id)
            if (!res) return false
            segmentation.removeSegment(this.segmentationId, Number(segmentIndex), { setNextSegmentAsActive: false, recordHistory: false })
            segmentation.helpers.clearSegmentValue(this.segmentationId, Number(segmentIndex), { recordHistory: false })
            let index = this.segmentList[groupIndex].segments.findIndex(item => item.segmentIndex === segmentIndex)
            this.segmentList[groupIndex].segments.splice(index, 1)
            let annotations = annotation.state.getAllAnnotations().filter(item => item.metadata.segmentationId === this.segmentationId && item.metadata.segmentIndex === segmentIndex);
            annotations.forEach(item => {
                annotation.state.removeAnnotation(item.annotationUID)
            })
            this.resetViewport()
            if (this.segmentList[groupIndex].segments.length > 0) {
                this.selectSegment(this.segmentList[groupIndex].segments[0])
            }
            this.$emit('resetQuestion')
            this.saveSegmentGroup([this.segmentList[groupIndex]], true)

        },
        resetViewport(passive = true) {
            DicomEvent.$emit('resetViewport')
            if (passive) this.$emit('setToolsPassive')
        },
        async rename(key, item) {
            let value = null
            if (key === 'segmentGroup') {
                let group = this.segmentList.find(i => i.segmentationId === this.segmentationId)
                value = group.name
            } else {
                value = item.SegmentLabel
            }
            let name = await this.customPrompt(value)
            if (!name) return false
            if (key === 'segmentGroup') {
                let group = this.segmentList.find(i => i.segmentationId === this.segmentationId)
                group.name = name
                this.addOrUpdateSegmentation({ name, id: group.segmentationId, url: group.segUrl, size: group.size })
            } else {
                item.SegmentLabel = name
                this.addOrUpdateSegment({ name: item.SegmentLabel, color: item.color, segmentIndex: item.segmentIndex, segmentationId: item.segmentationId, segmentJson: JSON.stringify({ stats: item.stats, bidirectional: item.bidirectional }), id: item.id })
            }
        },
        async customPrompt(name) {
            try {
                const that = this
                // 请输入标记名称
                let message = this.$t('trials:reading:Segmentations:message:rename')
                const { value } = await this.$prompt(message, '', {
                    showClose: false,
                    cancelButtonText: this.$t('common:button:cancel'),
                    confirmButtonText: this.$t('common:button:save'),
                    showCancelButton: true,
                    closeOnClickModal: false,
                    closeOnPressEscape: false,
                    inputValue: name,
                    beforeClose: (action, instance, done) => {
                        if (action === 'confirm') {
                            // const value = instance.inputValue
                            done()
                        } else {
                            done()
                        }
                    }
                })
                return value
            } catch (err) {
                console.log(err)
                return null
            }
        },
        // 切换非当前分组分割标记显示
        changeInactiveSegmentShow() {
            let segmentList = this.segmentList.filter(item => item.segmentationId !== this.segmentationId)
            this.viewportIds.forEach(id => {
                segmentation.config.visibility.setSegmentationRepresentationVisibility(
                    id,
                    {
                        segmentationId: this.segmentationId,
                        type: csToolsEnums.SegmentationRepresentations.Labelmap,
                    },
                    true
                );
                segmentList.forEach(segment => {
                    segmentation.config.visibility.setSegmentationRepresentationVisibility(
                        id,
                        {
                            segmentationId: segment.segmentationId,
                            type: csToolsEnums.SegmentationRepresentations.Labelmap,
                        },
                        this.SegmentConfig.InactiveSegmentations.show
                    );

                })

            })
            segmentList.forEach(segment => {
                this.viewBidirectional(segment.segments, this.SegmentConfig.InactiveSegmentations.show)
            })
            let segmentGroup = this.segmentList.find(item => item.segmentationId === this.segmentationId)
            if (segmentGroup) {
                let segments = segmentGroup.segments
                this.viewBidirectional(segments, true)
            }
        },
        // 更改分割标记显示模式
        changeSegmentConfig(renderOutline, renderFill) {
            this.SegmentConfig.renderOutline = renderOutline;
            this.SegmentConfig.renderFill = renderFill;
        },
        // 导出SEG
        exportSegmentGroup() {
            this.popoverVisible = false
            let group = this.segmentList.find(item => item.segmentationId === this.segmentationId)
            this.exportSegmentation(this.segmentationId, group, true)
        },
        exportSegmentation(segmentationId, group, isFile = false) {
            try {
                const segmentationIds = segmentation.state
                    .getSegmentations()
                    .map(x => x.segmentationId);
                if (!segmentationIds.length) {
                    return;
                }
                const segmentGroup =
                    segmentation.state.getSegmentation(segmentationId);

                let { imageIds } = segmentGroup.representationData.Labelmap;

                let segImages = imageIds.map(imageId => cache.getImage(imageId));
                segImages = segImages.reverse()
                let referencedImages = segImages.map(image =>
                    cache.getImage(image.referencedImageId)
                );
                const labelmaps2D = [];

                let z = 0;

                for (const segImage of segImages) {
                    const segmentsOnLabelmap = new Set();
                    const pixelData = segImage.getPixelData();
                    const { rows, columns } = segImage;

                    for (let i = 0; i < pixelData.length; i++) {
                        const segment = pixelData[i];
                        if (segment !== 0) {
                            segmentsOnLabelmap.add(segment);
                        }
                    }

                    labelmaps2D[z++] = {
                        segmentsOnLabelmap: Array.from(segmentsOnLabelmap),
                        pixelData,
                        rows,
                        columns
                    };
                }

                const allSegmentsOnLabelmap = labelmaps2D.map(
                    labelmap => labelmap.segmentsOnLabelmap
                );

                const labelmap3D = {
                    segmentsOnLabelmap: Array.from(new Set(allSegmentsOnLabelmap.flat())),
                    metadata: [],
                    labelmaps2D
                };
                let segmentIndexs = []
                labelmap3D.segmentsOnLabelmap.forEach(segmentIndex => {
                    const color = segmentation.config.color.getSegmentIndexColor(
                        `${this.viewportKey}-${this.activeViewportIndex}`,
                        segmentationId,
                        segmentIndex
                    );
                    const RecommendedDisplayCIELabValue = dcmjs.data.Colors.rgb2DICOMLAB(
                        color.slice(0, 3).map(value => value / 255)
                    ).map(value => Math.round(value));
                    let segment = group.segments.find(item => item.segmentIndex === segmentIndex)
                    if (segment) {
                        segmentIndexs.push(segmentIndex)
                        let SegmentLabel = segment.SegmentLabel
                        const segmentMetadata = {
                            SegmentNumber: segmentIndex.toString(),
                            SegmentLabel: SegmentLabel,
                            SegmentAlgorithmType: "MANUAL",
                            SegmentAlgorithmName: "OHIF Brush",
                            RecommendedDisplayCIELabValue,
                            SegmentedPropertyCategoryCodeSequence: {
                                CodeValue: "T-D0050",
                                CodingSchemeDesignator: "SRT",
                                CodeMeaning: "Tissue"
                            },
                            SegmentedPropertyTypeCodeSequence: {
                                CodeValue: "T-D0050",
                                CodingSchemeDesignator: "SRT",
                                CodeMeaning: "Tissue"
                            }
                        };

                        if (segment.stats) labelmap3D.metadata[segmentIndex] = segmentMetadata;
                    }
                });
                if (labelmap3D.metadata.length <= 0) {
                    return false
                }
                const generatedSegmentation =
                    Cornerstone3D.Segmentation.generateSegmentation(
                        referencedImages,
                        labelmap3D,
                        metaData
                    );
                segmentIndexs.forEach((item, index) => {
                    if (generatedSegmentation.dataset.SegmentSequence[index]) {
                        generatedSegmentation.dataset.SegmentSequence[index].SegmentNumber = item.toString()
                    }

                })
                generatedSegmentation.dataset.SegmentSequence.sort((a, b) => a.SegmentNumber - b.SegmentNumber)
                if (!isFile) {
                    const buffer = Buffer.from(dcmjs.data.datasetToDict(generatedSegmentation.dataset).write());
                    let blob = new Blob([buffer], { type: "application/dicom" });
                    return blob
                } else {
                    this.downloadDICOMData(generatedSegmentation.dataset, `${group.name}.dcm`);
                }
            } catch (err) {
                console.log(err)
            }

        },
        downloadDICOMData(bufferOrDataset, filename) {
            let blob;
            if (bufferOrDataset instanceof ArrayBuffer) {
                blob = new Blob([bufferOrDataset], { type: 'application/dicom' });
            } else {
                if (!bufferOrDataset._meta) {
                    throw new Error('Dataset must have a _meta property');
                }
                blob = dcmjs.data.datasetToBlob(bufferOrDataset);
            }

            const link = document.createElement('a');
            link.href = window.URL.createObjectURL(blob);
            link.download = filename;
            link.click();
        },

        // 导入SEG
        beginScanFiles(e) {
            let files = e.target.files
            for (const file of files) {
                file.segmentationId = this.$guid()
                this.readSegmentation(file, true)
            }
        },
        async readSegmentation(obj, isFile = false) {
            let imageId = null
            if (isFile) {
                imageId = cornerstoneDICOMImageLoader.wadouri.fileManager.add(obj);
                obj.segmentationId = this.$guid()
                await this.createSegmentation(obj.segmentationId);
            } else {
                const imageIdObj = await cornerstoneDICOMImageLoader.wadouri.loadImage(`wadouri:${this.OSSclientConfig.basePath}${obj.segUrl}`).promise
                imageId = imageIdObj.imageId
            }
            const image = await imageLoader.loadAndCacheImage(imageId);
            if (!image) {
                return;
            }

            const instance = metaData.get("instance", imageId);

            if (instance.Modality !== "SEG") {
                console.error("This is not segmentation: " + file.name);
                return;
            }

            const arrayBuffer = image.data.byteArray.buffer;
            await this.loadSegmentation(arrayBuffer, obj.segmentationId);
            // this.createSegmentationRepresentation(obj.segmentationId);
        },
        async loadSegmentation(arrayBuffer, segmentationId) {
            const generateToolState =
                await Cornerstone3D.Segmentation.generateToolState(
                    this.series.ImageIds,
                    arrayBuffer,
                    metaData,
                );
            if (generateToolState.labelmapBufferArray.length !== 1) {
                alert(
                    "Overlapping segments in your segmentation are not supported yet. You can turn on the skipOverlapping option but it will override the overlapping segments."
                );
                return;
            }
            let arr = []
            generateToolState.segMetadata.data.forEach(item => {
                if (item) {
                    let Target = JSON.parse(JSON.stringify(item))
                    arr.push(Target)
                }
            })

            let mapping = {}

            arr.forEach((item, index) => {
                mapping[index + 1] = Number(item.SegmentNumber)
            })
            console.log(mapping, 'mapping')
            const megmentGroup =
                segmentation.state.getSegmentation(segmentationId);
            const { imageIds } = megmentGroup.representationData.Labelmap;
            const derivedSegmentationImages = imageIds.map(imageId =>
                cache.getImage(imageId)
            );

            const volumeScalarData = new Uint8Array(
                generateToolState.labelmapBufferArray[0]
            );
            const remappedData = new Uint8Array(volumeScalarData.length);
            for (let i = 0; i < volumeScalarData.length; i++) {
                const value = volumeScalarData[i];
                remappedData[i] = value === 0 ? 0 : (mapping[value] ? mapping[value] : value);
            }
            for (let i = 0; i < derivedSegmentationImages.length; i++) {
                const voxelManager = derivedSegmentationImages[i].voxelManager;
                const scalarData = voxelManager.getScalarData();
                scalarData.set(
                    remappedData.slice(
                        i * scalarData.length,
                        (i + 1) * scalarData.length
                    )
                );
                voxelManager.setScalarData(scalarData);
            }
            this.createSegmentationRepresentation(segmentationId)
        },
        createSegmentGroupObj(name) {
            let flag = this.segmentList.some(item => item.name === name)
            let obj = {
                segmentationId: this.$guid(),
                name: !flag ? name : this.$t('trials:reading:Segmentations:name:SegmentGroup') + (this.segmentList.length + 1),
                view: true,
                segments: []
            }
            return obj
        },
        readingSegmentByConfig() {
            this.changeInactiveSegmentShow()
            segmentation.config.style.setStyle(
                {
                    type: csToolsEnums.SegmentationRepresentations.Labelmap,
                },
                {
                    renderFill: this.SegmentConfig.renderFill,
                    renderOutline: this.SegmentConfig.renderOutline,
                    outlineWidth: Number(this.SegmentConfig.outlineWidth),
                    fillAlpha: Number(this.SegmentConfig.fillAlpha),
                }
            )
        },
        setBrushSize(toolName = null) {
            const toolGroupId = this.isMPR ? this.volumeToolGroupId : `${this.viewportKey}-${this.activeViewportIndex}`
            CStUtils.segmentation.setBrushSizeForToolGroup(toolGroupId, this.brushSize);
            if (toolName === 'ThresholdSphere') {
                this.setDynamicRadius()
            }
            if (toolName === 'SphericalBrush') {
                this.setSphericalBrushConfig()
            }
        },
        setSphericalBrushConfig() {
            let volume = cache.getVolume(this.series.SeriesInstanceUid);
            let { spacing, numFrames } = volume
            let constant = numFrames * spacing[2] / 100
            let dynamicRadius = Math.ceil(this.brushSize * constant)
            let obj = {
                dynamicRadius: dynamicRadius,
                isDynamic: false,
                range: [-10000, 100000]
            }
            this.setBrushThreshold(obj)
        },
        setDynamicRadius() {
            let volume = cache.getVolume(this.series.SeriesInstanceUid);
            let { spacing, numFrames } = volume
            let constant = numFrames * spacing[2] / 100
            this.brushThreshold.dynamicRadius = Math.ceil(this.brushSize * constant)
        },
        setBrushThreshold(OBJ = null) {
            const toolGroupId = this.isMPR ? this.volumeToolGroupId : `${this.viewportKey}-${this.activeViewportIndex}`
            let brushThreshold = {
                isDynamic: this.brushThreshold.isDynamic,
                dynamicRadius: this.brushThreshold.dynamicRadius,
            }
            if (!this.brushThreshold.isDynamic) {
                brushThreshold.range = this.brushThreshold.range
            }
            if (OBJ) brushThreshold = OBJ
            CStUtils.segmentation.setBrushThresholdForToolGroup(toolGroupId, brushThreshold);
        },
        async createSegmentation(segmentationId) {
            const toolGroupId = this.isMPR ? this.volumeToolGroupId : `${this.viewportKey}-${this.activeViewportIndex}`
            const toolGroup = ToolGroupManager.getToolGroup(toolGroupId)
            toolGroup.setToolActive(
                LabelMapEditWithContourTool.toolName,
            );
            if (!cache.getVolume(segmentationId)) {
                await volumeLoader.createAndCacheDerivedLabelmapVolume(
                    this.series.SeriesInstanceUid,
                    {
                        volumeId: segmentationId
                    }
                )
            }
            if (!segmentation.state.getSegmentation(segmentationId)) {
                segmentation.addSegmentations([
                    {
                        segmentationId,
                        representation: {
                            type: cornerstoneTools.Enums.SegmentationRepresentations
                                .Labelmap,
                            data: {
                                volumeId: segmentationId
                            }
                        }
                    }
                ]);
            }

        },
        segmentationModifiedCallback(evt) {
            const { detail } = evt;
            let tools = [...this.ThresholdTools, ...this.tools, 'SphericalBrush']
            if (!detail || detail.segmentIndex === 255 || !this.activeTool || !tools.includes(this.activeTool)) {
                return;
            }
            this.drawing = true
        },
        async calculateStatistics(indices, segmentationId, mode) {
            try {
                if (!segmentation.state.getSegmentation(segmentationId)) return false
                this.saveLoading = true
                const stats = await segmentationUtils.getStatistics({
                    segmentationId,
                    segmentIndices: indices,
                    mode,
                });
                console.log(stats)
                if (mode === 'individual') {
                    const segmentStats = stats;
                    for (const segmentIndex of indices) {
                        if (segmentStats[segmentIndex]) {
                            const segmentStat = segmentStats[segmentIndex];
                            // console.log(segmentStat, 'segmentStat')
                            segmentStat.count.label = 'Voxels';
                            if (this.series.Modality === 'PT') {
                                const renderingEngine = getRenderingEngine(this.renderingEngineId)
                                const viewportId = `${this.viewportKey}-${this.activeViewportIndex}`
                                const viewport = renderingEngine.getViewport(viewportId);
                                let imageIds = viewport.getImageIds(this.series.SeriesInstanceUid)
                                let imageId = imageIds[0]
                                const suvFactor = metaData.get('scalingModule', imageId) || {};
                                console.log(suvFactor, 'suvFactor')
                                segmentStat.sulpeak = {
                                    label: "Mean Pixel",
                                    name: "sulpeak",
                                    unit: "SUL",
                                    value: suvFactor.suvlbm && suvFactor.suvbw ? segmentStat.mean.value * suvFactor.suvlbm / suvFactor.suvbw : 0,
                                }
                            }
                            let segmentGroup = this.segmentList.find(item => item.segmentationId === segmentationId)
                            if (segmentGroup) {
                                let segment = segmentGroup.segments.find(item => item.segmentIndex === segmentIndex)
                                segment.stats = segmentStat;
                            }

                        }
                    }
                } else {
                    const items = [`Statistics on ${indices.join(', ')}`];
                    const namedStats = stats;
                    namedStats.count.label = 'Voxels';

                }
                this.saveLoading = false
            } catch (err) {
                console.log(err)
                this.saveLoading = false
            }
        },
        createSegmentationRepresentation(segmentationId) {
            DicomEvent.$emit('createSegmentationRepresentation', segmentationId)
            this.$emit('setToolsPassive')
        },
        contentMouseup() {
            try {
                // console.log("segment contentMouseup")
                if (this.timeoutId) {
                    clearTimeout(this.timeoutId);
                    this.timeoutId = null;
                }
                this.timeoutId = setTimeout(() => {
                    if (!this.drawing) return false
                    this.timeoutId = null;
                    this.drawing = false;
                    let segmentGroup = this.segmentList.find(item => item.segmentationId === this.segmentationId)
                    if (segmentGroup && segmentGroup.segments && segmentGroup.segments.length > 0) {
                        let segmentIndexs = []
                        segmentGroup.segments.forEach(item => {
                            segmentIndexs.push(item.segmentIndex)
                            item.bidirectional = null
                            item.stats = null
                        })
                        annotation.state.getAllAnnotations().forEach(i => {
                            if (i.metadata.segmentationId === this.segmentationId && i.metadata.toolName === "SegmentBidirectional") {
                                annotation.state.removeAnnotation(i.annotationUID)
                            }
                        })
                        this.calculateStatistics(segmentIndexs, this.segmentationId, 'individual');
                        this.resetViewport(false)
                        // this.getBidirectional(segmentGroup.segments)

                    }
                }, 500);
            } catch (err) {
                console.log(err)
            }

        },
        // 获取当前任务分割标记与问题绑定关系
        async getSegmentBindingList(param = {}) {
            try {
                let data = {
                    VisitTaskId: this.series.TaskInfo.VisitTaskId,
                    PageSize: 9999,
                    PageIndex: 1,
                }
                data = Object.assign(data, param)
                let res = await getSegmentBindingList(data)
                if (res.IsSuccess) {
                    return res.Result.CurrentPageData
                }
            } catch (err) {
                console.log(err)
            }
        },
        // 添加分割标记与问题绑定关系
        async saveSegmentBindingAndAnswer(list) {
            try {
                let data = {
                    VisitTaskId: this.series.TaskInfo.VisitTaskId,
                    BindingList: list
                }
                let res = await saveSegmentBindingAndAnswer(data)
                if (res.IsSuccess) {
                    this.$emit("resetQuestion")
                }
            } catch (err) {
                console.log(err)
            }
        },
        checkSaveLoading(callback) {
            if (!this.saveLoading) {
                if (this.timer) {
                    clearInterval(this.timer)
                    this.timer = null
                }
                this.saveSegmentGroup(null, true, callback)
            } else {
                this.timer = setInterval(() => {
                    if (!this.saveLoading) {
                        console.log(this.saveLoading, 'timer')
                        if (this.timer) {
                            clearInterval(this.timer)
                            this.timer = null
                        }
                        this.saveSegmentGroup(null, true, callback)
                    }
                }, 100)
            }
        },
        // 保存整个分组
        async saveSegmentGroup(list = null, saveSegment = true, callback) {
            try {
                console.log('saveSegmentGroup')
                let segmentList = list ? list : this.segmentList
                if (segmentList.length <= 0) return false
                this.$emit("setToolsPassive")
                this.$emit("update:globalLoading", true)
                this.$emit("update:loadingText", this.$t("segment:loadingText:saveSegmentation"))
                let IsBeSegment = false
                for (let i = 0; i < segmentList.length; i++) {
                    let segmentGroup = segmentList[i]
                    // 将所有分割进行锁定
                    segmentGroup.segments.forEach(s => {
                        this.lockSegment(s, true)
                    })
                    // 生成文件路径
                    let blob = this.exportSegmentation(segmentGroup.segmentationId, segmentGroup)
                    console.log(blob, 'blob')
                    // if (!blob) return false
                    if (blob) {
                        let path = `/${this.$route.query.trialId}/Segment/${this.visitInfo.SubjectId
                            }/${this.visitInfo.VisistId}/${this.series.StudyId
                            }/${this.series.Id}/${segmentGroup.name}.dcm`
                        const result = await this.OSSclient.put(path, blob)
                        segmentGroup.oldSegUrl = segmentGroup.segUrl
                        segmentGroup.segUrl = this.$getObjectName(result.url)
                        DicomEvent.$emit("IsBeSegment", { StudyId: this.series.StudyId, Id: this.series.Id, IsBeSegment: true })
                    } else {
                        blob = { size: 0 }
                        segmentGroup.segUrl = null
                    }
                    segmentGroup.size = blob.size
                    this.addOrUpdateSegmentation({ name: segmentGroup.name, id: segmentGroup.segmentationId, url: segmentGroup.segUrl, size: blob.size })
                    this.changeSegmentationSavedStatus(segmentGroup.segmentationId, saveSegment)
                    if (saveSegment) {
                        await this.getBidirectionalSaveSegment(segmentList)
                        this.syncBindingAnswer(segmentList)
                    }
                }
                if (!IsBeSegment) {
                    let f = this.segmentList.some(item => item.segUrl)
                    DicomEvent.$emit("IsBeSegment", { StudyId: this.series.StudyId, Id: this.series.Id, IsBeSegment: f })
                }
                this.$emit("update:globalLoading", false)
                if (callback) callback()
            } catch (err) {
                this.loading = false
                console.log(err)
            }
        },
        // 获取长短径并提交分割段
        async getBidirectionalSaveSegment(list) {
            for (let i = 0; i < list.length; i++) {
                let segmentGroup = list[i]
                if (segmentGroup.segments && segmentGroup.segments.length > 0) {
                    for (let j = 0; j < segmentGroup.segments.length; j++) {
                        let segment = segmentGroup.segments[j]
                        let res = await Promise.race([this.getBidirectionalToSegment([segment]), this.setDelay(300000)])
                        if (res) {
                            this.addOrUpdateSegment({ name: segment.SegmentLabel, color: segment.color, segmentIndex: segment.segmentIndex, segmentationId: segment.segmentationId, segmentJson: JSON.stringify({ stats: segment.stats, bidirectional: segment.bidirectional }), id: segment.id })

                        }
                    }
                }
            }

        },
        getBidirectionalToSegment(list) {
            return new Promise(async (reslove, reject) => {
                list.forEach(item => {
                    this.createSegmentConfiguration(item.segmentIndex, item.segmentationId);
                })
                const renderingEngine = getRenderingEngine(this.renderingEngineId)
                const viewportId = `${this.viewportKey}-${this.activeViewportIndex}`
                const viewport = renderingEngine.getViewport(viewportId);
                [viewport.element].forEach(async (element) => {
                    const bidirectionalData =
                        await CStUtils.segmentation.getSegmentLargestBidirectional({
                            segmentationId: list[0].segmentationId,
                            segmentIndices: list.map(item => item.segmentIndex),
                        });
                    // console.log(bidirectionalData)
                    if (bidirectionalData.length <= 0) {
                        list.forEach(item => {
                            let annotations = annotation.state.getAllAnnotations().filter(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === item.segmentIndex);
                            annotations.forEach(i => {
                                annotation.state.removeAnnotation(i.annotationUID)
                            })
                            item.bidirectional = null
                        })
                        this.resetViewport(false)
                        return reslove(true)
                    }

                    let bidirectional = bidirectionalData[0]
                    const { segmentIndex } = bidirectional;
                    const { majorAxis, minorAxis } = bidirectional;
                    let item = list.find(i => i.segmentIndex === segmentIndex)
                    SegmentBidirectionalTool.hydrate(viewportId, [majorAxis, minorAxis], {
                        segmentIndex,
                        segmentationId: item.segmentationId,
                    });
                    let an = annotation.state.getAllAnnotations().find(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === bidirectional.segmentIndex && i.metadata.toolName === "SegmentBidirectional");
                    if (an) {
                        annotation.locking.setAnnotationLocked(an.annotationUID, true)
                        annotation.visibility.setAnnotationVisibility(an.annotationUID, true)
                    }
                    item.bidirectional = bidirectional
                    reslove(true)

                });
            })

        },
        setDelay(time) {
            return new Promise(async (reslove, reject) => {
                setTimeout(() => { reslove(true) }, time)
            })
        },
        async syncBindingAnswer(segmentList) {
            let bindingList = []
            for (let i = 0; i < segmentList.length; i++) {
                let segmentGroup = segmentList[i]
                let data = {
                    SegmentationId: segmentGroup.segmentationId
                }
                let res = await this.getSegmentBindingList(data)
                // if (res && res.length > 0) questionNeedChange = true
                for (let j = 0; j < res.length; j++) {
                    let item = res[j]
                    let segment = segmentGroup.segments.find(d => d.id === item.SegmentId)
                    let question = await this.getQuestionConfig(item.TableQuestionId ? item.TableQuestionId : item.QuestionId, !!item.TableQuestionId);
                    let imageToolAttribute = question.ImageToolAttribute
                    let answer = ''
                    if (imageToolAttribute === 'length' || imageToolAttribute === 'width') {
                        let s = {
                            length: "maxMajor",
                            width: 'maxMinor'
                        }
                        answer = segment.bidirectional && segment.bidirectional[s[imageToolAttribute]] ? Number(segment.bidirectional[s[imageToolAttribute]]).toFixed(this.digitPlaces) : ''
                    } else {
                        answer = segment.stats && segment.stats[imageToolAttribute] ? Number((segment.stats[imageToolAttribute]).value).toFixed(this.digitPlaces) : ''
                    }
                    let o = {
                        Answer: answer === '-Infinity' || answer === 'NaN' ? null : answer,
                        QuestionId: item.QuestionId,
                        RowId: item.RowId,
                        SegmentId: item.SegmentId,
                        SegmentationId: item.SegmentationId,
                        TableQuestionId: item.TableQuestionId,
                        VisitTaskId: this.series.TaskInfo.VisitTaskId,
                    }
                    bindingList.push(o)
                }
            }
            if (bindingList.length > 0) this.saveSegmentBindingAndAnswer(bindingList)
        },
        // 新增或修改分割组
        async addOrUpdateSegmentation(item) {
            let { name, id, url, size } = item
            try {
                let data = {
                    SegmentationName: name,
                    SeriesId: this.series.Id,
                    StudyId: this.series.StudyId,
                    SubjectId: this.visitInfo.SubjectId,
                    SubjectVisitId: this.visitInfo.VisistId,
                    TrialId: this.$route.query.trialId,
                    VisitTaskId: this.series.TaskInfo.VisitTaskId,
                }
                if (url) data.SegUrl = url;
                if (id) data.Id = id;
                if (size) data.FileSize = size;
                this.loading = true;
                let res = await addOrUpdateSegmentation(data);
                this.loading = false;
                if (res.IsSuccess) {
                    return res.Result
                }
            } catch (err) {
                this.loading = false
                console.log(err)
            }
        },
        async getSegmentation(segmentationId) {
            return new Promise(async (resolve, reject) => {
                try {
                    let data = {
                        SeriesId: this.series.Id,
                        VisitTaskId: this.series.TaskInfo.VisitTaskId,
                        PageSize: 9999,
                        PageIndex: 1,
                    }
                    this.loading = true;
                    let res = await getSegmentationList(data);
                    this.loading = false;
                    if (res.IsSuccess) {
                        // this.segmentList = []
                        // this.segmentationId = null;
                        // this.segmentIndex = null;
                        let list = res.Result.CurrentPageData;
                        for (let i = 0; i < list.length; i++) {
                            let item = list[i]
                            if (item.Id !== segmentationId) continue;
                            let obj = this.segmentList.find(i => i.segmentationId === item.Id)
                            if (!obj) continue;
                            obj.name = item.SegmentationName;
                            obj.segUrl = item.SEGUrl;
                            obj.size = item.FileSize;
                            obj.isSaved = item.IsSaved;
                            obj.segmentationId = item.Id;
                            obj.segments = []
                            if (!this.segmentationId) {
                                this.segmentationId = obj.segmentationId
                            }
                            let segments = await this.getSegmentList(item.Id)
                            segments.forEach((s, index) => {
                                let SegmentJson = s.SegmentJson ? JSON.parse(s.SegmentJson) : {};
                                let o = {
                                    segmentIndex: s.SegmentNumber,
                                    segmentationId: s.SegmentationId,
                                    SegmentLabel: s.SegmentName,
                                    color: s.ColorRgb,
                                    stats: SegmentJson.stats,
                                    bidirectional: SegmentJson.bidirectional,
                                    bidirectionalView: true,
                                    view: true,
                                    lock: s.IsLock,
                                    id: s.Id
                                }
                                obj.segments.push(o)

                            })
                            this.segmentIndex = obj.segments[0].segmentIndex
                        }
                        this.isloaded = false
                        resolve(true)
                    } else {
                        resolve(false)
                    }
                } catch (err) {
                    console.log(err)
                    resolve(false)
                }
            })

        },
        // 获取分割组
        async getSegmentationList() {
            try {
                this.$emit('setToolsPassive')
                let data = {
                    SeriesId: this.series.Id,
                    VisitTaskId: this.series.TaskInfo.VisitTaskId,
                    PageSize: 9999,
                    PageIndex: 1,
                }
                this.loading = true;
                let res = await getSegmentationList(data);
                // this.loading = false;
                if (res.IsSuccess) {
                    this.segmentList = []
                    this.segmentationId = null;
                    this.segmentIndex = null;
                    let list = res.Result.CurrentPageData;
                    for (let i = 0; i < list.length; i++) {
                        let item = list[i]
                        let obj = this.segmentList.find(i => i.segmentationId === item.Id)
                        if (!obj) {
                            obj = {
                                segmentationId: item.Id,
                                name: item.SegmentationName,
                                view: true,
                                segUrl: item.SEGUrl,
                                size: item.FileSize,
                                isSaved: item.IsSaved,
                                segments: []
                            }
                            this.segmentList.push(obj)
                        }
                        if (!this.segmentationId) {
                            this.segmentationId = obj.segmentationId
                        }
                        let segments = await this.getSegmentList(item.Id)
                        segments.forEach((s, index) => {
                            let SegmentJson = s.SegmentJson ? JSON.parse(s.SegmentJson) : {};
                            let o = obj.segments.find(i => i.id === s.Id)
                            if (!o) {
                                o = {
                                    segmentIndex: s.SegmentNumber,
                                    segmentationId: s.SegmentationId,
                                    SegmentLabel: s.SegmentName,
                                    color: s.ColorRgb,
                                    stats: SegmentJson.stats,
                                    bidirectional: SegmentJson.bidirectional,
                                    bidirectionalView: true,
                                    view: true,
                                    lock: s.IsLock,
                                    id: s.Id
                                }
                                obj.segments.push(o)
                            }
                            if (!this.segmentIndex) {
                                this.segmentIndex = s.SegmentNumber
                            }
                        })
                    }
                    this.isloaded = false
                }
            } catch (err) {
                // this.loading = false
                console.log(err)
            }
        },
        // 删除分割组
        async deleteSegmentation(id) {
            try {
                this.loading = true;
                let res = await deleteSegmentation(id)
                this.loading = false;
                if (res.IsSuccess) return true
                return false
            } catch (err) {
                this.loading = false
                console.log(err)
            }
        },
        // 新增或修改分割
        async addOrUpdateSegment(item) {
            try {
                let { name, color, segmentIndex, segmentationId, segmentJson, id } = item
                let data = {
                    ColorRgb: color,
                    SegmentName: name,
                    SegmentNumber: segmentIndex,
                    SegmentationId: segmentationId,
                    VisitTaskId: this.series.TaskInfo.VisitTaskId,
                    SegmentJson: segmentJson
                }
                if (id) data.Id = id
                this.loading = true;
                let res = await addOrUpdateSegment(data)
                this.loading = false;
                if (res.IsSuccess) {
                    return res.Result
                }
            } catch (err) {
                this.loading = false
                console.log(err)
            }
        },
        // 获取分割
        async getSegmentList(id) {
            try {
                let data = {
                    SegmentationId: id,
                    PageSize: 9999,
                    PageIndex: 1,
                }
                // this.loading = true;
                let res = await getSegmentList(data)
                // this.loading = false;
                if (res.IsSuccess) {
                    return res.Result.CurrentPageData
                }
            } catch (err) {
                // this.loading = false
                console.log(err)
            }
        },
        // 删除分割
        async deleteSegment(id) {
            try {
                this.loading = true;
                let res = await deleteSegment(id)
                this.loading = false;
                if (res.IsSuccess) return true
                return false
            } catch (err) {
                this.loading = false
                console.log(err)
            }
        },
        // 获取问题配置
        async getQuestionConfig(Id, isTable = false) {
            try {
                let params = {
                    Id
                }
                let res = null
                if (isTable) {
                    res = await getReadingTableQuestionTrialById(params)
                } else {
                    res = await getReadingQuestionTrialById(params)
                }
                if (res.IsSuccess) return res.Result
            } catch (err) {
                console.log(err)
            }
        },
        // 修改分割组状态
        async changeSegmentationSavedStatus(Id, IsSaved) {
            try {
                let params = {
                    IsSaved,
                    Id
                }
                let res = await changeSegmentationSavedStatus(params)
                if (res.IsSuccess) {
                    let segmentGroup = this.segmentList.find(item => item.segmentationId === Id)
                    if (segmentGroup) segmentGroup.isSaved = IsSaved

                }
            } catch (err) {
                console.log(err)
            }
        },
        // 修改分割片段锁定状态
        async lockOrUnLockSegment(SegmentId, IsLock) {
            try {
                let data = {
                    SegmentId,
                    IsLock
                }
                let res = await lockOrUnLockSegment(data)
                if (res.IsSuccess) return true
                return false
            } catch (err) {
                console.log(err)
            }
        },
        hex2Rgb(hexValue, alpha = 1) {
            const rgx = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
            const hex = hexValue.replace(rgx, (m, r, g, b) => r + r + g + g + b + b);
            const rgb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
            if (!rgb) {
                return hexValue;
            }
            const r = parseInt(rgb[1], 16),
                g = parseInt(rgb[2], 16),
                b = parseInt(rgb[3], 16);
            return [r, g, b, alpha * 255];
        },
        randomNearColor(hex, range = 3) {
            if (!/^#([0-9a-fA-F]{6})$/.test(hex)) {
                throw new Error('请输入正确的 6 位十六进制颜色值，例如 #000000');
            }

            const hexToRgb = (hex) => ({
                r: parseInt(hex.slice(1, 3), 16),
                g: parseInt(hex.slice(3, 5), 16),
                b: parseInt(hex.slice(5, 7), 16),
            });

            const rgbToHsl = (r, g, b) => {
                r /= 255; g /= 255; b /= 255;
                const max = Math.max(r, g, b);
                const min = Math.min(r, g, b);
                let h = 0, s = 0;
                const l = (max + min) / 2;

                if (max !== min) {
                    const d = max - min;
                    s = l > 0.5 ? d / (2 - max - min) : d / (max + min);

                    switch (max) {
                        case r: h = (g - b) / d + (g < b ? 6 : 0); break;
                        case g: h = (b - r) / d + 2; break;
                        case b: h = (r - g) / d + 4; break;
                    }

                    h *= 60;
                }

                return { h, s: s * 100, l: l * 100 };
            };

            const hslToRgb = (h, s, l) => {
                h /= 360; s /= 100; l /= 100;
                let r, g, b;

                if (s === 0) {
                    r = g = b = l;
                } else {
                    const hue2rgb = (p, q, t) => {
                        if (t < 0) t += 1;
                        if (t > 1) t -= 1;
                        if (t < 1 / 6) return p + (q - p) * 6 * t;
                        if (t < 1 / 2) return q;
                        if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
                        return p;
                    };

                    const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
                    const p = 2 * l - q;

                    r = hue2rgb(p, q, h + 1 / 3);
                    g = hue2rgb(p, q, h);
                    b = hue2rgb(p, q, h - 1 / 3);
                }

                return {
                    r: Math.round(r * 255),
                    g: Math.round(g * 255),
                    b: Math.round(b * 255),
                };
            };

            const rgbToHex = (r, g, b) =>
                `#${[r, g, b].map(v => v.toString(16).padStart(2, '0')).join('')}`;

            const clamp = (v, min, max) => Math.min(max, Math.max(min, v));
            const randomOffset = (n) => (Math.random() * 2 - 1) * n;

            const { r, g, b } = hexToRgb(hex);
            const { h, s, l } = rgbToHsl(r, g, b);

            const nh = (h + randomOffset(range) + 360) % 360;
            const ns = clamp(s + randomOffset(range), 0, 100);
            const nl = clamp(l + randomOffset(range), 0, 100);

            const rgb = hslToRgb(nh, ns, nl);
            return rgbToHex(rgb.r, rgb.g, rgb.b);
        }
    },
    destroyed() {
        if (this.timer) {
            clearInterval(this.timer)
            this.timer = null
        }
    }
}
</script>
<style lang="scss" scoped>
::v-deep .el-table th.el-table__cell {
    background-color: #1e1e1e;
}

::v-deep .el-table tr {
    background-color: #1e1e1e;
    color: #fff;
}

::v-deep .hover-row>td.el-table__cell {
    background-color: #1e1e1e !important;
    // opacity: 0.5;
    color: #fff;
}

.Segmentations {
    height: 100%;
    position: relative;

    .saveBtnBox {
        position: absolute;
        bottom: 5px;
        left: 50%;
    }
}

.Bidirectionalbox {
    padding: 10px;
    border-bottom: 1px solid #333;
    width: 100%;
    display: flex;
    justify-content: space-between;
    align-items: center;

    .BidirectionalBtn {
        width: 100%;
        cursor: pointer;
    }

    .num {
        display: flex;
        width: 70%;
        flex-wrap: wrap;

        span {
            display: block;
            width: 100%;
        }
    }

    .btnBox {
        display: flex;
        align-items: center;
    }
}

.statsBox {
    padding: 0 10px;
    display: flex;
    justify-content: space-between;
    color: #333;

    i {
        margin-left: 5px;
        color: #000;
    }
}

.SegmentBox {
    display: flex;
    align-items: center;
    justify-content: space-between;
    color: #fff;
    background-color: #333;
    cursor: pointer;
    margin: 0 5px 10px;
    border-radius: 3px;
    padding: 5px 10px;
    position: relative;

    .messageBox {
        display: flex;
        align-items: center;
        margin-left: 30px;
        width: 70%;

        .serialNum {
            position: absolute;
            height: 100%;
            width: 30px;
            left: 0;
            top: 0;
            display: flex;
            align-items: center;
            justify-content: center;
            line-height: 30px;
            background-color: #222;
        }

        .color {
            width: 10px;
            height: 10px;
            background-color: #f0f;
            border-radius: 50%;
        }

        .SegmentName {
            margin-left: 5px;
            max-width: 120px;
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
        }
    }

    .btnBox {
        i {
            font-size: 20px;
            margin-left: 5px;
        }

        .segmentBtn {
            display: none;
        }

        .docShow {
            display: inline-block;
        }
    }

    &:hover {
        background-color: #999;

        .messageBox {
            color: #333;
        }

        .serialNum {
            color: #fff;
        }

        .segmentBtn {
            display: inline-block;
        }
    }
}

.SegmentBox_active {
    background-color: #999;

    .messageBox {
        color: #333;
        cursor: not-allowed;
    }

    .serialNum {
        color: #fff;
    }
}

.SegmentGroupBox {
    padding: 8px 10px;
    background-color: #333;
    margin: 0 5px;
    border-radius: 3px;
    display: flex;
    align-items: center;
    justify-content: space-between;

    i {
        font-size: 20px;
    }

    ::v-deep .el-input--medium {
        .el-input__inner {
            line-height: 30px;
            height: 30px;
        }

        .el-input__icon {
            line-height: 30px;
        }
    }

    ::v-deep .el-select {
        margin-left: 10px;
    }
}

.SegmentGroupBtn {
    line-height: 30px;
    cursor: pointer;
    border-radius: 3px;
    padding: 0 10px;

    &:hover {
        background-color: rgba($color: #409EFF, $alpha: 0.2);
    }
}

.addSegmentBox {
    cursor: pointer;
    color: #fff;
    line-height: 30px;
    margin: 5px;
    padding: 0 10px;
    border-radius: 3px;
}

.viewHover {
    &:hover {
        background-color: #ddd;
        color: #333;

    }
}

.line {
    display: block;
    border-bottom: 1px solid #333;
    margin-bottom: 4px;
}

.SegmentTitle {
    width: 100%;
    display: flex;
    justify-content: space-between;

    .svg-icon {
        transform: rotate(90deg);
    }
}

.EraserConfig,
.SegmentConfig {
    width: calc(100% - 10px);
    padding: 0 10px;
    display: flex;
    justify-content: space-between;
    align-items: center;

    span {
        color: #fff;
        margin-right: 10px;
    }

    ::v-deep .el-slider {
        width: 70%;
    }

    ::v-deep .el-slider__input {
        width: 60px;
    }

    ::v-deep .el-slider__runway.show-input {
        margin-right: 70px;
    }
}

.EraserConfig {
    margin: 5px 0;

    ::v-deep .el-input-number {
        width: 90px;
    }

    ::v-deep .el-input-number.is-without-controls .el-input__inner {
        padding: 0 10px;
        width: 90px;
    }

    ::v-deep .el-radio-button__inner {
        width: 105px;
    }
}

.RadiusConfig {
    ::v-deep .el-input-number {
        width: 50px;
    }

    ::v-deep .el-input-number.is-without-controls .el-input__inner {
        padding: 0 10px;
        width: 50px;
    }
}

.SegmentConfig {
    padding: 5px 10px;
}

.svg-icon {
    color: #fff;
    font-size: 20px;
}

.tool-item {
    padding: 5px;
    margin: 0 5px;
    border: 1px solid #333;
    // font-size: 20px;
    cursor: pointer;
}

.tool-item-active {
    background-color: #607d8b;
}

.tool-disabled {
    cursor: not-allowed;
}

.tool-frame {
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    align-items: center;
    // margin-right: 20px;
    padding: 5px 10px;
    margin-bottom: 10px;
    border-bottom: 1px solid #404040;

    .icon {
        padding: 5px 10px;
        border-right: 1px solid #404040;
        cursor: pointer;
        text-align: center;

        .svg-icon {
            font-size: 20px;
            color: #ddd;
        }
    }

    .select-wrapper {
        width: 60px;
        background-color: black;
        color: #ddd;
        border: none;
        font-size: 13px;
        outline: none;
    }

    .text {
        position: relative;
        font-size: 12px;
        margin-top: 5px;
        color: #d0d0d0;
        display: none;
    }
}

::v-deep.el-collapse {
    border: none;

    .el-collapse-item {
        background-color: #000 !important;
        color: #ddd;

    }

    .el-collapse-item__content {
        padding-bottom: 0px;
        background-color: #000 !important;
        line-height: 1;
    }

    .el-collapse-item__header {
        background-color: #000 !important;
        color: #ddd;
        border-bottom-color: #5a5a5a;
        padding-left: 10px;
        // height: 50px;
        line-height: 20px;
    }
}

::v-deep .el-progress-bar__inner {
    transition: width 0s ease;
}

::v-deep .el-collapse-item__wrap {
    background-color: #000;
}
</style>