<template>
  <div class="build">
    <contentmenu ref="contentmenu"></contentmenu>
    <imglist ref="imglist"
             @change="handleSetimg"></imglist>
    <headers ref="headers"></headers>
    <top ref="top"></top>
    <div class="app"
         :class="{'app--none':!menuFlag}">
      <div class="menu"
           :style="{width:setPx(this.menuParams.menuWidth)}"
           v-show="menuFlag&&menuShow"
           @click.stop="handleInitActive">
        <div class="menu__drag"
             ref="menuDrag"
             @mousedown="handleDrag($event,'menu')"></div>
        <div class="menu_header  title">
          <div class="title_box">
            <span>
              图层({{list.length}})
              <el-icon @click="$refs.layer.handleRefresh()">
                <el-icon-caret-top></el-icon-caret-top>
              </el-icon>
            </span>
            <div class="title_menu">
              <div class="head_btn"
                   :class="{'head_btn--active':layerType==0}"
                   @click="layerType=0">
                <el-icon>
                  <el-icon-monitor />
                </el-icon>
              </div>
              <div class="head_btn"
                   :class="{'head_btn--active':layerType==1}"
                   @click="layerType=1">
                <el-icon>
                  <el-icon-coin />
                </el-icon>
              </div>
            </div>
          </div>
        </div>
        <el-scrollbar class="menu__scrollbar">
          <layer ref="layer"
                 :type="layerType"
                 style="padding:0 5px;"
                 :nav="nav"></layer>
        </el-scrollbar>
      </div>
      <!-- 中间区域 -->
      <div ref="sectionRef"
           id="section"
           :class="{'screens-drag':dragFlag}"
           @mousedown="dragMousedown"
           @mouseup="dragMouseup"
           @mousemove="dragMousemove"
           @contextmenu.prevent="()=>{}"
           class="section">
        <sketch-rule :thick="thick"
                     :key="themeUpdateTrigger"
                     :scale="scale"
                     :width="width"
                     :height="height"
                     :startX="startX"
                     :startY="startY"
                     :palette="palette"
                     :shadow="shadow"
                     :horLineArr="lines.h"
                     :verLineArr="lines.v" />
        <div ref='screensRef'
             class="screens"
             @wheel="handleWheel"
             @scroll="handleScroll">
          <div ref="containerRef"
               class="screen-container">
            <div class="canvas"
                 ref="canvasRef"
                 :style="canvasStyle">
              <container ref="container"></container>
            </div>
          </div>
        </div>
        <!-- 底部工具栏 -->
        <footer-toolbar ref="footer"></footer-toolbar>
      </div>
      <div class="menu params"
           :style="{width:setPx(this.menuParams.paramsWidth)}"
           v-show="menuFlag&&paramsShow">
        <div class="menu__drag"
             ref="paramsDrag"
             @mousedown="handleDrag($event,'params')"
             :style="{left:'-4px'}"></div>
        <div class="menu_header">
          <el-tabs v-if="isMain"
                   class="menu__tabs"
                   stretch
                   v-model="menuTabs">
            <el-tab-pane name="0">
              <template #label>
                <el-icon>
                  <el-icon-setting />
                </el-icon>
                <span>配置</span>
              </template>

            </el-tab-pane>
            <!-- 数据配置 -->
            <el-tab-pane name="1"
                         v-if="validProp('dataList')">
              <template #label>
                <el-icon>
                  <el-icon-document-copy />
                </el-icon>
                <span>数据</span>
              </template>
            </el-tab-pane>
            <template v-if="!isFolder&&!validProp('notEventList')">
              <!-- 交互配置 -->
              <el-tab-pane name="2">
                <template #label>
                  <el-icon>
                    <el-icon-edit />
                  </el-icon>
                  <span>交互</span>
                </template>

              </el-tab-pane>

              <el-tab-pane name="3">
                <template #label>
                  <el-icon>
                    <el-icon-film />
                  </el-icon>
                  <span>动画</span>
                </template>
              </el-tab-pane>
            </template>
            <!-- 基本参数配置 -->
            <el-tab-pane name="4">
              <template #label>
                <el-icon>
                  <el-icon-folder />
                </el-icon>
                <span>其它</span>
              </template>
            </el-tab-pane>
          </el-tabs>
          <p class="title"
             v-if="isMain">{{activeObj.title}}（{{activeObj.name}}）</p>
        </div>
        <el-scrollbar class="menu__scrollbar"
                      :style="scrollStyleName">
          <template v-if="menuTabs==0">
            <el-form label-width="90px"
                     label-position="left">
              <!-- 多选配置选项 -->
              <template v-if="isSelectActive">
                <el-form-item label="水平对齐">
                  <ul class="menu__button">
                    <li @click="$refs.contentmenu.handlePostionSelect('left')">
                      <el-tooltip content="左对齐"
                                  placement="top">
                        <el-button>
                          <svg-icon icon-class="pos1" />
                        </el-button>
                      </el-tooltip>
                    </li>
                    <li @click="$refs.contentmenu.handlePostionSelect('center')">
                      <el-tooltip content="水平对齐"
                                  placement="top">
                        <el-button>
                          <svg-icon icon-class="pos5" />
                        </el-button>
                      </el-tooltip>
                    </li>
                    <li @click="$refs.contentmenu.handlePostionSelect('right')">
                      <el-tooltip content="右对齐"
                                  placement="top">
                        <el-button>
                          <svg-icon icon-class="pos3" />
                        </el-button>
                      </el-tooltip>
                    </li>
                    <li @click="$refs.contentmenu.handleRotateX">
                      <el-tooltip content="水平翻转"
                                  placement="top">
                        <el-button>
                          <svg-icon icon-class="pos8" />
                        </el-button>
                      </el-tooltip>
                    </li>
                  </ul>
                </el-form-item>
                <el-form-item label="垂直对齐">
                  <ul class="menu__button">
                    <li @click="$refs.contentmenu.handlePostionSelect('top')">
                      <el-tooltip content="顶部对齐"
                                  placement="top">
                        <el-button>
                          <svg-icon icon-class="pos4" />
                        </el-button>
                      </el-tooltip>
                    </li>
                    <li @click="$refs.contentmenu.handlePostionSelect('middle')">
                      <el-tooltip content="垂直对齐"
                                  placement="top">
                        <el-button>
                          <svg-icon icon-class="pos2" />
                        </el-button>
                      </el-tooltip>
                    </li>
                    <li @click="$refs.contentmenu.handlePostionSelect('bottom')">
                      <el-tooltip content="底部对齐"
                                  placement="top">
                        <el-button>
                          <svg-icon icon-class="pos6" />
                        </el-button>
                      </el-tooltip>
                    </li>
                    <li @click="$refs.contentmenu.handleRotateY">
                      <el-tooltip content="垂直翻转"
                                  placement="top">
                        <el-button>
                          <svg-icon icon-class="pos7" />
                        </el-button>
                      </el-tooltip>
                    </li>
                  </ul>
                </el-form-item>
                <el-form-item label-width="0">
                  <el-button type="primary"
                             class="block"
                             @click="$refs.contentmenu.handleCompose">成组</el-button>
                </el-form-item>
                <el-form-item label-width="0">
                  <el-button type="danger"
                             class="block"
                             @click="$refs.contentmenu.handleDel">删除</el-button>
                </el-form-item>
                <el-form-item label=""
                              label-width="0px">
                  <monaco-editor v-model="activeObjList"
                                 disabled
                                 :showToolbar="false"
                                 @click="handleCopy(JSON.stringify(activeObjList,null,4))"
                                 language="javascript"
                                 height="400"></monaco-editor>
                </el-form-item>
              </template>
              <!-- 组件配置 -->
              <template v-else-if="activeIndex">
                <el-form-item label="图层名称">
                  <avue-input v-model="activeObj.name"></avue-input>
                </el-form-item>
                <el-form-item label="隐藏">
                  <avue-switch v-model="activeObj.display"
                               @change="({value})=>handleParams('display', null, value)"></avue-switch>
                </el-form-item>
                <el-form-item label="锁定">
                  <avue-switch v-model="activeObj.lock"
                               @change="({value})=>handleParams('lock', null, value)"></avue-switch>
                </el-form-item>
                <el-form-item label="水平对齐">
                  <ul class="menu__button">
                    <li @click="$refs.contentmenu.handlePostionSelect('left')">
                      <el-tooltip content="左对齐"
                                  placement="top">
                        <el-button>
                          <svg-icon icon-class="pos1" />
                        </el-button>
                      </el-tooltip>
                    </li>
                    <li @click="$refs.contentmenu.handlePostionSelect('middle')">
                      <el-tooltip content="水平对齐"
                                  placement="top">
                        <el-button>
                          <svg-icon icon-class="pos2" />
                        </el-button>
                      </el-tooltip>
                    </li>
                    <li @click="$refs.contentmenu.handlePostionSelect('right')">
                      <el-tooltip content="右对齐"
                                  placement="top">
                        <el-button>
                          <svg-icon icon-class="pos3" />
                        </el-button>
                      </el-tooltip>
                    </li>
                    <li @click="$refs.contentmenu.handleRotateX">
                      <el-tooltip content="水平翻转"
                                  placement="top">
                        <el-button>
                          <svg-icon icon-class="pos8" />
                        </el-button>
                      </el-tooltip>
                    </li>
                  </ul>
                </el-form-item>
                <el-form-item label="垂直对齐">
                  <ul class="menu__button">
                    <li @click="$refs.contentmenu.handlePostionSelect('top')">
                      <el-tooltip content="顶部对齐"
                                  placement="top">
                        <el-button>
                          <svg-icon icon-class="pos4" />
                        </el-button>
                      </el-tooltip>
                    </li>
                    <li @click="$refs.contentmenu.handlePostionSelect('center')">
                      <el-tooltip content="垂直对齐"
                                  placement="top">
                        <el-button>
                          <svg-icon icon-class="pos5" />
                        </el-button>
                      </el-tooltip>
                    </li>
                    <li @click="$refs.contentmenu.handlePostionSelect('bottom')">
                      <el-tooltip content="底部对齐"
                                  placement="top">
                        <el-button>
                          <svg-icon icon-class="pos6" />
                        </el-button>
                      </el-tooltip>
                    </li>
                    <li @click="$refs.contentmenu.handleRotateY">
                      <el-tooltip content="垂直翻转"
                                  placement="top">
                        <el-button>
                          <svg-icon icon-class="pos7" />
                        </el-button>
                      </el-tooltip>
                    </li>
                  </ul>
                </el-form-item>
                <el-collapse v-if="isFolder">
                  <el-collapse-item title="轮播">
                    <el-form-item label="开启">
                      <avue-switch v-model="activeObj.auto"
                                   @change="({value})=>handleParams('auto', null, value)"></avue-switch>
                    </el-form-item>
                    <template v-if="activeObj.auto">
                      <el-form-item label="初始化序号">
                        <el-input v-model="activeObj.autoInitialIndex"
                                  placeholder="默认0"> </el-input>
                      </el-form-item>
                      <el-form-item label="时间">
                        <el-input v-model="activeObj.autoInterval"
                                  placeholder="3000">
                          <template #append>
                            <span>毫秒</span>
                          </template>
                        </el-input>
                      </el-form-item>
                      <el-form-item label="类型">
                        <avue-select v-model="activeObj.autoType"
                                     :dic="[{label:'普通',value:''},{label:'卡片',value:'card'}]"
                                     placeholder="请选择类型"> </avue-select>
                      </el-form-item>
                      <el-form-item label="自动切换">
                        <avue-select v-model="activeObj.autoAutoplay"
                                     :dic="[{label:'是',value:true},{label:'否',value:false}]"
                                     placeholder="请选择自动切换"> </avue-select>
                      </el-form-item>
                      <el-form-item label="方向">
                        <avue-select v-model="activeObj.autoDirection"
                                     :dic="[{label:'横',value:'horizontal'},{label:'竖',value:'vertical'}]"
                                     placeholder="请选择方向"> </avue-select>
                      </el-form-item>
                      <el-form-item label="箭头">
                        <avue-select v-model="activeObj.autoArrow"
                                     :dic="[{label:'总显示',value:'always'},{label:'移动显示',value:'hover'},{label:'不显示',value:'never'}]"
                                     placeholder="请选择箭头"> </avue-select>
                      </el-form-item>
                      <el-form-item label="指示器">
                        <avue-select v-model="activeObj.autoIndicatorPosition"
                                     :dic="[{label:'不显示',value:'none'},{label:'显示',value:'outside'}]"
                                     placeholder="请选择指示器"> </avue-select>
                      </el-form-item>
                    </template>
                  </el-collapse-item>

                  <!-- 新增格栅布局配置 -->
                  <el-collapse-item title="格栅">
                    <el-form-item label="开启格栅">
                      <avue-switch v-model="activeObj.grid"
                                   @change="({value})=>handleParams('grid', null, value)"></avue-switch>
                    </el-form-item>
                    <template v-if="activeObj.grid">
                      <el-form-item label="宽度">
                        <el-input-number v-model="activeObj.gridWidth"
                                         :min="0"
                                         :max="2000"
                                         placeholder="请输入宽度"></el-input-number>
                      </el-form-item>
                      <el-form-item label="行数">
                        <el-input-number v-model="activeObj.gridSpan"
                                         :min="1"
                                         :max="24"
                                         placeholder="请输入行数"></el-input-number>
                      </el-form-item>
                      <el-form-item label="间距">
                        <el-input-number v-model="activeObj.gridGutter"
                                         :min="0"
                                         :max="50"
                                         placeholder="元素间距"></el-input-number>
                      </el-form-item>
                    </template>
                  </el-collapse-item>

                  <el-form-item label-width="0">
                    <el-button type="primary"
                               class="block"
                               @click="$refs.contentmenu.handleLogout">解散</el-button>
                  </el-form-item>
                  <el-form-item label-width="0">
                    <el-button type="danger"
                               class="block"
                               @click="$refs.contentmenu.handleLogout">删除</el-button>
                  </el-form-item>
                </el-collapse>
                <template v-if="validProp('colorList')">
                  <el-form-item label="系统配色">
                    <avue-switch v-model="activeOption.switchTheme"></avue-switch>
                  </el-form-item>
                </template>
                <component :is="activeComponent.prop+'Option'"></component>
                <mains-option></mains-option>
              </template>
              <!-- 主屏的配置项 -->
              <template v-else>
                <el-tabs class="menu__tabs"
                         stretch
                         v-model="mainTabs">
                  <el-tab-pane label="配置"
                               name="0">
                    <el-collapse accordion>
                      <el-form-item label="大屏大小">
                        <div class="flex">
                          <avue-input-number style="width:100px"
                                             v-model="config.width"></avue-input-number>
                          &nbsp;x&nbsp;
                          <avue-input-number style="width:100px"
                                             v-model="config.height"></avue-input-number>
                        </div>
                      </el-form-item>
                      <el-form-item label="大屏简介">
                        <avue-input v-model="config.info"
                                    type="textarea"
                                    :min-rows="5"></avue-input>
                      </el-form-item>
                      <el-form-item label="背景颜色">
                        <avue-input-color v-model="config.backgroundColor"></avue-input-color>
                      </el-form-item>
                      <el-form-item label="背景图片">
                        <img :src="config.backgroundImage"
                             @click="handleOpenImg('config.backgroundImage','background')"
                             alt=""
                             style="width:100%;" />
                        <el-input clearable
                                  v-model="config.backgroundImage">
                          <template #append>
                            <div @click="handleOpenImg('config.backgroundImage','background')">
                              <i class="iconfont icon-img"></i>
                            </div>
                          </template>
                        </el-input>
                      </el-form-item>
                      <el-form-item label="适配方式">
                        <el-radio-group v-model="config.screen">
                          <el-radio-button value="x">
                            <el-tooltip effect="dark"
                                        content="X轴铺满，Y轴自适应滚动"
                                        placement="top">
                              <svg-icon icon-class="fix2" />
                            </el-tooltip>
                          </el-radio-button>
                          <el-radio-button value="y">
                            <el-tooltip effect="dark"
                                        content="Y轴铺满，X轴自适应滚动"
                                        placement="top">
                              <svg-icon icon-class="fix3" />
                            </el-tooltip>
                          </el-radio-button>
                          <el-radio-button value="xy">
                            <el-tooltip effect="dark"
                                        content="强行拉伸画面，填充所有视图"
                                        placement="top">
                              <svg-icon icon-class="fix4" />
                            </el-tooltip>
                          </el-radio-button>
                        </el-radio-group>
                      </el-form-item>
                      <el-collapse-item title="辅助">
                        <el-form-item label="文件夹穿透">
                          <avue-switch v-model="config.folderDeep"></avue-switch>
                        </el-form-item>
                        <el-form-item label="超出隐藏">
                          <avue-switch v-model="config.overflow"></avue-switch>
                        </el-form-item>
                        <el-form-item label="辅助网格">
                          <avue-switch v-model="config.gradeShow"></avue-switch>
                        </el-form-item>
                        <el-form-item label="辅助线">
                          <avue-switch v-model="config.toolShow"></avue-switch>
                        </el-form-item>
                        <el-form-item>
                          <template #label>
                            <feature-tooltip label="跨屏复制"
                                             buy-tooltip="点击购买插件支持跨屏复制粘贴"
                                             buy-link="5" />
                          </template>
                          <avue-switch v-model="config.crossScreen"></avue-switch>
                        </el-form-item>
                      </el-collapse-item>
                      <el-collapse-item title="滤镜">
                        <el-form-item label="开启">
                          <avue-switch size="small"
                                       v-model="config.styles.show"></avue-switch>
                        </el-form-item>
                        <template v-if="config.styles.show">
                          <el-form-item label="对比度">
                            <avue-slider v-model="config.styles.contrast"
                                         :max="400"></avue-slider>
                          </el-form-item>
                          <el-form-item label="饱和度">
                            <avue-slider v-model="config.styles.saturate"
                                         :max="400"></avue-slider>
                          </el-form-item>
                          <el-form-item label="亮度">
                            <avue-slider v-model="config.styles.brightness"
                                         :max="400"></avue-slider>
                          </el-form-item>
                          <el-form-item label="透明度">
                            <avue-slider v-model="config.styles.opacity"
                                         :max="100"></avue-slider>
                          </el-form-item>
                          <el-form-item label="灰度">
                            <avue-slider v-model="config.styles.grayscale"
                                         :max="400"></avue-slider>
                          </el-form-item>
                          <el-form-item label="色相">
                            <avue-slider v-model="config.styles.hueRotate"
                                         :max="1000"></avue-slider>
                          </el-form-item>
                          <el-form-item label="反转">
                            <avue-slider v-model="config.styles.invert"
                                         :max="400"></avue-slider>
                          </el-form-item>
                          <el-form-item label="模糊">
                            <avue-slider v-model="config.styles.blur"
                                         :max="100"></avue-slider>
                          </el-form-item>
                        </template>
                      </el-collapse-item>
                      <el-collapse-item title="水印（预览模式生效）">
                        <el-form-item label="开启">
                          <avue-switch v-model="config.mark.show"></avue-switch>
                        </el-form-item>
                        <template v-if="config.mark.show">
                          <el-form-item label="内容">
                            <avue-input v-model="config.mark.text"
                                        placeholder="请输入水印内容"></avue-input>
                          </el-form-item>
                          <el-form-item label="大小">
                            <avue-input-number v-model="config.mark.fontSize"></avue-input-number>
                          </el-form-item>
                          <el-form-item label="颜色">
                            <avue-input-color v-model="config.mark.color"></avue-input-color>
                          </el-form-item>
                          <el-form-item label="角度">
                            <avue-input-number v-model="config.mark.degree"></avue-input-number>
                          </el-form-item>
                        </template>
                      </el-collapse-item>
                      <el-form-item label-width="0">
                        <el-button type="primary"
                                   class="block"
                                   @click="$refs.glob.box=true">更多设置</el-button>
                      </el-form-item>
                    </el-collapse>
                  </el-tab-pane>
                  <el-tab-pane label="屏幕"
                               name="1">
                    <group></group>
                  </el-tab-pane>
                  <el-tab-pane label="变量"
                               name="2">
                    <variable></variable>
                  </el-tab-pane>
                  <el-tab-pane label="过滤器"
                               name="3">
                    <filters></filters>
                  </el-tab-pane>
                  <el-tab-pane label="函数"
                               name="4">
                    <func></func>
                  </el-tab-pane>
                  <el-tab-pane label="主题"
                               name="5">
                    <theme></theme>
                  </el-tab-pane>

                </el-tabs>
              </template>
            </el-form>
          </template>
          <template v-else-if="menuTabs==1">
            <dataindex ref="dataindex"></dataindex>
          </template>
          <template v-else-if="menuTabs==2">
            <transfer ref="transfer"></transfer>
          </template>
          <template v-else-if="menuTabs==3">
            <anima ref="anima"></anima>
          </template>
          <template v-else-if="menuTabs==4">
            <el-form label-width="100px"
                     label-position="left">
              <el-form-item label="序号">
                <avue-input readonly
                            @click="handleCopy(activeIndex)"
                            v-model="activeIndex">
                </avue-input>
              </el-form-item>
              <el-form-item label="屏幕">
                <div class="avue-flex">
                  <avue-select :dic="config.group"
                               v-model="newGroup"
                               :empty-values="[undefined]"
                               :props="{label:'name',value:'id'}"
                               placeholder="请选择主屏幕"></avue-select>
                  &nbsp;
                  <el-button type="primary"
                             @click="handleMoveGroup">移动</el-button>
                </div>
              </el-form-item>
              <options v-if="!isFolder"></options>
              <el-form-item label=""
                            label-width="0px">
                <monaco-editor v-model="activeObj"
                               disabled
                               :showToolbar="false"
                               @click="handleCopy(JSON.stringify(activeObj,null,4))"
                               language="javascript"
                               height="300"></monaco-editor>
              </el-form-item>
            </el-form>
          </template>
        </el-scrollbar>
      </div>
    </div>

    <codeedit @submit="closeCode"
              v-if="code.box"
              :title="code.title"
              :type="code.type"
              :is-object="code.isObject"
              :codeType="code.codeType"
              :data-view="code.dataView"
              v-model="code.obj"
              v-model:visible="code.box"></codeedit>
    <glob ref="glob"></glob>
    <excel ref="excel"></excel>
  </div>
