<template>
  <div class="none-dicom-viewer">
    <!-- viewports -->
    <div class="viewports-wrapper" v-loading="loading" ref="viewports-wrapper">
      <div ref="container" class="grid-container" :style="gridStyle">
        <div v-for="(v, index) in viewportInfos" :ref="`grid-cell-${index}`" :key="index" :style="getCellStyle(index)"
          :class="['grid-cell', index === activeCanvasIndex ? 'cell_active' : '', index === fullScreenIndex ? 'cell-full-screen' : '']"
          @dblclick="toggleFullScreen($event, index)" @click="activeCanvas(index)"
          @mouseup="sliderMouseup($event, index)" @mousemove="sliderMousemove($event, index)"
          @mouseleave="sliderMouseleave($event, index)">
          <div v-show="imageType.includes(v.fileType)" :ref="`canvas-${index}`" class="content">
            <div class="left-top-text">
              <div v-if="v.currentFileName">{{ v.currentFileName }}</div>
              <div v-if="v.imageIds.length > 0">{{ `${v.currentImageIdIndex + 1} / ${v.imageIds.length}` }}</div>
              <div v-if="isComparison" style="font-size: 30px;color: #428bca;margin-top: 10px;">{{ tip[index] }}</div>
            </div>
            <div class="left-bottom-text">
              <div v-if="v.zoomText">{{ `Zoom: ${v.zoomText}` }}</div>
            </div>
            <div :ref="`sliderBox-${index}`" class="right-slider-box" @click.stop="clickSlider($event, index)">
              <div :style="{ top: v.height + '%' }" class="slider" @click.stop.prevent="() => { return }"
                @mousedown.stop="sliderMousedown($event, index)" />
            </div>
          </div>
          <div v-if="v.fileType === 'application/pdf' && fullScreenIndex === null" class="content flex_col">
            <div class="content-top" style="height: 50px;">
              <div class="left-top-text">
                <div v-if="v.currentFileName">{{ v.currentFileName }}</div>
              </div>
            </div>
            <div class="content-main" style="flex: 1;">
              <iframe v-if="v.currentFilePath" :ref="`iframe-${index}`"
                :src="`/static/pdfjs/web/viewer.html?file=${OSSclientConfig.basePath}${v.currentFilePath}?index=${index}`"
                width="100%" height="100%" frameborder="0" crossorigin="anonymous" />
            </div>

          </div>

          <div v-if="v.fileType.includes('mp4')" class="content flex_col">
            <div class="content-top" style="height: 50px;">
              <div class="left-top-text">
                <div v-if="v.currentFileName">{{ v.currentFileName }}</div>
              </div>
            </div>
            <div class="content-main" :ref="`video-content-main-${index}`" style="flex: 1;">
              <video v-if="v.currentFilePath" :ref="`videovideo-${index}`"
                :src="`${OSSclientConfig.basePath}${v.currentFilePath}`" crossorigin="anonymous" width="100%"
                height="100%" autoplay controls controlsList="nodownload"></video>
            </div>

          </div>

        </div>
      </div>
      <div class="Anonymous" v-if="isAnonymous">
        <div
          :class="{ btn: true, activeBtn: activeTool === 'Note_RectangleRoi' && !isComparison, isNoted: isComparison }"
          @click="setToolActive('Note_RectangleRoi')">{{
            $t('DicomViewer:anonymous:Note_RectangleRoi') }}</div>
        <div :class="{ btn: true, activeBtn: activeTool === 'Eraser' && !isComparison, isNoted: isComparison }"
          @click="setToolActive('Eraser')">{{
            $t('DicomViewer:anonymous:Eraser') }}
        </div>
        <div :class="{ btn: true, isNoted: isComparison }" @click="anonymousImage(false)">{{
          $t('DicomViewer:anonymous:Application') }}</div>
        <!-- <div class="btn">刷新图像</div> -->
        <div class="btn" v-if="!isComparison" @click="comparison(true)">{{
          $t('DicomViewer:anonymous:Comparison') }}</div>
        <div class="btn" v-else @click="comparison(false)">{{
          $t('DicomViewer:anonymous:Exit') }}</div>
        <div :class="{ btn: true }" @click="recovery(false)">{{
          $t('DicomViewer:anonymous:Recovery') }}</div>
        <!-- <div :class="{ btn: true }" @click="recovery(true)">{{
          $t('DicomViewer:anonymous:RecoveryAll') }}</div> -->
      </div>
    </div>
    <!-- tools -->
    <div class="dicom-tools">
      <div class="measureTool-wrapper" v-if="hasAnonymous && hasPermi(['role:iqc'])">
        <div class="sideTool-title">{{ $t('DicomViewer:anonymous:PixelAnonymity') }}</div>
        <div class="sideTool-wrapper">
          <!-- <label>{{ $t('trials:reading:button:layout') }}:</label> -->
          <!-- <select class="sidetool-select" style="width:90px" :value="layout.replace('*', 'x')"
            @change="handleLayoutChange">
            <option value="1x1">1x1</option>
            <option value="1x2">1x2</option>
            <option value="2x1">2x1</option>
            <option value="2x2">2x2</option>
          </select> -->
          <div :class="{ btnBox: true, activeBtnBox: isAnonymous }" @click="openAnonymous">{{
            $t('DicomViewer:anonymous:PixelAnonymity')
          }}
          </div>
        </div>
      </div>
      <!-- 图像变换 -->
      <div class="measureTool-wrapper">
        <div class="sideTool-title">{{ $t('trials:dicom-show:transform') }}</div>
        <div class="sideTool-wrapper">
          <button :title="$t('trials:reading:button:zoom')"
            :class="{ 'btn-link': true, activeTool: activeTool === 'Zoom' }" data-tool="Zoom"
            @click="setToolActive('Zoom')">
            <svg-icon icon-class="magnifier" style="font-size:20px;" />
          </button>
          <button :title="$t('trials:reading:button:move')"
            :class="{ 'btn-link': true, activeTool: activeTool === 'Pan' }" data-tool="Pan"
            @click="setToolActive('Pan')">
            <svg-icon icon-class="move" style="font-size:20px;" />
          </button>
          <button :title="$t('trials:reading:button:rotate')"
            :class="{ 'btn-link': true, activeTool: activeTool === 'PlanarRotate' }" data-tool="PlanarRotate"
            @click="setToolActive('PlanarRotate')">
            <svg-icon icon-class="rotate" style="font-size:20px;" />
          </button>
          <button
            :title="isFitToWindowMode ? $t('trials:reading:button:fitImage') : $t('trials:reading:button:fitWindow')"
            class="btn-link" @click="toggleFitMode">
            <svg-icon v-if="isFitToWindowMode" icon-class="fitToImage" style="font-size:20px;" />
            <svg-icon v-else icon-class="fitToWindow" style="font-size:20px;" />
          </button>
          <button :title="$t('trials:reading:button:reset')" class="btn-link" @click="resetViewport">
            <svg-icon icon-class="refresh" style="font-size:20px;" />
          </button>
        </div>
      </div>
      <!-- 测量工具 -->
      <!-- <div class="measureTool-wrapper">
        <div class="sideTool-title">{{ $t('trials:dicom-show:measurementLabeling') }}</div>
        <div class="sideTool-wrapper">
          <button :title="$t('trials:reading:button:screenShot')" class="btn-link" @click="saveImage">
            <svg-icon icon-class="image" style="font-size:20px;" />
          </button>
          <button :title="$t('trials:reading:button:reset')" class="btn-link" @click="resetViewport">
            <svg-icon icon-class="refresh" style="font-size:20px;" />
          </button>
        </div>
      </div> -->
    </div>
  </div>
