<template>
  
  <div
    class="thumbnails"
    @mousedown="() => setThumbnailsFocus(true)"
    v-click-outside="() => setThumbnailsFocus(false)"
    v-contextmenu="contextmenusThumbnails"
  >
    <div class="add-slide" v-if="queryObj.TemplateType!=2">
        <div class="btn" @click="createSlide()"><IconPlus class="icon" />添加幻灯片</div>
        <Popover trigger="click" placement="bottom-start" v-model:value="presetLayoutPopoverVisible" center>
          <template #content>
            <LayoutPool @select="slide => { createSlideByTemplate(slide); presetLayoutPopoverVisible = false }" />
          </template>
          <div class="select-btn" v-if="layoutSlides.length>0"><IconDown /></div>
        </Popover>
    </div>

    <Draggable 
      class="thumbnail-list"
      ref="thumbnailsRef"
      :modelValue="slides"
      :animation="200"
      :scroll="true"
      :scrollSensitivity="50"
      @end="handleDragEnd"
      itemKey="id"
    >
      <template #item="{ element, index }">
        <div
          class="thumbnail-item"
          :class="{
            'active': slideIndex === index,
            'selected': selectedSlidesIndex.includes(index),
          }"
          @mousedown="$event => handleClickSlideThumbnail($event, index)"
          @dblclick="enterScreening()"
          v-contextmenu="contextmenusThumbnailItem"
        >
          <div class="label" :class="{ 'offset-left': index >= 99 }">{{ fillDigit(index + 1, 2) }}</div>
          <ThumbnailSlide class="thumbnail" :slide="element" :size="120" :visible="index < slidesLoadLimit" />
        </div>
      </template>
    </Draggable>

    <div class="page-number">幻灯片 {{slideIndex + 1}} / {{slides.length}}</div>
  </div>
  <div style="position: fixed;left: 200px;top: -100px;opacity: 0;">
      <canvas style="display: none" id="canvas"></canvas>
      <div
         id="extract-color-id"
         class="extract-color"
         style="display: flex;padding: 0 20px; justify-content:end;">
      </div>
  </div>
</template>

<script lang="ts" setup>
import { computed, nextTick, ref, reactive, watch, inject,onMounted } from 'vue'
import { storeToRefs } from 'pinia'
import { useMainStore, useSlidesStore, useKeyboardStore, useScreenStore, useSellTemplateStore } from '@/store'
import { fillDigit } from '@/utils/common'
import { isElementInViewport } from '@/utils/element'
import type { ContextmenuItem } from '@/components/Contextmenu/types'
import useSlideHandler from '@/hooks/useSlideHandler'
import useScreening from '@/hooks/useScreening'
import useLoadSlides from '@/hooks/useLoadSlides'
import { injectKeyDataSource, injectKeyTemplate } from '@/types/injectKey'
import ConfigService from '@/services/ConfigService'
import { getHtmlPlainText, query, getRgbLevel } from '@/utils/common'
import useEditor from '@/utils/Editor/index'
import { VIEWPORT_SIZE, VIEWPORT_VER_SIZE } from '@/configs/canvas'
import { ToolbarStates } from '@/types/toolbar'

import ThumbnailSlide from '@/views/components/ThumbnailSlide/index.vue'
import LayoutPool from './LayoutPool.vue'
import Popover from '@/components/Popover.vue'
import Draggable from 'vuedraggable'
import { ElLoading, ElMessageBox, ElMessage } from 'element-plus'
import FileService from '@/services/FileService'
import { Slide } from '@/types/slides'
import { uniqueId } from 'lodash'
import { useUserStore } from "@/store";
import themeColor from '@/utils/colorExtraction';
import HtmlUtil from '@/utils/htmlutil'

const mainStore = useMainStore()
const slidesStore = useSlidesStore()
const layoutsStore = useSlidesStore()
const keyboardStore = useKeyboardStore()
const { selectedSlidesIndex: _selectedSlidesIndex, thumbnailsFocus } = storeToRefs(mainStore)
const { slides, currentSlide, slideIndex, layoutSlides, viewportRatio } = storeToRefs(slidesStore)
const { ctrlKeyState, shiftKeyState } = storeToRefs(keyboardStore)
const { SalesEditor, SalesBack, SalesTripId } = storeToRefs(useSellTemplateStore())
const { userInfo } = storeToRefs(useUserStore())

const { slidesLoadLimit } = useLoadSlides()
const TemplateTypeStore = useScreenStore()
const CoverImgStore = useScreenStore()
const dataLoadingStore = useScreenStore()
const { model, ConfigId, TemplateDataSource, TemplateType, dataLoading, TempId, SourceLoading } = storeToRefs(TemplateTypeStore)