</template>
<script>
import AsyncLoading from './components/AsyncLoading.vue'
import AsyncError from './components/AsyncError.vue'
import { dicOption } from '@/option/config'
import init from '@/mixins/'
import components from '@/option/components'
import { SketchRule } from 'vue3-sketch-ruler'
import 'vue3-sketch-ruler/lib/style.css'
import _get from 'lodash/get';
import _set from 'lodash/set'
import { onThemeChange } from '@/utils/theme'

/**
 * 创建带有loading和错误处理的异步组件
 * @param {Function} loader - 组件加载函数
 * @param {number} delay - 延迟显示loading的时间(ms)
 * @param {number} timeout - 超时时间(ms)
 * @returns {Object} 异步组件配置
 */
const createAsyncComponent = (loader, delay = 200, timeout = 3000) => {
  return defineAsyncComponent({
    loader,
    loadingComponent: AsyncLoading,
    errorComponent: AsyncError,
    delay,
    timeout
  })
}

// 异步组件导入
const MonacoEditor = createAsyncComponent(() => import('@/page/components/monaco-editor'))
const FeatureTooltip = createAsyncComponent(() => import('@/page/components/FeatureTooltip.vue'))
const layer = createAsyncComponent(() => import('./group/layer.vue'))
const top = createAsyncComponent(() => import('./group/top.vue'))
const glob = createAsyncComponent(() => import('@/page/setup/glob.vue'))
const transfer = createAsyncComponent(() => import('@/page/setup/transfer.vue'))
const headers = createAsyncComponent(() => import('./group/header.vue'))
const options = createAsyncComponent(() => import('@/page/setup/options.vue'))
const imglist = createAsyncComponent(() => import('@/page/setup/imglist.vue'))
const group = createAsyncComponent(() => import('@/page/setup/group.vue'))
const excel = createAsyncComponent(() => import('@/page/setup/excel.vue'))
const theme = createAsyncComponent(() => import('@/page/setup/theme.vue'))
const filters = createAsyncComponent(() => import('@/page/setup/filters.vue'))
const func = createAsyncComponent(() => import('@/page/setup/func.vue'))
const variable = createAsyncComponent(() => import('@/page/setup/variable.vue'))
const dataindex = createAsyncComponent(() => import('@/page/setup/dataindex.vue'))
const anima = createAsyncComponent(() => import('@/page/setup/anima.vue'))
const contentmenu = createAsyncComponent(() => import('@/page/setup/contentmenu.vue'))
const codeedit = createAsyncComponent(() => import('./group/code.vue'))
const footerToolbar = createAsyncComponent(() => import('./group/footer.vue'))