</template>
<script>

import {
  RenderingEngine,
  Enums,
  imageLoader,
  metaData,
  getRenderingEngine,
  eventTarget,
  utilities as csUtils
  // getEnabledElementByIds
} from '@cornerstonejs/core'

import * as cornerstoneTools from '@cornerstonejs/tools'
import LengthscaleTool from "@/views/trials/trials-panel/reading/visit-review/tools/LengthscaleTool"
import initLibraries from '@/views/trials/trials-panel/reading/dicoms/components/Fusion/js/initLibraries'
import hardcodedMetaDataProvider from '@/views/trials/trials-panel/reading/visit-review/js/hardcodedMetaDataProvider'
import registerWebImageLoader from '@/views/trials/trials-panel/reading/visit-review/js/registerWebImageLoader'
import Note_RectangleRoiTool from '@/views/trials/trials-panel/reading/dicoms3D/components/tools/Note_RectangleRoiTool'
import { noneDicomStudyMaskImage, noneDicomStudyUndoMaskImage } from "@/api/reading"
const { ViewportType } = Enums
const renderingEngineId = 'myRenderingEngine'
const {
  ToolGroupManager,
  Enums: csToolsEnums,
  StackScrollTool,
  PanTool,
  ZoomTool,
  PlanarRotateTool,
  ArrowAnnotateTool,
  RectangleROITool,
  PlanarFreehandROITool,
  SplineROITool,
  EraserTool,
  LengthTool,
  EllipticalROITool,
  CircleROITool,
  AngleTool,
  BidirectionalTool,
  // cursors
  annotation
} = cornerstoneTools
const newStyles = {
  global: {
    color: 'rgb(255, 0, 0)',
    colorHighlighted: 'rgb(0, 255, 0)',
    colorSelected: 'rgb(255, 0, 0)',
    colorLocked: 'rgb(255, 0, 0)',
    lineWidth: '1',
    lineDash: '',
    shadow: true,
    textBoxVisibility: true,
    textBoxFontFamily: 'Helvetica Neue, Helvetica, Arial, sans-serif',
    textBoxFontSize: '14px',
    textBoxColor: 'rgb(255, 0, 0)',
    textBoxColorHighlighted: 'rgb(0, 255, 0)',
    textBoxColorSelected: 'rgb(255, 0, 0)',
    textBoxColorLocked: 'rgb(255, 0, 0)',
    textBoxBackground: '',
    textBoxLinkLineWidth: '1',
    textBoxLinkLineDash: '2,3',
    textBoxShadow: true,
    markerSize: '10'
  }
}
cornerstoneTools.annotation.config.style.setDefaultToolStyles(newStyles)
const { MouseBindings, Events: toolsEvents } = csToolsEnums
export default {
  name: 'ImageViewer',
  data() {
    return {
      hasAnonymous: false,
      isAnonymous: false,
      isComparison: false,
      rows: 1,
      cols: 1,
      fullScreenIndex: null,
      imageIds: [],
      layout: '1*1',
      cellsMax: 4,
      activeTool: '',
      imageType: ['image/jpeg', 'image/jpg', 'image/bmp', 'image/png'],
      loading: false,
      isFitToWindowMode: true,
      trialId: null,
      activeName: '1',
      tools: [],
      viewportInfos: [],
      activeCanvasIndex: 0,
      serie: {},
      tip: [
        this.$t('DicomViewer:anonymous:after'),
        this.$t('DicomViewer:anonymous:before')
      ]
    }
  },
  computed: {
    gridStyle() {
      return {
        display: 'grid',
        gridTemplateRows: `repeat(${this.rows}, 1fr)`,
        gridTemplateColumns: `repeat(${this.cols}, 1fr)`,
        height: '100%',
        width: '100%'
      }
    },
    cellStyle() {
      return {
        border: '1px dashed #ccc',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center'
      }
    },
    cells() {
      return Array(this.rows * this.cols).fill(0)
    }
  },
  mounted() {
    // let type = this.$router.currentRoute.query.isQcCheck ? this.$router.currentRoute.query.type : ''
    this.hasAnonymous = this.$router.currentRoute.query.isQcCheck
    this.tools = config.customizeStandardsNoneDicom
    this.trialId = this.$route.query.trialId
    this.viewportInfos = Array.from({ length: this.cellsMax }, (_, index) => ({
      index: index,
      studyId: '',
      currentImageIdIndex: 0,
      viewportId: `canvas-${index}`,
      fileType: '',
      currentFileName: '',
      currentFilePath: '',
      imageIds: [],
      oldB: null,
      oldM: null,
      isMove: false,
      height: 0,
      zoomText: ''
    }))
    this.initLoader()
    this.$refs['viewports-wrapper'].addEventListener('wheel', (e) => {
      this.setToolsPassive()
    });
  },
  methods: {
    // 对比
    comparison(f) {
      this.setToolsPassive()
      if (f) {
        if (!this.serie.fileInfo.IsBeMark) return this.$confirm(this.$t("DicomViewer:anonymous:notMasked"))
        this.isComparison = f
        this.$emit("update:isComparison", this.isComparison)
        const toolGroup = ToolGroupManager.getToolGroup(`canvas-0`)
        toolGroup.setToolEnabled(StackScrollTool.toolName)
        this.handleLayoutChange({
          target: {
            value: `1x2`
          }
        })
        let path = this.serie.fileInfo.Path.split(".MaskNoneDicom_")[0]
        let imageIds = [`web:${this.OSSclientConfig.basePath}${path}`]
        let file = Object.assign({}, this.serie.fileInfo)
        file.Path = path
        file.FullFilePath = path
        this.viewportInfos[1] = Object.assign({}, this.viewportInfos[0])
        this.viewportInfos[1].fileList = [file]
        this.viewportInfos[1].imageIds = imageIds
        console.log(imageIds, 'imageIds')
        if (imageIds.length > 0) {
          this.renderImage(imageIds, 1, 0)
        }
      } else {
        this.isComparison = f
        this.$emit("update:isComparison", this.isComparison)
        const toolGroup = ToolGroupManager.getToolGroup(`canvas-0`)
        toolGroup.setToolActive(StackScrollTool.toolName, {
          bindings: [{ mouseButton: MouseBindings.Wheel }]
        })
        this.handleLayoutChange({
          target: {
            value: `1x1`
          }
        })
        this.activeCanvasIndex = 0
        this.$emit('toggleImage', {
          studyId: this.serie.studyId,
          path: this.serie.fileInfo.Path,
        })
      }
    },
    // 恢复
    async recovery() {
      // if (this.isComparison) return false
      if (!this.serie.fileInfo.IsBeMark) return this.$confirm(this.$t("DicomViewer:anonymous:notMasked"))
      if (this.isAnonymous) {
        this.comparison(false)
      }
      this.setToolsPassive()
      let data = {
        // NodicomStudyId: this.serie.studyId,
        NoneDicomStudyFileIdList: [
          this.serie.fileInfo.Id
        ],
      }
      let res = await this.noneDicomStudyUndoMaskImage(data)
      if (!res) return false
      let file = res.find(item => item.Id === this.serie.fileInfo.Id)
      this.$emit('replaceImage', {
        studyId: this.serie.studyId,
        path: this.serie.fileInfo.Path,
        file,
        IsBeMark: false
      })
    },
    // 应用
    async anonymousImage() {
      if (this.isComparison) return false
      this.setToolsPassive()
      const renderingEngine = getRenderingEngine(renderingEngineId)
      const viewport = renderingEngine.getViewport(`canvas-${this.activeCanvasIndex}`)
      let imageId = viewport.getCurrentImageId()
      console.log(imageId);
      let annotations = annotation.state.getAllAnnotations().filter(item => item.metadata.toolName === "Note_RectangleRoi" && item.metadata.referencedImageId === imageId)
      if (annotations.length <= 0) return false
      console.log(annotations)
      let data = {
        // NodicomStudyId: this.serie.studyId,
        NoneDicomStudyFileIdList: [
          this.serie.fileInfo.Id
        ],
        MaskRegionList: []
      }
      annotations.forEach(item => {
        let points = item.data.handles.points
        let currentStart = points[0]
        let currentEnd = points[3]
        let start = {
          x: currentStart[0] > currentEnd[0] ? Math.round(currentEnd[0]) : Math.round(currentStart[0]),
          y: currentStart[1] > currentEnd[1] ? Math.round(currentEnd[1]) : Math.round(currentStart[1]),
        }
        let end = {
          x: currentStart[0] > currentEnd[0] ? Math.round(currentStart[0]) : Math.round(currentEnd[0]),
          y: currentStart[1] > currentEnd[1] ? Math.round(currentStart[1]) : Math.round(currentEnd[1]),
        }
        let width = end.x - start.x
        let height = end.y - start.y
        data.MaskRegionList.push({
          X: start.x,
          Y: start.y,
          Width: width,
          Height: height
        })
      })
      let res = await this.noneDicomStudyMaskImage(data)
      if (!res || res.length <= 0) return this.$confirm(this.$t("DicomViewer:anonymous:studyMaskImageFail"))
      annotations.forEach(item => {
        annotation.state.removeAnnotation(item.annotationUID)
      })
      let file = res.find(item => item.Id === this.serie.fileInfo.Id)
      this.$emit('replaceImage', {
        studyId: this.serie.studyId,
        path: this.serie.fileInfo.Path,
        file,
        IsBeMark: true
      })
    },
    openAnonymous() {
      if (this.loading || this.isComparison) return false
      this.isAnonymous = !this.isAnonymous
      // if (!this.isAnonymous) {
      //   const elements = document.querySelectorAll('.dicom-item')
      //   const scope = this
      //   Array.from(elements).forEach((element, index) => {
      //     if (element.style.display !== 'none') {
      //       scope.$refs[`dicomCanvas${index}`].setToolPassive(scope.activeTool)
      //     }
      //   })
      //   scope.activeTool = null
      // } else {
      //   this.activateDicomCanvas(0)
      //   this.changeLayout('1x1')
      // }
    },
    async noneDicomStudyMaskImage(data) {
      try {
        this.loading = true
        let res = await noneDicomStudyMaskImage(data)
        this.loading = false
        if (res.IsSuccess) {
          return res.Result.OkList
        }
        return false
      } catch (err) {
        console.log(err)
        this.loading = false
        return false
      }
    },
    async noneDicomStudyUndoMaskImage(data) {
      try {
        this.loading = true
        let res = await noneDicomStudyUndoMaskImage(data)
        this.loading = false
        if (res.IsSuccess) {
          return res.Result.OkList
        }
        return false
      } catch (err) {
        console.log(err)
        this.loading = false
        return false
      }
    },
    showPanel(e) {
      e.currentTarget.firstChild.lastChild.style.display = 'block'
    },
    toolMouseout(e) {
      e.currentTarget.firstChild.lastChild.style.display = 'none'
    },
    // 初始化加载器
    async initLoader() {
      registerWebImageLoader(imageLoader)
      await initLibraries()

      let renderingEngine = getRenderingEngine(renderingEngineId)
      if (!renderingEngine) {
        renderingEngine = new RenderingEngine(renderingEngineId)
      }
      const resizeObserver = new ResizeObserver(() => {
        const renderingEngine = getRenderingEngine(renderingEngineId)
        if (renderingEngine) {
          renderingEngine.resize(true, false)
          this.$nextTick(() => {
            this.reapplyFitModeForVisibleViewports()
          })
        }
      })
      const element1 = this.$refs['canvas-0'][0]
      const element2 = this.$refs['canvas-1'][0]
      const element3 = this.$refs['canvas-2'][0]
      const element4 = this.$refs['canvas-3'][0]
      const elements = [
        element1,
        element2,
        element3,
        element4
      ]
      elements.forEach((element, i) => {
        element.oncontextmenu = (e) => e.preventDefault()
        resizeObserver.observe(element)
        element.addEventListener('CORNERSTONE_STACK_NEW_IMAGE', this.stackNewImage)
        element.addEventListener('CORNERSTONE_IMAGE_RENDERED', this.handleImageRendered)
      })
      const viewportInputArray = [
        {
          viewportId: 'canvas-0',
          type: ViewportType.STACK,
          element: element1
        },
        {
          viewportId: 'canvas-1',
          type: ViewportType.STACK,
          element: element2
        },
        {
          viewportId: 'canvas-2',
          type: ViewportType.STACK,
          element: element3
        },
        {
          viewportId: 'canvas-3',
          type: ViewportType.STACK,
          element: element4
        }
      ]
      const viewportIds = ['canvas-0', 'canvas-1', 'canvas-2', 'canvas-3']
      renderingEngine.setViewports(viewportInputArray)
      cornerstoneTools.addTool(StackScrollTool)
      cornerstoneTools.addTool(PanTool)
      cornerstoneTools.addTool(ZoomTool)
      cornerstoneTools.addTool(PlanarRotateTool)
      cornerstoneTools.addTool(ArrowAnnotateTool)
      cornerstoneTools.addTool(RectangleROITool)
      cornerstoneTools.addTool(EllipticalROITool)
      cornerstoneTools.addTool(CircleROITool)
      cornerstoneTools.addTool(AngleTool)
      cornerstoneTools.addTool(PlanarFreehandROITool)
      cornerstoneTools.addTool(SplineROITool)
      cornerstoneTools.addTool(EraserTool)
      cornerstoneTools.addTool(Note_RectangleRoiTool)
      cornerstoneTools.addTool(LengthTool)
      cornerstoneTools.addTool(LengthscaleTool)
      cornerstoneTools.addTool(BidirectionalTool)
      viewportIds.forEach((viewportId, i) => {
        const toolGroupId = `canvas-${i}`
        const toolGroup = ToolGroupManager.createToolGroup(toolGroupId)
        toolGroup.addViewport(viewportId, renderingEngineId)
        toolGroup.addTool(StackScrollTool.toolName)
        toolGroup.addTool(PanTool.toolName)
        toolGroup.addTool(ZoomTool.toolName)
        toolGroup.addTool(PlanarRotateTool.toolName)
        toolGroup.addTool(ArrowAnnotateTool.toolName)
        toolGroup.addTool(RectangleROITool.toolName)
        toolGroup.addTool(BidirectionalTool.toolName)
        toolGroup.addTool(EllipticalROITool.toolName)
        toolGroup.addTool(CircleROITool.toolName)
        toolGroup.addTool(AngleTool.toolName)
        toolGroup.addTool(PlanarFreehandROITool.toolName)
        toolGroup.addTool(SplineROITool.toolName)

        toolGroup.addTool(EraserTool.toolName)
        toolGroup.addTool(Note_RectangleRoiTool.toolName)
        toolGroup.addTool(LengthTool.toolName)
        toolGroup.addTool(LengthscaleTool.toolName)

        toolGroup.setToolActive(StackScrollTool.toolName, {
          bindings: [{ mouseButton: MouseBindings.Wheel }]
        })
        toolGroup.setToolPassive(PanTool.toolName)
        toolGroup.setToolPassive(ZoomTool.toolName)
        toolGroup.setToolPassive(PlanarRotateTool.toolName)
        toolGroup.setToolPassive(EraserTool.toolName)
        toolGroup.setToolPassive(Note_RectangleRoiTool.toolName)
      })
    },
    lengthscaleToolDisabled(saved) {
      const viewportIds = ['canvas-0', 'canvas-1', 'canvas-2', 'canvas-3']
      viewportIds.forEach(toolGroupId => {
        const toolGroup = ToolGroupManager.getToolGroup(toolGroupId)
        if (saved) {
          toolGroup.setToolPassive(LengthscaleTool.toolName)
        } else {
          toolGroup.setToolEnabled(LengthscaleTool.toolName)
        }
      })
    },
    // 加载图片回调
    stackNewImage(e) {
      if (this.isComparison) return false
      const { detail } = e
      const i = this.viewportInfos.findIndex(i => i.viewportId === detail.viewportId)
      if (i === -1) return
      if (detail.imageIdIndex !== this.viewportInfos[i].currentImageIdIndex) {
        this.viewportInfos[i].currentImageIdIndex = detail.imageIdIndex
        const obj = this.viewportInfos[i].fileList[detail.imageIdIndex]
        if (!obj) return
        this.viewportInfos[i].currentFileName = obj.FileName
        const total = this.viewportInfos[i].imageIds.length
        this.viewportInfos[i].height = total > 1 ? (this.viewportInfos[i].currentImageIdIndex) * 100 / (total - 1) : 0
        this.$emit('toggleImage', {
          studyId: this.viewportInfos[i].studyId,
          path: obj.Path
        })
        this.$nextTick(() => {
          this.applyFitMode(i, this.isFitToWindowMode)
        })
        return
      }
      this.updateZoomDisplayByViewportId(detail.viewportId)
    },
    handleImageRendered(e) {
      const viewportId = e?.detail?.viewportId || e?.currentTarget?.dataset?.viewportUid
      if (!viewportId) return
      this.updateZoomDisplayByViewportId(viewportId)
    },
    updateZoomDisplayByViewportId(viewportId) {
      const index = this.viewportInfos.findIndex(item => item.viewportId === viewportId)
      if (index === -1) return
      this.updateZoomDisplay(index)
    },
    updateZoomDisplay(index) {
      const viewportInfo = this.viewportInfos[index]
      if (!viewportInfo || !this.imageType.includes(viewportInfo.fileType) || !viewportInfo.imageIds.length) {
        if (viewportInfo) viewportInfo.zoomText = ''
        return
      }
      const renderingEngine = getRenderingEngine(renderingEngineId)
      const viewport = renderingEngine?.getViewport(viewportInfo.viewportId)
      if (!viewport) return
      const camera = viewport.getCamera?.()
      const canvas = viewport.getCanvas?.() || this.$refs[`canvas-${index}`]?.[0]
      const canvasHeight = canvas?.clientHeight
      const parallelScale = Number(camera?.parallelScale)
      if (!canvasHeight || !Number.isFinite(parallelScale) || parallelScale <= 0) {
        viewportInfo.zoomText = ''
        return
      }
      const magnification = canvasHeight / (parallelScale * 2)
      if (!Number.isFinite(magnification) || magnification <= 0) {
        viewportInfo.zoomText = ''
        return
      }
      viewportInfo.zoomText = `${magnification.toFixed(1)}x`
    },
    // 渲染图片
    async renderImage(imageIds, canvasIndex, sliceIndex) {
      metaData.addProvider((type, imageId) => hardcodedMetaDataProvider(type, imageId, imageIds), 10000)
      const renderingEngine = getRenderingEngine(renderingEngineId)
      const viewport = renderingEngine.getViewport(`canvas-${canvasIndex}`)
      await viewport.setStack(imageIds)
      this.setToolsPassive()
      viewport.setImageIdIndex(sliceIndex)
      viewport.render()
      this.$nextTick(() => {
        this.applyFitMode(canvasIndex, this.isFitToWindowMode)
        this.updateZoomDisplay(canvasIndex)
      })
      // this.updateViewportInfos()
    },
    setActiveCanvasImages(obj) {
      if (!obj || Object.keys(obj).length === 0) return
      this.serie = obj
      const i = this.viewportInfos.findIndex(i => i.index === this.activeCanvasIndex)
      if (i === -1) return
      if (obj.studyId === this.viewportInfos[i].studyId && this.imageType.includes(this.viewportInfos[i].fileType) && this.imageType.includes(obj.fileInfo.FileType) && !obj.isReset) {
        const fileIndex = this.viewportInfos[i].fileList.findIndex(i => i.Path === obj.fileInfo.Path)
        this.sliceIndex(fileIndex)
      } else {
        if (!this.imageType.includes(obj.fileInfo.FileType)) {
          this.fullScreenIndex = null
        }
        this.updateViewportInfos(this.activeCanvasIndex, obj)
      }
      this.setToolsPassive()
    },
    // 激活视图
    activeCanvas(index) {
      if (this.activeCanvasIndex === index) return
      const i = this.viewportInfos.findIndex(i => i.index === index)
      if (i === -1) return
      this.activeCanvasIndex = index
      this.setToolsPassive()
    },
    // 更新视图信息
    updateViewportInfos(index, obj) {
      const i = this.viewportInfos.findIndex(i => i.index === index)
      if (i === -1) return

      this.viewportInfos[i].taskInfo = obj.visitTaskInfo

      this.viewportInfos[i].currentFileName = obj.fileInfo.FileName
      this.viewportInfos[i].studyId = obj.studyId
      this.viewportInfos[i].fileType = obj.fileInfo.FileType
      if (this.imageType.includes(obj.fileInfo.FileType)) {
        const arr = obj.fileList.filter(i => this.imageType.includes(i.FileType))
        this.viewportInfos[i].fileList = arr
        const fileIndex = this.viewportInfos[i].fileList.findIndex(i => i.Path === obj.fileInfo.Path)
        this.viewportInfos[i].currentImageIdIndex = fileIndex
        const imageIds = []
        for (let i = 0; i < arr.length; i++) {
          const path = arr[i].Path
          imageIds.push(`web:${this.OSSclientConfig.basePath}${path}`)
        }
        this.viewportInfos[i].imageIds = imageIds
        if (imageIds.length > 0) {
          this.renderImage(imageIds, index, fileIndex)
        }
        this.$nextTick(() => {
          const renderingEngine = getRenderingEngine(renderingEngineId)
          if (renderingEngine) {
            renderingEngine.resize(true, false)
          }
        })
      } else {
        this.viewportInfos[i].currentFilePath = obj.fileInfo.Path
        this.viewportInfos[i].zoomText = ''
      }
    },
    // 切换图片
    sliceIndex(index) {
      const i = this.viewportInfos.findIndex(i => i.index === this.activeCanvasIndex)
      if (i === -1) return
      if (index < 0 || index >= this.viewportInfos[i].imageIds.length) return
      const renderingEngine = getRenderingEngine(renderingEngineId)
      const viewport = renderingEngine.getViewport(
        this.viewportInfos[i].viewportId
      )
      this.setToolsPassive()
      viewport.setImageIdIndex(index)
      viewport.render()
    },
    // 更改视图布局
    handleCommand(command) {
      this.fullScreenIndex = null
      this.layout = command
      this.rows = parseInt(command.split('*')[0])
      this.cols = parseInt(command.split('*')[1])
      if (this.rows === 1 && this.cols === 1) {
        this.$nextTick(() => {
          this.activeCanvas(0)
        })
      }
    },
    handleLayoutChange(event) {
      this.handleCommand(event.target.value.replace('x', '*'))
    },
    getCellStyle(index) {
      return {
        ...this.cellStyle,
        display: index < this.cells.length ? this.cellStyle.display : 'none'
      }
    },
    // 切换全屏
    toggleFullScreen(e, index) {
      const i = this.viewportInfos.findIndex(i => i.index === index)
      if (i === -1) return
      if (!this.viewportInfos[i].currentFileName) return
      if (this.imageType.includes(this.viewportInfos[i].fileType)) {
        this.fullScreenIndex = this.fullScreenIndex === index ? null : index
        this.activeCanvasIndex = index
      }
    },
    // 激活工具
    setToolActive(toolName) {
      const i = this.viewportInfos.findIndex(i => i.index === this.activeCanvasIndex)
      if (i === -1) return
      const toolGroupId = `canvas-${this.viewportInfos[i].index}`
      const toolGroup = ToolGroupManager.getToolGroup(toolGroupId)
      if (this.activeTool === toolName) {
        toolGroup.setToolPassive(this.activeTool)
        this.activeTool = ''
      } else {
        if (this.activeTool) {
          toolGroup.setToolPassive(this.activeTool)
        }
        toolGroup.setToolActive(toolName, {
          bindings: [{ mouseButton: MouseBindings.Primary }]
        })
        this.activeTool = toolName
      }
    },
    setToolsPassive() {
      if (!this.activeTool) return
      const toolGroupIds = ['canvas-0', 'canvas-1', 'canvas-2', 'canvas-3']
      toolGroupIds.forEach(toolGroupId => {
        const toolGroup = ToolGroupManager.getToolGroup(toolGroupId)
        toolGroup.setToolPassive(this.activeTool)
      })
      this.activeTool = ''
    },
    // 重置视图
    resetViewport() {
      this.setToolsPassive()
      const renderingEngine = getRenderingEngine(renderingEngineId)
      const viewportId = `canvas-${this.activeCanvasIndex}`
      const viewport = (renderingEngine.getViewport(viewportId))
      viewport.resetCamera({ resetPan: true, resetZoom: true, resetToCenter: true })
      renderingEngine.render()
      this.updateZoomDisplay(this.activeCanvasIndex)
    },
    toggleFitMode() {
      this.setToolsPassive()
      this.isFitToWindowMode = !this.isFitToWindowMode
      this.applyFitMode(this.activeCanvasIndex, this.isFitToWindowMode)
    },
    applyFitMode(canvasIndex = this.activeCanvasIndex, isFitToWindowMode = this.isFitToWindowMode) {
      const viewportInfo = this.viewportInfos[canvasIndex]
      if (!viewportInfo || !this.imageType.includes(viewportInfo.fileType) || !viewportInfo.imageIds.length) return
      const renderingEngine = getRenderingEngine(renderingEngineId)
      const viewport = renderingEngine?.getViewport(`canvas-${canvasIndex}`)
      if (!viewport) return

      viewport.resetCamera({ resetPan: true, resetZoom: true, resetToCenter: true })
      if (isFitToWindowMode) {
        viewport.render()
        return
      }

      const canvas = viewport.getCanvas() || this.$refs[`canvas-${canvasIndex}`]?.[0]
      const imageData = viewport.getImageData?.()?.imageData
      const dimensions = imageData?.getDimensions?.()
      const imageWidth = dimensions?.[0]
      const imageHeight = dimensions?.[1]
      const canvasWidth = canvas?.clientWidth
      const canvasHeight = canvas?.clientHeight

      if (!imageWidth || !imageHeight || !canvasWidth || !canvasHeight) {
        viewport.render()
        return
      }

      const fitScale = Math.min(canvasWidth / imageWidth, canvasHeight / imageHeight)
      if (fitScale > 0) {
        viewport.setZoom(1 / fitScale)
      }
      viewport.render()
      this.updateZoomDisplay(canvasIndex)
    },
    reapplyFitModeForVisibleViewports() {
      this.viewportInfos.forEach((viewportInfo, index) => {
        if (index >= this.cells.length) return
        if (!this.imageType.includes(viewportInfo.fileType) || !viewportInfo.imageIds.length) return
        this.applyFitMode(index, this.isFitToWindowMode)
      })
    },
    setZoomScale(isZoomIn) {
      this.setToolsPassive()
      const renderingEngine = getRenderingEngine(renderingEngineId)
      const viewportId = `canvas-${this.activeCanvasIndex}`
      const viewport = renderingEngine?.getViewport(viewportId)
      if (!viewport) return
      const camera = viewport.getCamera()
      const factor = 1.1
      const current = Number(camera.parallelScale)
      if (!Number.isFinite(current) || current <= 0) return
      const next = isZoomIn ? current / factor : current * factor
      const parallelScale = Math.max(0.0001, Math.min(1000000, next))
      viewport.setCamera({ parallelScale })
      viewport.render()
      this.updateZoomDisplay(this.activeCanvasIndex)
    },
    // 滚动条
    clickSlider(e, index) {
      const i = this.viewportInfos.findIndex(i => i.index === index)
      if (i === -1) return
      const sliderBox = this.$refs[`sliderBox-${index}`] && this.$refs[`sliderBox-${index}`][0]
      if (!sliderBox || !this.imageType.includes(this.viewportInfos[i].fileType)) return
      const boxHeight = sliderBox.clientHeight
      if (!boxHeight || !this.viewportInfos[i].imageIds.length) return
      const height = e.offsetY * 100 / boxHeight
      this.viewportInfos[i].height = height
      let sliceIdx = Math.trunc(this.viewportInfos[i].imageIds.length * height / 100)
      sliceIdx = sliceIdx >= this.viewportInfos[i].imageIds.length ? this.viewportInfos[i].imageIds.length - 1 : sliceIdx < 0 ? 0 : sliceIdx
      const renderingEngine = getRenderingEngine(renderingEngineId)
      const viewport = renderingEngine.getViewport(
        this.viewportInfos[i].viewportId
      )
      this.setToolsPassive()
      viewport.setImageIdIndex(sliceIdx)
      viewport.render()
      this.updateZoomDisplay(index)
    },
    sliderMouseup(e, index) {
      const i = this.viewportInfos.findIndex(i => i.index === index)
      if (i === -1 || !this.imageType.includes(this.viewportInfos[i].fileType)) return
      this.viewportInfos[i].isMove = false
    },
    sliderMousemove(e, index) {
      const i = this.viewportInfos.findIndex(i => i.index === index)
      if (i === -1 || !this.imageType.includes(this.viewportInfos[i].fileType)) return
      if (!this.viewportInfos[i].isMove) return
      const sliderBox = this.$refs[`sliderBox-${index}`] && this.$refs[`sliderBox-${index}`][0]
      if (!sliderBox || !this.viewportInfos[i].imageIds.length) return
      const delta = this.viewportInfos[i].oldB - (this.viewportInfos[i].oldM - e.clientY)
      const boxHeight = sliderBox.clientHeight
      if (delta < 0) return
      if (delta > boxHeight) return
      const height = delta * 100 / boxHeight
      let sliceIdx = Math.trunc(this.viewportInfos[i].imageIds.length * height / 100)
      sliceIdx = sliceIdx >= this.viewportInfos[i].imageIds.length ? this.viewportInfos[i].imageIds.length - 1 : sliceIdx < 0 ? 0 : sliceIdx
      this.viewportInfos[i].height = height
      // if (this.viewportInfos[i].currentImageIdIndex !== i) {
      const renderingEngine = getRenderingEngine(renderingEngineId)
      const viewport = renderingEngine.getViewport(
        this.viewportInfos[i].viewportId
      )
      this.setToolsPassive()
      viewport.setImageIdIndex(sliceIdx)
      viewport.render()
      this.updateZoomDisplay(index)
      // }
      // this.$emit('toggleImage', { taskId: this.viewportInfos[i].taskInfo.VisitTaskId, studyId: this.viewportInfos[i].studyId, imageIndex: sliceIdx })
    },
    sliderMouseleave(e, index) {
      const i = this.viewportInfos.findIndex(i => i.index === index)
      if (i === -1 || !this.imageType.includes(this.viewportInfos[i].fileType)) return
      if (!this.viewportInfos[i].isMove) return
      this.viewportInfos[i].isMove = false
    },
    sliderMousedown(e, index) {
      const i = this.viewportInfos.findIndex(i => i.index === index)
      if (i === -1 || !this.imageType.includes(this.viewportInfos[i].fileType)) return
      const sliderBox = this.$refs[`sliderBox-${index}`] && this.$refs[`sliderBox-${index}`][0]
      if (!sliderBox || !this.viewportInfos[i].imageIds.length) return
      const boxHeight = sliderBox.clientHeight
      const sliderTop = parseFloat(e.currentTarget.style.top) || 0
      this.viewportInfos[i].oldB = sliderTop * boxHeight / 100
      this.viewportInfos[i].oldM = e.clientY
      this.viewportInfos[i].isMove = true
      e.stopImmediatePropagation()
      e.stopPropagation()
      e.preventDefault()
    }
  }
}
</script>
<style lang="scss" scoped>
.content {
  cursor: default !important;
}