const selectedSlidesIndex = computed(() => [..._selectedSlidesIndex.value, slideIndex.value])
const { setNewDatasList } = useEditor()

const presetLayoutPopoverVisible = ref(false)

const {
  copySlide,
  pasteSlide,
  createSlide,
  createSlideByTemplate,
  copyAndPasteSlide,
  deleteSlide,
  cutSlide,
  selectAllSlide,
  sortSlides,
} = useSlideHandler()

const datas = reactive({
  DataSource:{}
})
const queryObj = ref({} as any)
const searchData = ref({} as any)
datas.DataSource = inject(injectKeyDataSource)
searchData.value = inject(injectKeyTemplate)

const acquiesceLogo = ref([
  'https://im.oytour.com/pptist/static/logo1.png',
  'https://im.oytour.com/pptist/static/logo2.png',
  'https://im.oytour.com/pptist/static/logo3.png',
  'https://im.oytour.com/pptist/static/logo4.png',
  'https://im.oytour.com/pptist/static/logo5.png',
  'https://im.oytour.com/pptist/static/logo6.png',
  'https://im.oytour.com/pptist/static/logo7.png',
])

const tempDatas = ({} as any)
const colorList = ref([] as any)
watch(() => slideIndex.value, () => {
  // 清除多选状态的幻灯片
  if (selectedSlidesIndex.value.length) {
    mainStore.updateSelectedSlidesIndex([])
  }

  // 检查当前页缩略图是否在可视范围，不在的话需要滚动到对应的位置
  nextTick(() => {
    const activeThumbnailRef: HTMLElement = thumbnailsRef.value?.$el?.querySelector('.thumbnail-item.active')
    if (thumbnailsRef.value && activeThumbnailRef && !isElementInViewport(activeThumbnailRef, thumbnailsRef.value.$el)) {
      setTimeout(() => {
        activeThumbnailRef.scrollIntoView({ behavior: 'smooth' })
      }, 100)
    }
  })
})

// 监听请求保存成功 重新请求数据 1模版
watch(() => dataLoading.value, (n,o) =>{
  if(searchData.value.sellId) sellGetTripTemplate()
  else{
    if(dataLoading.value==1){
      GetTripTemplate()
    }else if(dataLoading.value==2){
      if(ConfigId.value) GetTripConfig()
    }
  }
})


queryObj.value = inject(injectKeyDataSource).queryObj

/**
 * 行程保存成功获取行程详情
 */
 const GetTripConfig = async () =>{
  try {
      let queryMsg = {
          ConfigId: ConfigId.value
      }
      let datasRes = await ConfigService.triptemplateGetTripConfig(queryMsg);
      if (datasRes.data.resultCode == 1 && datasRes.data.data && datasRes.data.data.TempId) {
        let dataObj = datasRes.data.data
        let SlidesData = JSON.parse(dataObj.TempData)
        let newSlides = []
        await SlidesData.forEach((x,i)=>{
          newSlides.push(x)
        })
        slidesStore.setSlides(newSlides)
      }
  } catch (error) {
      
  }
}