export default {
  mixins: [init, components],
  data () {
    return {
      newGroup: '',
      layerType: 0,
      currentHistoryIndex: -1,
      menuId: 'avue-data-menu',
      menuShow: true,
      paramsShow: true,
      cacheList: {
        timer: null,
        nav: null,
        copy: null,
        data: null,
        history: []
      },
      keys: {
        ctrl: false,
        space: false
      },
      nav: [],
      loading: '',
      key: '',
      menuParams: {
        menuWidth: 200,
        paramsWidth: 330,
      },
      menuFlag: true,
      code: {
        codeType: '',
        title: '',
        box: false,
        type: '',
        obj: '',
      },
      form: {},
      dicOption: dicOption,
      mainTabs: '0',
      menuTabs: '0',
      //拖拽
      dragFlag: false,
      dragEvent: null,
      dragStartX: null,
      dragStartY: null,
      // 标尺
      width: document.body.clientWidth,
      height: document.body.clientHeight,
      scale: 1,
      startX: 0,
      startY: 0,
      // 主题更新触发器，用于强制 palette 计算属性重新计算
      themeUpdateTrigger: 0,
      lines: {
        h: [],
        v: []
      },
      thick: 20
    }
  },
  components: {
    MonacoEditor,
    FeatureTooltip,
    imglist,
    layer,
    transfer,
    codeedit,
    excel,
    top,
    theme,
    glob,
    headers,
    group,
    options,
    filters,
    func,
    anima,
    variable,
    dataindex,
    contentmenu,
    footerToolbar,
    SketchRule
  },
  computed: {
    activeObjList () {
      let list = []
      this.active.forEach(index => {
        let item = this.findnav(index);
        list.push(item.item)
      })
      return list;
    },
    isMain () {
      return this.isActive && !this.isSelectActive
    },
    scrollStyleName () {
      let calc = this.setPx(!this.isMain ? 2 : 85)
      return { paddingTop: calc }
    },
    shadow () {
      return {
        x: 0,
        y: 0,
        width: this.width,
        height: this.height
      }
    },
    // 标尺颜色配置 - 使用主题颜色
    palette () {
      // 强制响应式更新，通过监听主题变化
      this.themeUpdateTrigger; // 触发重新计算

      const getThemeColor = (varName, fallback) => {
        return getComputedStyle(document.documentElement).getPropertyValue(varName).trim() || fallback;
      };

      const palette = {
        bgColor: getThemeColor('--bg-color-secondary', '#202023'),
        longfgColor: getThemeColor('--text-color-primary', '#BABBBC'),
        shortfgColor: getThemeColor('--text-color-secondary', '#9C9C9C'),
        fontColor: getThemeColor('--text-color-regular', '#919398'),
        shadowColor: getThemeColor('--shadow-color', '#18181c'),
        lineColor: getThemeColor('--primary-color', '#2681ff'),
        borderColor: getThemeColor('--border-color-base', '#B5B5B5'),
        cornerActiveColor: getThemeColor('--color-white', '#fff'),
      };

      return palette;
    },
    // 能否撤销
    canUndo () {
      return this.currentHistoryIndex > 0
    },
    canRedo () {
      return this.cacheList.history.length > this.currentHistoryIndex + 1
    },
    isKeysCtrl () {
      return this.keys.ctrl == true
    },

    isFolder () {
      return this.activeObj.children
    },
    isActive () {
      return this.activeIndex
    },
    isSelectActive () {
      return this.active.length > 1;
    },
    activeComponent () {
      return this.activeObj.component || {}
    },
    activeOption () {
      return this.activeObj.option || {}
    },
    activeObj () {
      let item = this.findList(this.activeIndex) || {}
      if (!item.child) item.child = {}
      return item
    },
    activeList () {
      let result = []
      this.active.forEach(ele => {
        let item = this.findnav(ele);
        result.push(item.item);
      })
      return result
    },
    publicList () {
      return this.list.filter(ele => {
        return (ele.component || {}).prop == 'data'
      }).map(ele => {
        return {
          label: ele.name,
          value: ele.index
        }
      })
    },
    canvasStyle () {
      return {
        width: this.setPx(this.canvasWidth),
        height: this.setPx(this.canvasHeight),
        transform: `scale(${this.scale})`,
        overflow: this.config.overflow ? 'hidden' : ''
      }
    }
  },
  watch: {
    nav: {
      handler (val) {
        this.recordHistoryCache(val)
      },
      deep: true
    },
    activeObj: {
      handler () {
        this.newGroup = this.activeObj.group
      },
      deep: true
    },
    activeOverIndex (n, o) {
      [o, n].forEach((ele, index) => {
        if (!ele) return
        this.setActive(ele, index === 1, 'setOverActive');
      })
    },
    active (n, o) {
      [o, n].forEach((ele, index) => {
        ele.forEach(item => {
          this.setActive(item, index === 1, 'setActive');
        })
      })
      // 初始化选项卡
      this.menuTabs = '0';
    },
  },
  mounted () {
    setTimeout(() => {
      this.initFun()
      this.initSize()
      this.listenKey();
      this.initThemeWatcher();
    })
  },
  beforeUnmount () {
    // 清理主题变化监听器
    if (this.$themeUnsubscribe) {
      this.$themeUnsubscribe();
    }
  },
  methods: {
    // 初始化主题变化监听器
    initThemeWatcher () {
      // 监听主题变化事件
      this.$themeUnsubscribe = onThemeChange(() => {
        // 当主题改变时，触发 palette 重新计算
        this.themeUpdateTrigger++;
      });
    },
    handleMoveGroup () {
      this.$confirm(`是否移动到对应屏幕?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        let { itemList, itemIndex } = this.findnav(this.activeIndex);
        let obj = itemList.splice(itemIndex, 1)[0];
        if (obj.children) {
          obj.children.forEach(ele => {
            ele.group = this.newGroup;
          })
        }
        obj.group = this.newGroup;
        this.nav.unshift(obj);
        this.handleInitActive()
        this.mainTabs = '1';
      })
    },
    dragMousedown (e) {
      this.handleInitActive()
      this.dragFlag = true
      this.dragEvent = e
      this.dragStartX = this.$refs.screensRef.scrollLeft
      this.dragStartY = this.$refs.screensRef.scrollTop
    },
    dragMouseup () {
      this.dragFlag = false
    },
    dragMousemove (e) {
      if (this.dragFlag) {
        let x = e.clientX - this.dragEvent.clientX
        let y = e.clientY - this.dragEvent.clientY
        this.$refs.screensRef.scrollLeft = this.dragStartX - x
        this.$refs.screensRef.scrollTop = this.dragStartY - y
      }
    },
    handleDrag (e, name) {
      let resize = this.$refs[name + 'Drag']
      if (!resize) return
      let startX = e.clientX;
      document.onmousemove = (e) => {
        let endX = e.clientX;
        let moveLen = endX - startX;
        startX = endX;
        this.menuParams[name + 'Width'] += name == 'params' ? -moveLen : moveLen
        this.$refs.headers.handleSet(false)
      };
      document.onmouseup = () => {
        document.onmousemove = null;
        document.onmouseup = null;
      };
      return false;
    },
    handleCopy (data) {
      this.$Clipboard({
        text: data
      }).then(() => {
        this.$message.success('复制成功')
      }).catch(() => {
        this.$message.error('复制失败')
      });
    },
    handleRefresh (fn) {
      return this.$refs.container.handleRefresh(fn);
    },
    handleParams (type, obj, val) {
      const deepList = (list, flag) => {
        list.forEach(ele => {
          ele[type] = flag
          if (ele.children) deepList(ele.children, flag);
        })
      }
      if (obj) {
        let value = this.validatenull(val) ? !obj[type] : val
        obj[type] = value
        deepList([obj], value)
      } else {
        this.active.forEach(ele => {
          let { item } = this.findnav(ele)
          let value = this.validatenull(val) ? !item[type] : val
          item[type] = value
          deepList([item], value)
        })
      }
      this.validatenull(val) && this.handleInitActive()
    },
    closeCode (value) {
      if (this.code.sql) {
        this.code.sql[this.code.id] = value
      } else if (this.configData.includes(this.code.type)) {
        this.config[this.code.type] = value;
      } else {
        const targetPath = this.code.parent
          ? `${this.code.parent}.${this.code.index}.${this.code.type}`
          : this.code.type;
        _set(this.activeObj, targetPath, value);
      }
      this.$refs.dataindex && this.$refs.dataindex.handleRes(false)
    },
    openCode ({ type, title, parent, index, dataView, sql, id, isObject }) {
      this.code.codeType = type === 'data' ? 'mock' : '';
      this.code = { ...this.code, parent, index, type, title, dataView, id, sql, isObject };
      if (sql) {
        this.code.obj = sql[id]
      } else if (this.configData.includes(type)) {
        this.code.obj = this.config[type];
      } else {
        const targetPath = parent ? `${parent}.${index}.${type}` : type;
        this.code.obj = _get(this.activeObj, targetPath)
      }
      this.code.box = true;
    },
    initFun () {
      ['setScale'].forEach(ele => {
        this[ele] = this.$refs.container[ele]
      })
    },
    // 右键菜单
    handleContextMenu (item = {}, done) {
      if (!item.index || this.isKeysCtrl) return
      else if (!this.isSelectActive) {
        this.active = [item.index];
        this.activeIndex = item.index;
      }
      const contentmenuRef = this.$refs.contentmenu
      contentmenuRef.beforeOpen && contentmenuRef.beforeOpen()
      done()
    },
    //监听键盘的按键
    listenKey () {
      let sectionRef = this.$refs.sectionRef;
      sectionRef.onkeydown = (e) => {
        const keyCode = e.keyCode;
        if (keyCode == 76 && this.isKeysCtrl) {
          if (!this.activeObj) return
          this.handleParams('lock')
        } else if (keyCode == 67 && this.isKeysCtrl) {
          if (!this.activeObj) return
          this.$refs.contentmenu.handleRplica()
        } else if (keyCode == 86 && this.isKeysCtrl) {
          this.$refs.contentmenu.handlePaste()
        } else if (keyCode == 88 && this.isKeysCtrl) {
          this.$refs.contentmenu.handleShear()
        } else if (keyCode == 8 || keyCode == 46) {
          this.$refs.contentmenu.handleDel();
        }
      }
      sectionRef.onkeyup = (e) => {
        const keyCode = e.keyCode;
      }
      document.onkeydown = (e) => {
        const keyCode = e.keyCode;
        var elm = e.srcElement || e.target;
        const validElm = (elm.tagName.toLowerCase() == "input" && elm.type.toLowerCase() == "text" || elm.tagName.toLowerCase() == "textarea") && elm.parentNode.className !== 'el-input avue-draggable__focus'
        if (keyCode == 32) {
          this.keys.space = true
          if (validElm) return;
          e.preventDefault()
        } else if (keyCode == 17 || keyCode == 91) {
          this.keys.ctrl = true
          if (validElm) return;
        } else if (keyCode == 86 && this.isKeysCtrl) {
          if (validElm) return;
          this.$refs.contentmenu.handlePaste()
        } else if (keyCode == 90 && this.isKeysCtrl) {
          if (validElm) return;
          this.editorUndo()
          e.preventDefault()
        } else if (keyCode == 89 && this.isKeysCtrl) {
          if (validElm) return;
          this.editorRedo()
          e.preventDefault()
        } else if (keyCode == 83 && this.isKeysCtrl) {
          if (validElm) return;
          this.$refs.headers.handleBuild();
          e.preventDefault()
        }
      }
      document.onkeyup = (e) => {
        const keyCode = e.keyCode;
        if (keyCode == 32) {
          this.keys.space = false
        } else if (keyCode == 17 || keyCode == 91) {
          this.keys.ctrl = false
        }
      }
    },
    setActive (val, result, fun) {
      const obj = this.$refs.container.getListRef(val);
      if (obj) obj[fun](result, true)
    },
    validProp (name) {
      return this.dicOption[name].includes(this.activeComponent.prop)
    },
    formatTooltip (val) {
      return parseInt(val);
    },
    //打开图库
    handleOpenImg (item, type) {
      this.$refs.imglist.openImg(item, type);
    },
    //图库框回调赋值
    handleSetimg (val, type) {
      let params = type.split('.')[1];
      if (type.includes('config')) {
        this.config[params] = val;
      } else if (type.includes('activeObj.data.value')) {
        this.activeObj.data.value = val;
      } else if (type.includes('activeObj.data')) {
        this.activeObj.data = val;
      } else if (type.includes('activeObj')) {
        this.activeObj[params] = val;
      } else if (type.includes('activeOption')) {
        this.activeOption[params] = val;
      }
    },
    handleScroll () {
      this.$nextTick(() => {
        const screensRect = this.$refs.screensRef.getBoundingClientRect();
        const canvasRect = this.$refs.canvasRef.getBoundingClientRect();
        // 标尺开始的刻度
        const startX = (screensRect.left + this.thick - canvasRect.left) / this.scale;
        const startY = (screensRect.top + this.thick - canvasRect.top) / this.scale;
        this.startX = startX >> 0;
        this.startY = startY >> 0;
      })
    },
    // 控制缩放值
    handleWheel (e) {
      if (e.ctrlKey || e.metaKey) {
        e.preventDefault();
        const nextScale = parseFloat(
          Math.max(0.2, this.scale - e.deltaY / 500).toFixed(2)
        );
        this.scale = nextScale;
      }
      this.$nextTick(() => {
        this.handleScroll();
      });
    },
    // 初始化标尺数值
    initSize () {
      // 滚动居中
      let containerRect = this.$refs.containerRef.getBoundingClientRect()
      this.$refs.screensRef.scrollLeft = containerRect.width / 2 - this.thick * 2
      this.$refs.screensRef.scrollTop = containerRect.height / 2 - this.thick * 2
      this.$nextTick(() => {
        this.handleScroll();
      });
    },
    selectNav (item) {
      if (this.isKeysCtrl) {
        if (Array.isArray(item)) {
          this.active = this.active.concat(item)
        } else {
          this.active.push(item);
        }
      } if (Array.isArray(item)) {
        this.active = item;
        this.activeIndex = item[item.length - 1];
      } else if (this.active.includes(item)) {
        this.activeIndex = item;
      } else {
        this.active = [item];
        this.activeIndex = item;
      }
    },
    recordHistoryCache (val) {
      const debounce = (func, delay) => {
        return () => {
          let context = this;
          let args = arguments;
          clearTimeout(this.cacheList.timer);
          this.cacheList.timer = setTimeout(() => {
            func.apply(context, args);
          }, delay);
        }
      }
      const callback = () => {
        try {
          let nav = JSON.stringify(val)
          if (nav != this.cacheList.nav) {
            this.cacheList.nav = nav
            this.addHistoryCache(val)
          }
        } catch { }
      }
      debounce(callback, 300)()
    },
    addHistoryCache (val) {
      if (this.currentHistoryIndex + 1 < this.cacheList.history.length) {
        this.cacheList.history.splice(this.currentHistoryIndex + 1)
      }
      this.cacheList.history.push({
        nav: this.deepClone(val),
        timestamp: Date.now()
      })
      this.cacheList.history.splice(100)
      this.currentHistoryIndex++
    },
    editorUndo () {
      if (!this.canUndo) {
        this.$message.warning('暂无可后退操作')
        return
      }
      this.currentHistoryIndex--
      this.recoveryHistoryCache()
    },
    editorRedo () {
      if (!this.canRedo) {
        this.$message.warning('暂时无可前进操作')
        return
      };
      this.currentHistoryIndex++
      this.recoveryHistoryCache()
    },
    recoveryHistoryCache () {
      const prevState = this.cacheList.history[this.currentHistoryIndex]
      this.nav = this.deepClone(prevState.nav)
      this.cacheList.nav = JSON.stringify(prevState.nav)
    },

    // 新增：跳转到指定历史记录索引
    goToHistoryIndex (targetIndex) {
      if (targetIndex < 0 || targetIndex >= this.cacheList.history.length) {
        this.$message.warning('无效的历史记录索引')
        return
      }

      if (targetIndex === this.currentHistoryIndex) {
        this.$message.info('已经是当前状态')
        return
      }

      const oldIndex = this.currentHistoryIndex
      this.currentHistoryIndex = targetIndex
      this.recoveryHistoryCache()

      const operation = targetIndex > oldIndex ? '前进' : '后退'
      this.$message.success(`已${operation}到历史记录 ${targetIndex + 1}`)
    },

    // 新增：清空历史记录
    clearHistory () {
      // 保留当前状态作为唯一的历史记录
      const currentState = {
        nav: this.deepClone(this.nav),
        timestamp: Date.now()
      }

      this.cacheList.history = [currentState]
      this.currentHistoryIndex = 0
      this.cacheList.nav = JSON.stringify(this.nav)

      this.$message.success('历史记录已清空')
    },

    // 新增：获取历史记录摘要信息
    getHistorySummary () {
      return {
        total: this.cacheList.history.length,
        current: this.currentHistoryIndex + 1,
        canUndo: this.canUndo,
        canRedo: this.canRedo
      }
    }
  }
}
</script>
<style lang="scss">
@import '@/styles/style.scss';
@import '@/styles/list.scss';

// 构建页面布局调整，为底部工具栏留出空间
.build {
  height: 100vh;
  display: flex;
  flex-direction: column;

  .app {
    flex: 1;
    min-height: 0; // 防止 flex 子元素溢出
  }
}
</style>