.dropdown {
  position: relative;
  display: inline-block;

  .text {
    text-align: center;
  }
}

.dropdown-content {
  display: none;
  position: absolute;
  background-color: #383838;
  color: #fff;
  box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
  z-index: 9999;
  font-size: 12px;

  ul {
    list-style: none;
    margin: 0;
    padding: 0;
    text-align: center;

    li {
      a {
        display: block;
        padding: 5px;
      }
    }
  }

  ul li a:hover {
    background-color: #727272;
  }

  .customize-standards-list {
    width: max-content;
    white-space: nowrap;

    li a {
      display: flex;
      align-items: center;
      padding: 8px !important;
      box-sizing: border-box;
    }
  }
}

.none-dicom-viewer {
  display: flex;
  flex-direction: row;
  width: 100%;
  height: 100%;
  user-select: none;
  background: #000;

  .dicom-tools {
    width: 300px;
    height: 100%;
    background-color: #323232;
    margin: 0 0 0 2px;
    padding: 0;
    color: #d0d0d0;
    font-size: 13px;
    overflow-y: auto;
  }

  .sideTool-title {
    padding: 5px 8px;
    background-color: #525252;
    color: #bebdbd;
    font-size: 14px;
    margin: 4px;
  }

  .sideTool-wrapper {
    border-bottom: 1px solid gray;
    margin: 0 4px;
    padding: 4px;
    font-size: 12px;
  }

  .sidetool-select {
    height: 30px;
    background-color: rgba(0, 0, 0, 0);
    color: #d0d0d0;
    border-radius: 4px;
    border: 1px solid #5b5b5b;
  }

  .sidetool-select>option {
    background-color: #323232;
  }

  .sideTool-wrapper button.btn-link {
    height: 40px;
    padding: 8px !important;
    border: 1px solid rgba(37, 37, 37, 1);
    margin: 1px 1px;
  }

  .sideTool-wrapper .btn-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 40px;
    color: #cccccc;
    background-color: transparent;
    cursor: pointer;
  }

  .activeTool {
    background: #16477b90 !important;
    border: none !important;
  }

  .sideTool-wrapper label {
    display: inline-block;
    min-width: 44px;
    margin-right: 6px;
  }

  .viewports-wrapper {
    flex: 1;
    min-width: 0;
    position: relative;

    .grid-container {
      display: grid;
      height: 100%;
      width: 100%;
      position: relative;
    }

    .grid-cell {
      border: 1px dashed #ccc;
      display: flex;
      align-items: center;
      justify-content: center;
      overflow: hidden;
      min-width: 0;
      min-height: 0;
      z-index: 1;
    }

    .cell_active {
      border-color: #fafa00 !important;
    }

    .cell-full-screen {
      grid-column: 1 / -1;
      grid-row: 1 / -1;
    }

    .flex_col {
      display: flex;
      flex-direction: column;
    }

    .content {
      width: 100%;
      height: 100%;
      position: relative;

      .left-top-text {
        position: absolute;
        left: 5px;
        top: 5px;
        color: #ddd;
        z-index: 1;
        font-size: 14px;

        .cd-info {
          color: #ddd;
          font-size: 18px;
        }

        .subject-info {
          color: #f44336;
          padding: 5px 0px;
          margin: 0;
        }
      }

      .left-bottom-text {
        position: absolute;
        left: 5px;
        bottom: 5px;
        color: #ddd;
        z-index: 1;
        font-size: 14px;
      }

      .top-center-tool {
        position: absolute;
        left: 50%;
        top: 5px;
        transform: translateX(-50%);
        z-index: 1;

        .toggle-visit-container {
          display: flex;
        }

        .arrw_icon {
          width: 20px;
          height: 20px;
          background-color: #3f3f3f;
          text-align: center;
          line-height: 20px;
          border-radius: 10%;
        }

        .arrow_text {
          height: 20px;
          line-height: 20px;
          background-color: #00000057;
          color: #fff;
          padding: 0 10px;
          font-size: 14px;
        }
      }

      .right-slider-box {
        position: absolute;
        right: 1px;
        height: calc(100% - 140px);
        transform: translateY(-50%);
        top: calc(50% - 30px);
        width: 10px;
        background: #333;
        z-index: 1;
        cursor: pointer;
      }

      .right-slider-box:after {
        content: '';
        position: absolute;
        bottom: -20px;
        left: 0;
        height: 20px;
        width: 100%;
        background: #333;
      }

      .slider {
        height: 20px;
        width: 100%;
        position: absolute;
        top: 0;
        z-index: 10;
        background: #9e9e9e;
        cursor: move
      }

      .content-main {
        position: relative;
        overflow: hidden;
        background: #1e1e1e;
      }

      video {
        display: block;
        width: 100%;
        height: 100%;
        object-fit: contain;
        object-position: center center;
        background: transparent;
      }
    }
  }
}