// 获取行程团数据初始化数据
const GetTripFiledData = async () =>{
  const loadingObj = ElLoading.service({
    text:'正在渲染团队数据',
    lock:true
  })
  
  const slidesData = slides.value
  try {
      let queryMsg = {
        ConfigId: ConfigId.value
      }
      let dataRes = await ConfigService.triptemplateGetTripFiledData(queryMsg);
      if (dataRes.data.resultCode == 1) {
        if(!dataRes.data.data) {
          loadingObj.close()
          return
        }
        datas.DataSource.TravelAatas = dataRes.data.data
        if(TempId.value&&!searchData.value.TempId) {
          loadingObj.close()
          return
        }
        let isHideOverflowText = false
        try {
          await ElMessageBox.confirm('行程数据可能会超出模板预设宽度或高度，是否自动裁剪','提示',{
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
            closeOnClickModal:false
          })
          isHideOverflowText = true
        } catch (error) {}
        // let maxWidth = VIEWPORT_SIZE,maxHeight = VIEWPORT_VER_SIZE.Value, viewportRatios = slidesStore.viewportRatio
        // if(viewportRatio<1){
        //   maxWidth = VIEWPORT_VER_SIZE.Value
        //   maxHeight = VIEWPORT_SIZE.Value
        // }
        const travel = dataRes.data.data
        const cursors = [] as Array<any>
        for (let index = 0; index < slidesData.length; index++) {
          const x = slidesData[index] as any;
          let eles = x.elements.filter(y=>y.groupId && y.groupId=='first_row')
          if(eles.length>0){
            x.elements = x.elements.filter(y=>!y.groupId || y.groupId!='first_row')
            let newElements = ResolveTripDaysHandler(eles,index)
            x.elements = x.elements.concat(newElements?.elements)
            if(newElements?.newSlider){
              slidesData.splice(index+1,0,newElements.newSlider)
            }
          }
          for (let j = 0; j < x.elements.length; j++) {
            let y = x.elements[j]
            if(y.TemplateDataSource && y.TemplateDataSource.Content){
                let dataPath = y.TemplateDataSource.Content.split('.')
                let value=JSON.parse(JSON.stringify(travel));
                let parentData:any = null
                for (let i = 0; i < dataPath.length; i++) {
                  const oo = dataPath[i];
                  if(value && value[oo]){
                    if(i==0 && Array.isArray(value[oo])){
                      let temp = cursors.find(item=>item.key==oo)
                      if(temp){
                        temp.index++
                      }else{
                        temp={key:oo,index:0}
                        cursors.push(temp)
                      }
                      if(y.TemplateDataSource.index!=null&&y.TemplateDataSource.index>=0){
                        value=value[oo][y.TemplateDataSource.index]
                      }else{
                        if(value[oo].length>temp.index) value=value[oo][temp.index]
                        else value=value[oo]
                      }
                    }else{
                      value=value[oo]
                    }
                    if(i<dataPath.length-1) parentData = value
                  }else{
                    value = null
                  }
                }
                if(value && typeof(value) == 'string'){
                  //替换
                  if(isHideOverflowText){
                    const maxLength = getHtmlPlainText(y.content).length
                    const newValue = maxLength<value.length?value.substring(0,maxLength):value
                    y.content= y.content.replace(getHtmlPlainText(y.content),newValue)
                  }else{
                    y.content= y.content.replace(getHtmlPlainText(y.content),value)
                  }
                  
                }else if(value && Array.isArray(value)){
                  //替换
                  if(y.type=='image'&&value[0]!=''){
                    try {
                      // let width = y.width
                      // let height = y.height
                      let tempSize = await FileService.convertNetworkToBase64Async(value[0])//await FileService.getImageSizeWithoutDownloading(value[0])
                      let width = 0
                      let height =  0
                      //按照宽度进行缩放
                      let ratio = tempSize.width / y.width
                      width = y.width
                      height = tempSize.height / ratio

                      if(height<y.height){
                          ratio = height / y.height
                          height =  y.height
                          width = width / ratio
                          y.left -= Math.ceil((width - y.width)/2)
                      }else{
                          y.top = Math.ceil((height - y.height)/2)
                      }
                      y.height = height
                      y.width = width
                      
                      y.fixedRatio = true
                    } catch (error) {
                      y.fixedRatio = false
                    }
                    y.src = value[0]
                    
                  } 
                }
                y.below = y.TemplateDataSource.index!=null && y.TemplateDataSource.index>=0 ? y.TemplateDataSource.index:-1
                if(parentData && parentData.Id) {
                  y.dataMapping = {
                    id:parentData.Id,
                    filed:dataPath[dataPath.length-1]
                  }
                }
              }
          }
        }
        slidesStore.setSlides(slidesData)
      }
  } catch (error) {
  }
  loadingObj.close()
}

const ResolveTripDaysHandler = (items:any, slideIndex:number)=>{
  let elements = []
  if(items.length>0){
    let topList = items.map(item=>{ return item.top })
    let heightList = items.map(item=>{ return item.height })
    let tempNewSlide:any = null //JSON.parse(JSON.stringify(slides.value[slideIndex]))
    let formBg:any = slides.value[slideIndex].elements.find(x=>x.layerName &&x.layerName=='form_bg')
    let maxTop = formBg?(formBg.top+formBg.height):-1
    let max=Math.max.apply(null,topList);
    let min=Math.min.apply(null,topList);
    let maxh = Math.max.apply(null,heightList)
    let mutils = max-min
    let elementsHeight = maxh>mutils?maxh:mutils;

    let value=datas.DataSource.TravelAatas.simpleTripInfo;
    let baseIndex = 0
    for(let i=0;i<value.length;i++){
      let templateObj = JSON.parse(JSON.stringify(items))
      let currentTop = elementsHeight*baseIndex
      for(let k=0;k<templateObj.length;k++){
        const oo = templateObj[k].layerName;
        let valueData
        if(oo=='day') valueData = value[i]['DayNum']
        if(oo=='title') valueData = value[i]['Title']
        if(oo=='hotel') valueData = '宿：'+value[i]['Hotel']
        if(oo=='dinner') valueData = '餐：'+value[i]['Zao']+'/'+value[i]['Wu']+'/'+value[i]['Wan']
        if(oo=='dinner_hotel') valueData = '餐：'+value[i]['Zao']+'/'+value[i]['Wu']+'/'+value[i]['Wan']+' 宿：'+value[i]['Hotel']
        templateObj[k].top += currentTop
        templateObj[k].groupId +="_"+i.toString()
        templateObj[k].id +="_"+i.toString()+"_"+k.toString()
        if(valueData){
          let txt = getHtmlPlainText(templateObj[k].content)
          if(oo=='day') valueData = txt.replace(/[0-9]/ig,valueData)
          
          templateObj[k].content = templateObj[k].content.replace(txt,valueData)
        }
      }
      if(tempNewSlide){
        tempNewSlide.elements.push(...templateObj)
      }else{
        elements.push(...templateObj)
        if((currentTop+elementsHeight*2+min)>maxTop){
          tempNewSlide = copySlidHandler(slideIndex)
          baseIndex = -1
        }
      }
      baseIndex++
    }

    return {
      elements,
      newSlider:tempNewSlide
    }
  }
}

const copySlidHandler = (slideIndex:number)=>{
  let newSlide = JSON.parse(JSON.stringify(slides.value[slideIndex]))
  newSlide.id = uniqueId()
  newSlide.elements = newSlide.elements.filter((y:any)=>!y.groupId || y.groupId!='first_row')
  return newSlide
}

// 获取行程模版数据
const GetTripTemplate = async () =>{
  const loadingObj = ElLoading.service({
    text:'正在渲染模版数据',
    lock:true
  })
  if(!searchData.value.TempId&&!searchData.value.TempId2&&!TempId.value&&!searchData.value.sellTempId&&searchData.value.ViewSlideshow) {
    let list = [
      {
        id: 'test-slide-1',
        pageType: searchData.value.TemplateType!=2?1:0,
        elements: [],
        background: {
          type: 'solid',
          color: '#ffffff',
        },
      }
    ]
    let Title = '模版名称'
    if(searchData.value.TemplateType==2) Title = '广告名称'
    slidesStore.setTitle(Title)
    loadingObj.close()
    return slidesStore.setSlides(list)
  }
  try {
      let queryMsg = {
        TempId: 0
      } 
      if(searchData.value.TempId) queryMsg.TempId = searchData.value.TempId
      else if(searchData.value.TempId2&&!searchData.value.TempId) queryMsg.TempId = searchData.value.TempId2
      else if(searchData.value.sellTempId) queryMsg.TempId = searchData.value.sellTempId
      else if(TempId.value) queryMsg.TempId = TempId.value
      let dataRes = await ConfigService.GetTripTemplateSlide(queryMsg);
      if (dataRes.data.resultCode == 1) {
        colorList.value = []
        tempDatas.value = dataRes.data.data

        for(let i=0;i<tempDatas.value.PageImageList.length;i++){
          const img = new Image();
          img.src = `${tempDatas.value.PageImageList[i]}`;
          img.crossOrigin = 'anonymous';
          img.onload = () => {
            themeColor(1, img, 20, SetColor);
          };
        }
        if(SalesBack.value==0||(SalesBack.value==1&&searchData.value.TempId)){
          let viewportRatios = 0
          if(dataRes.data.data.TemplateType!=2) {
            viewportRatios = 1.414
            if(dataRes.data.data.TempType==1) viewportRatios = 0.7069
          }
          if(dataRes.data.data.TemplateType==2&&dataRes.data.data.Width&&dataRes.data.data.Height) {
            viewportRatios = dataRes.data.data.Height/dataRes.data.data.Width
            queryObj.value.Width = dataRes.data.data.Width
            queryObj.value.Height = dataRes.data.data.Height
          }
          slidesStore.setViewportRatio(viewportRatios)

          let SlidesData = JSON.parse(dataRes.data.data.TempData)
          let newSlides = []
          if(typeof SlidesData=='object'&&!SlidesData.length){
            SlidesData.pageType = searchData.value.TemplateType!=2?1:0
            let obj = {
              ...SlidesData
            }
            newSlides.push(obj)          
          }else if(SlidesData.length>0){
            SlidesData.forEach((x: any) => {
              x.elements.forEach((y:any)=>{
                if(y.content && y.defaultFontName && y.defaultFontName.includes(',')) y.defaultFontName = y.defaultFontName.split(',')[0]
                if(y.contentStr && y.content && y.content.includes(y.contentStr)){
                  let temp = HtmlUtil.htmlEncodeByRegExp(y.contentStr)
                  if(temp!=y.contentStr) {
                    y.content = y.content.replace(y.contentStr,temp)
                  }
                }
              })
            })
            newSlides = SlidesData
          }
          let IDs = []
          for(let i=0;i<newSlides.length;i++){
            let ids = newSlides[i].id.split('-')
            let existId = IDs.findIndex(y=>{ y==newSlides[i].id }) == -1
            if(existId) IDs.push(newSlides[i].id)
            else {
              //Math.floor(Math.random() * newSlides.length)
              //Math.floor(Math.random())+i
              let id = generateUniqueId()
              x.id = `${ids[0]}-${ids[1]}${id}`
            }
            newSlides[i].elements.forEach(y=>{
              if(newSlides[i].pageType!=1&&y.TemplateDataSource&&y.TemplateDataSource.index==null){
                Reflect.set(y.TemplateDataSource, 'index', null)
              }
            })
          }

          if(ConfigId.value>0){
            newSlides = newSlides.filter((x:Slide)=>!x.isTripItems)
          }
          
          getColorShade(newSlides)
        }

        queryObj.value.TempId = dataRes.data.data.TempId
        queryObj.value.LineId = dataRes.data.data.LineId
        queryObj.value.LineName = dataRes.data.data.LineName
        queryObj.value.LtId = dataRes.data.data.LtId
        
        queryObj.value.TempData = dataRes.data.data.TempData
        queryObj.value.CoverImg = dataRes.data.data.CoverImg
        queryObj.value.CountryName = dataRes.data.data.CountryName
        queryObj.value.SeasonName = dataRes.data.data.SeasonName
        queryObj.value.ColorName = dataRes.data.data.ColorName
        queryObj.value.ColorStr = dataRes.data.data.ColorStr
        queryObj.value.TempType = dataRes.data.data.TempType
        queryObj.value.TemplateType = dataRes.data.data.TemplateType
        queryObj.value.AuthType = dataRes.data.data.AuthType
        
        if(queryObj.value.Width){
          VIEWPORT_SIZE.Value = queryObj.value.Height
          VIEWPORT_VER_SIZE.Value = queryObj.value.Width
        }else {
          VIEWPORT_SIZE.Value = 1754
          VIEWPORT_VER_SIZE.Value = 1240
        }
        // if(searchData.value.isTeamManage) mainStore.setToolbarState(ToolbarStates.EL_TEMPLATEDATA)
        setTimeout(()=>{
          loadingObj.close()
        },300)
        if(ConfigId.value==0) return 
        if(TempId.value&&!searchData.value.TempId) await GetTripConfig()
        if(model.value!=3) await GetTripFiledData()
      }else{
        loadingObj.close()
      }
  } catch (error) {
    loadingObj.close()
  }
}