.Anonymous {
  position: absolute;
  border-radius: 5px;
  bottom: 30px;
  left: 5%;
  right: 5%;
  width: 90%;
  height: 60px;
  padding: 0 10px;
  background-color: rgba(255, 255, 255, .2);
  display: flex;
  align-items: center;
  justify-content: space-between;
  z-index: 2000;

  .btn {
    width: 12%;
    text-align: center;
    height: 40px;
    line-height: 30px;
    border-radius: 15px;
    cursor: pointer;
    padding: 5px 10px;
    color: #428bca;
    background: #ecf3fa;
    border-color: #b3d1ea;
  }

  .activeBtn {
    background: #428bca;
    border-color: #428bca;
    color: #fff;
  }

  .isNoted {
    cursor: not-allowed;
  }

  // &:hover {
  //   background-color: rgba(255, 255, 255, .5);
  // }
}




.dicom-tools .btnBox {
  display: inline-block;
  width: 80px;
  text-align: center;
  height: 30px;
  line-height: 20px;
  border-radius: 15px;
  color: #428bca;
  background: #ecf3fa;
  border-color: #b3d1ea;
  cursor: pointer;
  padding: 5px 10px;
  border: 1px solid rgba(255, 255, 255, .7);
  margin: 5px;
}

.dicom-tools .activeBtnBox {
  background: #428bca;
  border-color: #428bca;
  color: #fff;
}
</style>