const generateUniqueId = () => {
    const timestamp = new Date().getTime()
    const randomNum = Math.floor(Math.random() * 1000)
    return '-' + timestamp + '-' + randomNum
}

// 获取是否深色
const getColorShade = async (newSlides:any) => {
  let dark = false
  let day = 0
  // 根据集团渲染logo 
  if(tempDatas.value.GId!=userInfo.value.gid&&!searchData.value.isTeamManage){
    for(let j=0;j<colorList.value.length;j++){
      if (getRgbLevel(colorList.value[j].Color) > 50) dark = true
    }
    for(let i=0;i<newSlides.length;i++){
      day = 0
      if(i>colorList.value.length-2) {
        dark = false
      }
      let x = newSlides[i]
      let eles = x.elements.filter(y=>y.layerName && y.layerName.indexOf('logo')!=-1)
      let layerNames =  x.elements.filter(z=>{
        if(z.layerName&&z.layerName.indexOf('DAY')!=-1) return z
      })
      day = layerNames&&layerNames.length>0?1:0
      let newElementsImg = await ResolveTripLogoHandler(eles,i,dark,day)
      let newElements = []
      x.elements.forEach(y=>{
        if(newElementsImg?.elements){
          newElementsImg?.elements.forEach(z=>{
            if(y.id==z.id) y = JSON.parse(JSON.stringify(z))
          })
        }
        newElements.push(y)
      })
      x.elements = newElements
    }
  }
  if(searchData.value.isTeamManage){
    for(let i=0;i<newSlides.length;i++){
      for(let j=0;j<newSlides[i].elements.length;j++){
        if(newSlides[i].elements[j].layerName&&newSlides[i].elements[j].layerName.indexOf('logo')!=-1) newSlides[i].elements[j].lock = false
      }
    }
  }
  layoutsStore.setLayouts(JSON.parse(JSON.stringify(newSlides)))
  if(searchData.value.sellId&&!searchData.value.TempId) return
  slidesStore.setSlides(newSlides)
  
  CoverImgStore.setCoverImg(tempDatas.value.CoverImg)
  slidesStore.updateSlideIndex(0)
  datas.DataSource.pageType = newSlides[0].pageType
  if(SalesBack.value==0) slidesStore.setTitle(tempDatas.value.Title)
}

// 替换logo
const ResolveTripLogoHandler = async (items:any, slideIndex:number,dark:false,day:Number) =>{
    let elements = []
    let tempNewSlide:any = null
    let templateObj = JSON.parse(JSON.stringify(items))
    for(let i=0;i<templateObj.length;i++){
      try {
          let Colors = templateObj[i].layerName.split(',')
          let y = templateObj[i]
          let tempSize = await FileService.getImageSizeWithoutDownloading(templateObj[i].src)
          let scale = parseInt(y.width/y.height)
          let url = ''
          console.log()
          if(scale>=1&&scale<3&&!day) url = dark==true?acquiesceLogo.value[0]:acquiesceLogo.value[3]
          if(scale>=1&&scale<3&&day) url = acquiesceLogo.value[6]
          if(scale<1) url = dark==true?acquiesceLogo.value[1]:acquiesceLogo.value[4]
          if(scale>=5) url = dark==true?acquiesceLogo.value[2]:acquiesceLogo.value[5]
          if(scale>=3&&scale<5&&!day) url = dark==true?acquiesceLogo.value[2]:acquiesceLogo.value[5]
          if(scale>=3&&scale<5&&day) url = acquiesceLogo.value[2]
          let newTempSize = await FileService.getImageSizeWithoutDownloading(url)
          let width = 0
          let height =  0
          //按照宽度进行缩放
          let ratio = newTempSize.width / y.width
          width = y.width
          height = newTempSize.height / ratio
          if(height>y.height){
              ratio = height / y.height
              height =  y.height
              width = width / ratio
          }
          y.height = height
          y.width = width
          y.lock = false
          delete y.clip
          templateObj[i].src = url
          if(tempNewSlide){
            tempNewSlide.elements.push(...templateObj)
          }else{
            elements.push(...templateObj)
            tempNewSlide = copySlidHandlerLogo(slideIndex)
          }
          
        } catch (error) {

        }
    }
    return {
      elements,
      newSlider:tempNewSlide,
    }
}

const SetColor = (colorArr: number[][]) => {
    // 初始化删除多余子节点
    const extractColor = document.querySelector('#extract-color-id') as HTMLElement;
    while (extractColor.firstChild) {
      extractColor.removeChild(extractColor.firstChild);
    }
    // 创建子节点
    for (let index = 0; index < colorArr.length; index++) {
      const bgc = '(' + colorArr[index][0] + ',' + colorArr[index][1] + ',' + colorArr[index][2] + ')';
      const colorBlock = document.createElement('div') as HTMLElement;
      colorBlock.id = `color-block-id${index}`;
      colorBlock.style.cssText = 'height: 50px;width: 50px;margin-right: 10px;border-radius: 50%;';
      colorBlock.style.backgroundColor = `rgb${bgc}`;
      let list = [parseInt(colorArr[index][0]),parseInt(colorArr[index][1]),parseInt(colorArr[index][2])]
      let obj = {
        Color: list
      }
      colorList.value.push(obj)
      extractColor.appendChild(colorBlock);
    }
}

const copySlidHandlerLogo = (slideIndex:number)=>{
  let newSlide = JSON.parse(JSON.stringify(slides.value[slideIndex]))
  newSlide.id = uniqueId()
  newSlide.elements = newSlide.elements.filter((y:any)=>!y.layerName || y.layerName!='logo')
  return newSlide
}

// 销售模版数据
const sellGetTripTemplate = async () =>{
  try {
      let Id = 0
      if(searchData.value.sellId) Id = searchData.value.sellId
      let queryMsg = {
        Id: Id
      }
      // 行程广告浏览记录
      const loadingObj = ElLoading.service({text:'正在渲染数据',lock:true})
      await ConfigService.SetTripBrowse({FileId: searchData.value.sellId});
      let dataRes = await ConfigService.sellGetTemplateDetails(queryMsg);
      loadingObj.close()
      if (dataRes.data.resultCode == 1) {
        if(searchData.value.TempId) queryObj.value.TempId = searchData.value.TempId
        else if(searchData.value.TempId2&&!searchData.value.TempId) queryObj.value.TempId = searchData.value.TempId2
        else if(searchData.value.sellTempId) queryObj.value.TempId = searchData.value.sellTempId
        else if(TempId.value) queryObj.value.TempId = TempId.value

        let dataObj = dataRes.data.data
        queryObj.value.TemplateType = dataRes.data.data.TemplateType
        let viewportRatios = 0
        if(dataRes.data.data.TemplateType!=2) {
          viewportRatios = 1.414
          if(dataRes.data.data.TempType==1) viewportRatios = 0.7069
        }
        if(dataRes.data.data.TemplateType==2&&dataRes.data.data.Width&&dataRes.data.data.Height) {
          viewportRatios = dataRes.data.data.Height/dataRes.data.data.Width
          queryObj.value.Width = dataRes.data.data.Width
          queryObj.value.Height = dataRes.data.data.Height
        }
        slidesStore.setViewportRatio(viewportRatios)

        if(queryObj.value.Width){
          VIEWPORT_SIZE.Value = queryObj.value.Height
          VIEWPORT_VER_SIZE.Value = queryObj.value.Width
        }else {
          VIEWPORT_SIZE.Value = 1754
          VIEWPORT_VER_SIZE.Value = 1240
        }
        if(SalesBack.value==0) slidesStore.setTitle(dataRes.data.data.Title)
        if(SalesBack.value==0&&searchData.value.sellId){
          let SlidesData = JSON.parse(dataObj.TempData)

          let newSlides = []
           SlidesData.forEach((x,i)=>{
            x.elements.forEach((y:any)=>{
              if(y.content && y.defaultFontName && y.defaultFontName.includes(',')) y.defaultFontName = y.defaultFontName.split(',')[0]
              if(y.contentStr && y.content && y.content.includes(y.contentStr)){
                let temp = HtmlUtil.htmlEncodeByRegExp(y.contentStr)
                if(temp!=y.contentStr) {
                  y.content = y.content.replace(y.contentStr,temp)
                }
              }
            })
            newSlides.push(x)
          })
          slidesStore.setSlides(newSlides)
          
        }
      }else ElMessage({
                  showClose: true,
                  message: dataRes.data.message,
                  type: 'warning',
              })
  } catch (error) {
      
  }
}

// 页面被切换时
const thumbnailsRef = ref<InstanceType<typeof Draggable>>()

// 切换页面
const changeSlideIndex = (index: number) => {
  if(SourceLoading.value) setNewDatasList(datas.DataSource)
  mainStore.setActiveElementIdList([])
  // 绑定数据源
  const newElements = slides.value.find((slide,indexs) => {
    return index==indexs
  })
  datas.DataSource.pageType = newElements.pageType
  let TemplateList = TemplateDataSource.value.filter(x=>{
    return x.FiledType==newElements.pageType
  })
  datas.DataSource.DataSourceList = []
  newElements&&newElements.elements&&newElements.elements.forEach(slide=>{
    if(slide.type=="text"||slide.type=="image") {
      let contentStr
      if(slide.type=="text") contentStr = getHtmlPlainText(slide.content)
      if(slide.type=="image") contentStr = slide.src
        let Obj = {}
        Obj = {
          ...slide,
          contentStr: contentStr,
          TemplateList: TemplateList,
          TemplateDataSource: {
            Content: slide.TemplateDataSource&&slide.TemplateDataSource.Content?slide.TemplateDataSource.Content:'',
            Name: slide.TemplateDataSource&&slide.TemplateDataSource.Name?slide.TemplateDataSource.Name:'',
            Id: slide.TemplateDataSource&&slide.TemplateDataSource.Id?slide.TemplateDataSource.Id:null as Number,
          }
        }
        if(newElements.pageType!=1){
          let index = slide.TemplateDataSource&&slide.TemplateDataSource.index>=0?slide.TemplateDataSource.index:null as Number
          Reflect.set(Obj.TemplateDataSource, 'index', index)
        }
        if(Obj){
          datas.DataSource.DataSourceList.push(Obj)
        }
    }
    
  })
  
  if (slideIndex.value === index) return
  slidesStore.updateSlideIndex(index)
}

// 点击缩略图
const handleClickSlideThumbnail = (e: MouseEvent, index: number) => {
  const isMultiSelected = selectedSlidesIndex.value.length > 1

  if (isMultiSelected && selectedSlidesIndex.value.includes(index) && e.button !== 0) return

  // 按住Ctrl键，点选幻灯片，再次点击已选中的页面则取消选中
  // 如果被取消选中的页面刚好是当前激活页面，则需要从其他被选中的页面中选择第一个作为当前激活页面
  if (ctrlKeyState.value) {
    if (slideIndex.value === index) {

      if (!isMultiSelected) return

      const newSelectedSlidesIndex = selectedSlidesIndex.value.filter(item => item !== index)
      mainStore.updateSelectedSlidesIndex(newSelectedSlidesIndex)
      changeSlideIndex(selectedSlidesIndex.value[0])
    }
    else {
      if (selectedSlidesIndex.value.includes(index)) {
        const newSelectedSlidesIndex = selectedSlidesIndex.value.filter(item => item !== index)
        mainStore.updateSelectedSlidesIndex(newSelectedSlidesIndex)
      }
      else {
        const newSelectedSlidesIndex = [...selectedSlidesIndex.value, index]
        mainStore.updateSelectedSlidesIndex(newSelectedSlidesIndex)
      }
    }
  }
  // 按住Shift键，选择范围内的全部幻灯片
  else if (shiftKeyState.value) {
    if (slideIndex.value === index && !isMultiSelected) return

    let minIndex = Math.min(...selectedSlidesIndex.value)
    let maxIndex = index

    if (index < minIndex) {
      maxIndex = Math.max(...selectedSlidesIndex.value)
      minIndex = index
    }

    const newSelectedSlidesIndex = []
    for (let i = minIndex; i <= maxIndex; i++) newSelectedSlidesIndex.push(i)
    mainStore.updateSelectedSlidesIndex(newSelectedSlidesIndex)
  }
  // 正常切换页面
  else {
    mainStore.updateSelectedSlidesIndex([])
    changeSlideIndex(index)
  }
}

// 设置缩略图工具栏聚焦状态（只有聚焦状态下，该部分的快捷键才能生效）
const setThumbnailsFocus = (focus: boolean) => {
  if (thumbnailsFocus.value === focus) return
  mainStore.setThumbnailsFocus(focus)

  if (!focus) mainStore.updateSelectedSlidesIndex([])
}

// 拖拽调整顺序后进行数据的同步
const handleDragEnd = (eventData: { newIndex: number; oldIndex: number }) => {
  const { newIndex, oldIndex } = eventData
  if (newIndex === undefined || oldIndex === undefined || newIndex === oldIndex) return
  sortSlides(newIndex, oldIndex)
}

const { enterScreening, enterScreeningFromStart } = useScreening()

const contextmenusThumbnails = (): ContextmenuItem[] => {
  return [
    {
      text: '粘贴',
      subText: 'Ctrl + V',
      handler: pasteSlide,
    },
    {
      text: '全选',
      subText: 'Ctrl + A',
      handler: selectAllSlide,
    },
    {
      text: '新建页面',
      subText: 'Enter',
      handler: createSlide,
    },
    {
      text: '幻灯片放映',
      subText: 'F5',
      handler: enterScreeningFromStart,
    },
  ]
}

const contextmenusThumbnailItem = (): ContextmenuItem[] => {
  return [
    {
      text: '剪切',
      subText: 'Ctrl + X',
      handler: cutSlide,
    },
    {
      text: '复制',
      subText: 'Ctrl + C',
      handler: copySlide,
    },
    {
      text: '粘贴',
      subText: 'Ctrl + V',
      handler: pasteSlide,
    },
    {
      text: '全选',
      subText: 'Ctrl + A',
      handler: selectAllSlide,
    },
    { divider: true },
    {
      text: '新建页面',
      subText: 'Enter',
      handler: createSlide,
    },
    {
      text: '复制页面',
      subText: 'Ctrl + D',
      handler: copyAndPasteSlide,
    },
    {
      text: '删除页面',
      subText: 'Delete',
      handler: () => deleteSlide(),
    },
    { divider: true },
    {
      text: '从当前放映',
      subText: 'Shift + F5',
      handler: enterScreening,
    },
  ]
}

if(searchData.value.sellId&&!searchData.value.TempId) sellGetTripTemplate()
if(!query().ViewSlideshow) GetTripTemplate()
  
</script>

<style lang="scss" scoped>
.thumbnails {
  border-right: solid 1px $borderColor;
  background-color: #fff;
  display: flex;
  flex-direction: column;
  user-select: none;
}
.add-slide {
  height: 40px;
  font-size: 12px;
  display: flex;
  flex-shrink: 0;
  border-bottom: 1px solid $borderColor;
  cursor: pointer;

  .btn {
    flex: 1;
    display: flex;
    justify-content: center;
    align-items: center;

    &:hover {
      background-color: $lightGray;
    }
  }
  .select-btn {
    width: 30px;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    border-left: 1px solid $borderColor;

    &:hover {
      background-color: $lightGray;
    }
  }

  .icon {
    margin-right: 3px;
    font-size: 14px;
  }
}
.add-slide.borderBottom0{
  border-bottom: 0;
}
.thumbnail-list {
  padding: 5px 0;
  flex: 1;
  overflow: auto;
  width: 164px;
}
.thumbnail-item {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 5px 0;

  .thumbnail {
    outline: 2px solid rgba($color: $themeColor, $alpha: .15);
  }

  &.active {
    .label {
      color: $themeColor;
    }
    .thumbnail {
      outline-color: $themeColor;
    }
  }
  &.selected {
    .thumbnail {
      // outline-color: $themeColor;
      outline-color: #0B40FE;
      box-shadow: 0px 0px 15px 0px rgba(11,64,254,0.8);
    }
  }
}
.label {
  font-size: 12px;
  color: #999;
  width: 20px;
  cursor: grab;

  &.offset-left {
    position: relative;
    left: -4px;
  }

  &:active {
    cursor: grabbing;
  }
}
.page-number {
  height: 40px;
  font-size: 12px;
  border-top: 1px solid $borderColor;
  line-height: 40px;
  text-align: center;
  color: #666;
}
</style>