<template>
  <div class="props">
    <t-space direction="vertical" class="py-16 w-full">

    <div class="form-item px-16">
      <label style="width: 50px">ID</label>
      <t-input
        class="w-full"
        placeholder="ID"
        :value="props.pen.id"
        @change="changeID($event)"
      />
    </div>
    </t-space>
    <t-collapse
      :defaultValue="['1', '2', '3','4', '7']"
      expandIconPlacement="right"
      :borderless="true"
    >
    <t-collapse-panel  v-if="props.pen.formId" value="7" header="表单">
          <!-- 表单子图元 -->
          <div class="form-item px-12">
            <label title="所属表单">所属表单 </label>
            <div class="ml-8" :title="leaderPen?.id">{{ leaderPen?.description||leaderPen?.name }}</div>
          </div>
          <div class="form-item px-12">
            <label>表单key </label>
            <t-input
              class="w-full"
              v-model="props.pen.formKey"
              @change="changeValue('formKey')"
            />
          </div>
          <div class="form-item px-12">
            <label>表单value </label>
            <t-input
              class="w-full"
              v-model="props.pen.formValue"
              @change="changeValue('formValue')"
            />
          </div>
          <div class="form-item px-12">
            <label>表单类型 </label>
            <t-select
              class="w-full"
              v-model="props.pen.formType"
              placeholder="选择变量"
            >
            <t-option key="submit" value="submit" label="提交"/>
            <t-option key="reset" value="reset" label="重置"/>
          </t-select>
          </div>
      </t-collapse-panel>
      <!-- <t-collapse-panel value="1" header="通信">
        <t-space direction="vertical" size="small" class="w-full">
          <div class="form-item">
            <label title="http地址">http地址 </label>
            <t-input
              class="w-full"
              v-model="props.pen.apiUrl"
              @change="changeValue('apiUrl')"
            />
          </div>
          <div class="form-item">
            <label title="请求方式">请求方式</label>
            <t-select
              v-model="props.pen.apiMethod"
              @change="changeValue('apiMethod')"
            >
              <t-option key="GET" value="GET" label="GET" />
              <t-option key="POST" value="POST" label="POST" />
            </t-select>
          </div>
          <div class="form-item">
            <label title="请求头">请求头</label>
            <t-button
              class="ml-8"
              shape="square"
              variant="outline"
              style="width: 24px"
              @click="preShowPropsEdit('apiHeaders')"
            >
              <ellipsis-icon slot="icon"/>
          </t-button>
          </div>
          <div class="form-item" v-if="props.pen.apiMethod === 'POST'">
            <label title="请求体">请求体</label>
            <t-button
              class="ml-8"
              shape="square"
              variant="outline"
              style="width: 24px"
              @click="preShowPropsEdit('apiBody')"
            >
              <ellipsis-icon slot="icon"/>
            </t-button>
          </div>
          <div class="form-item">
            <label title="开启轮询">开启轮询</label>
            <t-switch
              class="mt-8 ml-8"
              v-model="props.pen.apiEnable"
              size="small"
              @change="changeValue('apiEnable')"
            />
          </div>
        </t-space>
      </t-collapse-panel> -->
      <!-- <t-collapse-panel v-if="props.pen.props.custom" value="2" header="属性">
        <t-space direction="vertical" size="small" class="w-full">
          <div v-for="item in props.pen.props.custom" class="form-item">
            <label :title="item.label">{{ item.label }}</label>
            <t-checkbox
              class="ml-8"
              v-if="item.type === 'bool'"
              v-model="props.pen[item.key]"
              @change="changeValue(item.key)"
            />
            <t-input-number
              class="w-full"
              v-else-if="item.type === 'number'"
              v-model.number="props.pen[item.key]"
              theme="column"
              :max="item.max"
              :min="item.min"
              @change="changeValue(item.key)"
              :placeholder="item.placeholder"
              :allowInputOverLimit="false"
              :decimalPlaces="2"
            />
            <t-color-picker
              class="w-full"
              v-else-if="item.type === 'color'"
              :enable-alpha="true"
              :recent-colors="null"
              format="CSS"
              :swatch-colors="defaultPureColor"
              :color-modes="['monochrome']"
              :show-primary-color-preview="false"
              v-model="props.pen[item.key]"
              @change="changeValue(item.key)"
              :placeholder="item.placeholder"
            />
            <t-select
              class="w-full"
              v-else-if="item.type === 'select'"
              size="small"
              :options="item.options"
              v-model="props.pen[item.key]"
              @change="changeValue(item.key)"
              :placeholder="item.placeholder"
            />
            <t-button
              class="ml-8"
              v-else-if="item.type === 'code'"
              shape="square"
              variant="outline"
              style="width: 24px"
              @click="showDrawer(item)"
            >
              <ChevronLeftDoubleIcon slot="icon"/>
            </t-button>
            <t-slider
              v-else-if="item.type === 'slider'"
              v-model="props.pen[item.key]"
              :min="0"
              :max="1"
              :step="0.01"
              @change="changeValue(item.key)"
            />
            <t-switch
              size="small"
              class="mt-8 ml-8"
              v-else-if="item.type === 'switch'"
              v-model="props.pen[item.key]"
              @change="changeValue(item.key)"
            />
            <t-input
              class="w-full"
              v-else
              v-model="props.pen[item.key]"
              @change="changeValue(item.key)"
              :placeholder="item.placeholder"
            />
          </div>
        </t-space>
      </t-collapse-panel> -->
      <t-collapse-panel value="4" header="设置" v-if="props.pen.name==='tablePlus'">
        <div class="form-item py-8">
          <label class="label">数据源</label>
          <t-select
            v-model="dataSource"
            placeholder="请选择"
            @change="getDataSource"
          >
            <t-option key="api" value="api"  label="API接口"/>
            <t-option key="csv" value="csv"  label="CSV文件"/>
            <t-option key="excel" value="excel"  label="从Excel导入"/>
            <t-option key="sql" value="sql"  label="SQL数据库"/>
          </t-select>
        </div>
        <div class="t-space-item" v-if="props.pen.name==='tablePlus'">
          <div v-if="cell.row!==undefined" class="flex between form-item  py-12">
              <div  v-if="cell.col!==undefined"  style="line-height: 30px">
                {{$t( '当前选中单元格' )}}  ({{$t( '第' )}}{{ props.pen.colHeaders? cell.row:cell.row+1 }}{{$t( '行' )}}，{{$t( '第' )}}{{ cell.col}}{{$t( '列' )}})
              </div>
              <div v-else style="line-height: 30px">
                {{$t( '当前选中行' )}}  ({{$t( '第' )}}{{ props.pen.colHeaders? cell.row:cell.row+1 }}{{$t( '行' )}})
              </div>
              <div>
                <t-tooltip placement="top" :content="$t('快捷绑定')">
                 <link-icon style="width: 13px;margin-right: 26px" class="hover ml-4" @click="onQuickBind()"></link-icon>
                </t-tooltip>
              </div>
          </div>
        <div class="form-item py-8" v-if="props.pen.dbid">
          <label>自动保存 
            <t-tooltip content="编辑表格后会自动保存到sql数据库" placement="top">
              <HelpCircleIcon style="font-size: 12px" class="ml-2"/>
            </t-tooltip>
          </label>
          <t-switch size="small" style="margin:8px 8px" v-model="props.pen.autoSave" />
        </div>
        <div class="form-item py-8">
          <label>可编辑
            <t-tooltip content="表格可以在运行时被编辑" placement="top">
              <HelpCircleIcon style="font-size: 12px" class="ml-2"/>
            </t-tooltip>
          </label>
          <t-switch size="small" style="margin:8px 8px" v-model="props.pen.input" />
        </div>
        <div class="form-item py-8" v-if="props.pen.columns?.length">
          <label>不可编辑列</label>
          <t-select
            @change="changeColumns"
            v-model="props.pen.notEdit"
            :options="props.pen.columns.map(item=>{return {key:item.colKey,value:item.text}})"
            multiple
          />
        </div>
        </div>
      </t-collapse-panel>
      <t-collapse-panel value="3" header="数据">
        <!-- <div class="t-space-item">
          <div class="form-item  py-12">
              <label style="width: 76px">{{$t('关联设备')}}</label>
              <t-input class="w-full" v-model="props.pen.deviceId" @change="changeValue('deviceId')" :placeholder="$t('设备ID')"></t-input>
          </div>
        </div> -->
        <template  v-if="props.pen.name==='tablePlus'">
        <div class="t-space-item">
          <div v-if="cell.row!==undefined" class="flex between form-item  py-12">
              <div  v-if="cell.col!==undefined"  style="line-height: 30px">
                选中单元格  (第{{ cell.row }}行，第{{ cell.col}}列)
              </div>
              <div v-else style="line-height: 30px">
                选中行  (第{{ cell.row }}行)
              </div>
              <div>
                <t-tooltip content="快捷绑定" placement="top">
                 <link-icon style="width: 13px;margin-right: 26px"class="hover ml-4" @click="onQuickBind()"/>
                </t-tooltip>
              </div>
          </div>
        </div>
        </template>
        <div
          class="real-times"
          v-if="props.pen.realTimes && props.pen.realTimes.length||pen.children?.length"
        >
          <div class="grid head">
            <div class="title">{{$t('数据名')}}</div>
            <div class="title">{{$t('值')}}</div>
            <!-- <div class="title" style="text-align: center;">{{$t('绑定')}}</div> -->
            <div class="title" style="text-align: center;">{{$t('操作')}}</div>

            <!-- <div class="actions">
              <more-icon />
            </div> -->
          </div>
          <div class="grid" v-for="(item, i) in props.pen.realTimes">
            <t-tooltip :content="item.key" placement="top">
              <label class="label">{{ item.label }}</label>
            </t-tooltip>
            <div class="value">
              <t-input
                v-if="item.type === 'integer'"
                v-model.number="props.pen[item.key]"
                :placeholder="$t('整数')"
                @change="changeValue(item.key)"
              />
              <t-input-number
                v-else-if="item.type === 'float'"
                v-model="props.pen[item.key]"
                :placeholder="$t('浮点数')"
                theme="normal"
                @change="changeValue(item.key)"
              />
              <t-switch
                v-else-if="item.type === 'bool'"
                v-model="props.pen[item.key]"
                class="ml-8"
                size="small"
                @change="changeValue(item.key)"
              />
              <t-button
                v-else-if="item.type === 'array' || item.type === 'object'"
                variant="outline"
                style="padding: 0px 2px 0 4px; margin: 0 4px"
                @click="editObject(item)"
              >
                <ellipsis-icon />
                <!-- <t-icon name="ellipsis" /> -->
              </t-button>
              <t-input v-else v-model="props.pen[item.key]" @change="changeValue(item.key)" :placeholder="$t('字符串')"></t-input>

             
            </div>
            <div class="flex"> 
            <div class="mr-8" style="text-align: center;">
              <t-tooltip :content="getBindsDesc(item)" placement="top">
                <link-icon class="hover ml-4"
                  :class="{ primary: item.enableMock || item.bind?.id }"
                  @click="onBind(item)"/>
              </t-tooltip>
            </div>
            <div class="mr-8" @click="gotoTrigger(item.trigger)" style="text-align: center;">
              <t-tooltip :content="item.trigger!==undefined?'配置了状态':''" placement="top">
                <ErrorCircleIcon class="hover"  :class="{ primary: item.trigger!==undefined }" />
              </t-tooltip>
            </div>
            <div style="text-align: center;">
              <!-- <t-tooltip :content="item.triggers?.length || '状态'">
                <t-badge
                  :count="item.triggers?.length"
                  size="small"
                  dot
                  :offset="[0, 5]"
                >
                  <relativity-icon  class="hover"
                    @click="onTrigger(item)"/>
                </t-badge>
              </t-tooltip> -->
                <t-dropdown
                  @click="addTrigger(item, $event, i)"
                  :minColumnWidth="120"
                >
                  <!-- <ViewListIcon class="hover"/> -->
                  <MoreIcon class="hover"/>
                  <template #dropdown>
                    <t-dropdown-menu >
                      <t-dropdown-item v-for="(option) in triggerOptions" :value="option.value">
                        {{ option.content  }}
                        <t-divider v-if="option.divider"></t-divider>
                        <check-icon class="ml-16" v-show="option.value === 'mock' && item.enableMock" />
                      </t-dropdown-item> 
                    </t-dropdown-menu>
                  </template>
                </t-dropdown>
            </div>
          </div>
            <!-- <div class="actions">
              <t-dropdown
                :options="moreOptions"
                @click="onMenuMore($event, item, i)"
                :minColumnWidth="80"
              >
                <more-icon class="more hover" />
              </t-dropdown>
            </div> -->
          </div>
          <div class="mt-8 pb-16">
            <t-dropdown
              :options="options"
              @click="addRealTime"
              :minColumnWidth="150"
            >
              <a class="ml-12">
                <add-rectangle-icon />
                <!-- <t-icon name="add-rectangle" />  -->
                {{$t('添加动态数据')}}
              </a>
            </t-dropdown>
          </div>
        </div>
        <div class="flex column center blank" v-else>
          <img src="/img/blank.png">
          <div class="gray center">{{$t('还没有动态数据')}}</div>
          <div class="mt-8">
            <t-dropdown
              :options="options"
              @click="addRealTime"
              :minColumnWidth="150"
            >
              <t-button style="height: 30px"> 添加动态数据 </t-button>
            </t-dropdown>
          </div>
        </div>
        <div v-if="props.pen.children?.length" class="c-titile">
          <t-tooltip :content="$t('ctrl+shift+点击，可选中子图元')">
            {{$t('图元结构')}}
          </t-tooltip>
        </div>
        <template v-for="(cPen) in childrenPens">
          <div
          class="real-times"
        >
          <div class="flex mt-8 mb-8 between">
            <div> {{ cPen.description||cPen.name }}</div>
            <t-dropdown
              :options="options"
              @click="addCRealTime($event,cPen)"
              :minColumnWidth="150"
            >
              <a class="ml-12">
                <add-rectangle-icon></add-rectangle-icon>
                {{$t('添加动态数据')}}
              </a>
            </t-dropdown>
          </div>
          <div class="grid" v-for="(item, i) in cPen.realTimes">
            <t-tooltip :content="item.key" placement="top">
              <label class="label">{{ item.label }}</label>
            </t-tooltip>
            <div class="value">
              <t-input
                v-if="item.type === 'integer'"
                v-model.number="cPen[item.key]"
                :placeholder="$t('整数')"
                @change="changeCValue(item.key,cPen)"
              />
              <t-input-number
                v-else-if="item.type === 'float'"
                v-model="cPen[item.key]"
                :placeholder="$t('浮点数')"
                theme="normal"
                @change="changeCValue(item.key,cPen)"
              />
              <t-switch
                v-else-if="item.type === 'bool'"
                v-model="cPen[item.key]"
                class="ml-8"
                size="small"
                @change="changeCValue(item.key,cPen)"
              />
              <t-button
                v-else-if="item.type === 'array' || item.type === 'object'"
                variant="outline"
                style="padding: 0px 2px 0 4px; margin: 0 4px"
                @click="editCObject(item,cPen)"
              >
                <ellipsis-icon />
              </t-button>
              <t-input
                v-else
                v-model="cPen[item.key]"
                :placeholder="$t('字符串')"
                @change="changeCValue(item.key,cPen)"
              />


            </div>
            <div style="text-align: center;">
              <t-tooltip :content="getBindsDesc(item)" placement="top">
                <link-icon class="hover ml-4"
                  :class="{ primary: item.enableMock || item.bind?.id }"
                  @click="onBind(item)"/>
              </t-tooltip>
            </div>
            <!-- <div>
              <t-tooltip :content="item.triggers?.length || '状态'">
                <t-badge
                  :count="item.triggers?.length"
                  size="small"
                  dot
                  :offset="[0, 5]"
                >
                  <relativity-icon  class="hover"
                    @click="onTrigger(item)"/>
                </t-badge>
              </t-tooltip>
            </div> -->
            <div class="actions" style="text-align: center;">
              <t-dropdown
                :options="moreOptions"
                @click="onCMenuMore($event, item, i, cPen)"
                :minColumnWidth="80"
              >
                <ViewListIcon class="hover"/>
              </t-dropdown>
            </div>
          </div>
         
        </div>
        </template>
      </t-collapse-panel>
    </t-collapse>
  </div>
  <!-- <t-drawer 
    v-model:visible="drawer.visible" 
    :header="drawer.header" 
    cancelBtn="关闭"
    confirmBtn="运行"
    @confirm="onConfirmDrawer"
    :closeOnOverlayClick="false" 
    :sizeDraggable="true"
    >
    <div style="height:100%">
      <CodeEditor
        style="height: 100%"
        :key="drawer.randomkey"
        :json="true"
        :language="'json'"
        v-model="drawer.value"
      />
    </div>
    <div class="gray" style="font-size: 12px">
      {{ drawer.placeholder }}
    </div>
    </t-drawer> -->
  <t-dialog
    v-if="addDataDialog.show"
    :visible="true"
    class="data-dialog"
    :header="addDataDialog.header"
    @close="addDataDialog.show = false"
    @confirm="onConfirmData"
  >
    <div class="form-item mt-16">
      <label>{{$t('数据名')}}</label>
      <t-input v-model="addDataDialog.data.label" :disabled="!!addDataDialog.data.keywords" @blur="onChangeLabel" :placeholder="$t('简短描述')"></t-input>
    </div>
    <div class="form-item mt-16">
      <label>{{$t('属性名')}}</label>
      <t-input v-model="addDataDialog.data.key" @blur="onKeyBlur" :disabled="!!addDataDialog.data.keywords" :placeholder="$t('关键字')"></t-input>
    </div>
    <div class="form-item mt-16">
      <label>{{$t('类型')}}</label>
      <t-select class="w-full" :options="typeOptions" v-model="addDataDialog.data.type" :disabled="!!addDataDialog.data.keywords" @change="onKeyBlur" :placeholder="$t('字符串')"></t-select>
    </div>
  </t-dialog>

  <t-dialog
    v-if="dataBindDialog.show"
    :visible="true"
    class="data-link-dialog"
    :header="$t('动态数据设置')"
    @close="
      dataBindDialog.datasetList = undefined;
      dataBindDialog.show = false;
    "
    @confirm="dataBindonConfirm"
    :top="70"
    :width="700"
  >
    <div class="form-item" style="height: 32px;">
      <label>当前绑定：</label>
      <div class="label" v-if="dataBindDialog.data.bind?.id">
        <t-tooltip :content="dataBindDialog.data.bind?.id">
          <t-tag class="mr-8 mb-8" closable @close="onRemoveBind()">
            {{ dataBindDialog.data.bind?.label }}
          </t-tag>
        </t-tooltip>
      </div>
      <div class="label gray" v-else>无</div>
    </div>
    <template v-if="!old">
      <div class="input-search mb-8 mt-8" style="padding:0px;">
        <div class="btn" style="left:10px">
          <img style="margin-top: 7px" src="/img/icon_search_gray.svg" />
        </div>
        <t-input
          style="height: 32px;"
          v-model="bindSearch"
          @change="onSearchBind"
          @enter="onSearchBind"
          placeholder="搜索绑定变量"
        />
      </div>
      <t-tree 
        style="height:420px;overflow:auto; scrollbar-width: thin;" 
        v-model="dataBindDialog.selectedIds" 
        :activeMultiple="false" 
        :data="bindTreeData"
        :expand-level="1"
        :checkable="true" 
        :checkStrictly="false" 
        allow-fold-node-on-filter
        :filter="bindFilter"
        @change="doBind"
      />
    </template>
    <template v-else>
        <div class="form-item flex middle mt-8">
          <t-input
            style="width:250px;"
            placeholder="搜索"
            v-model="dataBindDialog.input"
            @change="onSearchDataset"
            @enter="onSearchDataset"
          >
            <template #suffixIcon>
              <search-icon class="hover" @click="onSearchDataset"/>
            </template>
          </t-input>
        </div>
        <t-table
          class="mt-12 data-list"
          row-key="id"
          :data="dataBindDialog.dataset"
          :columns="dataSetColumns"
          size="small"
          bordered
          rowSelectionAllowUncheck
          :loading="dataBindDialog.loading"
          :pagination="query"
          @page-change="onChangePagination"
          :selected-row-keys="dataBindDialog.selectedIds"
          @select-change="onSelectBindsChange"
          :max-height="270"
        >
        </t-table>
     </template>
  </t-dialog>
  <t-dialog
    v-if="dataMockDialog.show"
    :visible="true"
    class="data-link-dialog"
    header="本地调试"
    @close="dataMockDialog.show = false;"
    @confirm="dataMockDialog.show = false;"
    :top="70"
    :width="700"
  >
    <div class="form-item mt-20">
      <label>模拟值：</label>
      <t-input v-model="dataMockDialog.data.mock" />
    </div>
    <div class="form-item mt-20">
      <label>类型：</label>
      <t-select
        class="w-full"
        :options="typeOptions"
        v-model="dataMockDialog.data.type"
        placeholder="字符串"
      />
    </div>
    <div class="form-item mt-12">
      <label>开启：</label>
      <t-switch
        class="mt-8"
        size="small"
        v-model="dataMockDialog.data.enableMock"
      />
    </div>
    <h6 class="desc mt-20" style="font-size: 13px;">模拟值说明</h6>
    <ul class="desc mt-4" style="list-style-type: none;">
      <li class="mt-4">
        <label class="inline" style="width: 80px">固定值：</label>
        直接填写，例如：10
      </li>
      <li class="mt-4">
        <label class="inline" style="width: 80px">随机值：</label>
        值1,值2,...。例如：1,2,3,4,5
      </li>
      <li class="mt-4">
        <label class="inline" style="width: 80px">范围数字：</label>
        最小值-最大值。例如：0-1.0 或 0-100
      </li>
      <li class="mt-4">
        <label class="inline" style="width: 80px">随机字符串：</label>
        [长度]。例如：[8]
      </li>
    </ul>
  </t-dialog>
  <t-dialog
    v-if="triggersDialog.show"
    :visible="true"
    class="data-events-dialog"
    :header="$t('数据状态')"
    @confirm="triggersDialog.show = false"
    @close="triggersDialog.show = false"
    :width="700"
  >
    <div class="body">
      <t-collapse
        v-model="triggersDialog.openedCollapses"
        :borderless="true"
        :expand-on-row-click="false"
      >
        <t-collapse-panel
          v-for="(trigger, i) in triggersDialog.data.triggers"
          :value="i"
        >
          <template #header>
            <t-input v-model="trigger.name" class="mr-12" />
          </template>
          <template #headerRightContent>
            <t-popconfirm @confirm="triggersDialog.data.triggers.splice(i, 1)" :content="$t('确认删除该状态吗？')">
              <delete-icon class="hover"></delete-icon>
              <!-- <t-icon name="delete" class="hover" /> -->
            </t-popconfirm>
          </template>
          <section>
            <div class="form-item banner">
              <label>{{$t('满足条件')}}</label>
              <div class="w-full flex middle between">
                <div></div>
                <t-radio-group v-model="trigger.conditionType">
                  <t-radio value="and"> {{$t('所有')}} </t-radio>
                  <t-radio value="or"> {{$t('任意')}} </t-radio>
                </t-radio-group>
              </div>
            </div>
            <div v-for="(c, index) in trigger.conditions" class="mb-12">
              <div class="flex middle between head">
                <div class="flex middle">
                  <arrow-right-icon class="mr-4"/>
                  <!-- <t-icon name="arrow-right" class="mr-4" /> -->
{{$t('                  条件')}}{{ index + 1 }}
                </div>
                <close-icon  class="hover"
                  @click="trigger.conditions.splice(index, 1)"/>
                <!-- <t-icon
                  name="close"
                  class="hover"
                  @click="trigger.conditions.splice(index, 1)"
                /> -->
              </div>
              <div class="px-16 py-4">
                <div class="form-item mt-4">
                  <label>{{$t('条件类型')}}</label>
                  <t-radio-group v-model="c.type">
                    <t-radio value> {{$t('关系条件')}} </t-radio>
                    <t-radio value="fn"> {{$t('高级条件')}} </t-radio>
                  </t-radio-group>
                </div>
                <template v-if="!c.type">
                  <div class="form-item mt-8">
                    <label>{{$t('比较条件')}}</label>
                    <div class="flex middle">
                      <label class="shrink-0 mr-8">{{$t('数据')}}</label>
                      <t-select v-model="c.operator" :options="operatorOptions" class="shrink-0 mr-8" style="width: 80px" :placeholder="$t('关系运算')"></t-select>
                      <t-select v-model="c.valueType" class="shrink-0 mr-8" style="width: 110px" :placeholder="$t('固定值')">
                        <t-option key value :label="$t('固定值')">
                          {{$t('固定值')}}
                        </t-option>
                        <t-option key="prop" value="prop" :label="$t('对象属性值')">
                          {{$t('对象属性值')}}
                        </t-option>
                      </t-select>
                      <template v-if="!c.valueType">
                        <t-input
                          @change="valueChange($event,c)"
                          v-model="c.value"
                          class="shrink-0"
                          style="width: 320px"
                        />
                      </template>
                      <template v-else>
                        <t-tree-select
                          v-model="c.target"
                          :data="penTree"
                          filterable
                          :placeholder="$t('对象')"
                          class="shrink-0 mr-8"
                          style="width: 160px"
                          @change="onChangeTriggerTarget(c)"
                        />
                        <t-select-input
                          v-model:inputValue="c.value"
                          :value="c.label"
                          v-model:popupVisible="c.popupVisible"
                          allow-input
                          clearable
                          @clear="c.label = undefined"
                          @focus="c.popupVisible = true"
                          @blur="c.popupVisible = false"
                          @input-change="onInput(c)"
                          class="shrink-0"
                          style="width: 152px"
                        >
                          <template #panel>
                            <ul style="padding: 8px 12px">
                              <li
                                v-for="item in cProps"
                                :key="item.value"
                                @click="
                                  c.value = item.value;
                                  c.label = item.label;
                                  c.popupVisible = false;
                                "
                              >
                                {{ item.label }}
                              </li>
                            </ul>
                          </template>
                        </t-select-input>
                      </template>
                    </div>
                  </div>
                </template>
                <template v-else>
                  <div>function condition(pen) {</div>
                  <CodeEditor class="mt-4" @change="codeChange($event,c)" v-model="c.fnJs" />
                  <div class="mt-4">}</div>
                </template>
              </div>
            </div>
            <div class="mt-8">
              <a @click="addTriggerCondition(trigger)"> + {{$t('添加条件')}} </a>
            </div>

            <div class="form-item banner mt-16">
              <label>{{$t('执行动作')}}</label>
            </div>
            <Actions class="mt-8" :data="trigger" />
          </section>
        </t-collapse-panel>
      </t-collapse>

      <div class="mt-8">
        <!-- <a @click="onAddTrigger"> + 添加状态 </a> -->
        <t-button @click="onAddTrigger" style="width: 100%;" variant="outline">
          <template #icon><add-icon></add-icon></template>
          {{$t('添加状态')}}
        </t-button>
      </div>
    </div>
  </t-dialog>

  <t-dialog v-if="ojbectDialog.show" :visible="true" @confirm="onOkEditOjbect" @close="ojbectDialog.show = false" :width="700" :header="$t('数据编辑')">
    <div class="py-8">
      <CodeEditor
        :json="true"
        v-model="ojbectDialog.data"
        style="height: 300px"
      />
    </div>
  </t-dialog>
  <t-dialog
    v-if="propsDialog.show"
    :visible="true"
    :header="propsDialog.header"
    @confirm="onOkPropsEdit"
    @close="propsDialog.show = false"
    :width="700"
  >
    <div class="py-8">
      <CodeEditor
        :json="true"
        :language="'json'"
        v-model="propsDialog.value"
        style="height: 300px"
      />
    </div>
    <div class="gray" style="font-size: 12px">
      {{ propsDialog.placeholder }}
    </div>
  </t-dialog>

  <t-dialog v-if="apiDialog.show" :visible="true" class="data-dialog" @close="apiDialog.show = false" @confirm="onConfirmAPI" :header="$t('API接口')">
  <div class="form-item mt-8">
      <label>http{{$t('地址')}}</label>
      <t-input v-model="apiDialog.url" :placeholder="$t('请输入（临时请求，不会保存）')"></t-input>
    </div>
    <div class="form-item mt-8">
        <label>{{$t('请求方式')}}</label>
        <t-select v-model="apiDialog.method">
          <t-option key="GET" value="GET" label="GET" />
          <t-option key="POST" value="POST" label="POST" />
        </t-select>
      </div>
      <div class="form-item mt-8">
        <label>{{$t('请求头')}}</label>
        <CodeEditor :json="true" :language="'json'" v-model="apiDialog.headers" class="mt-4" style="height: 50px"></CodeEditor>
      </div>
      <div v-if="apiDialog.method === 'POST'" class="form-item mt-8">
        <label>{{$t('请求体')}}</label>
        <CodeEditor :json="true" :language="'json'" v-model="apiDialog.body" class="mt-4" style="height: 50px"></CodeEditor>
      </div>
  </t-dialog>
  <t-dialog
    v-if="sqlDialog.show"
    :visible="true"
    class="data-link-dialog"
    header="绑定sql数据源"
    @close="sqlDialog.show = false;"
    @confirm="sqlConnect"
    :top="70"
    :width="700"
  >
    <div class="form-item  py-12">
        <label style="width: 76px">SQL数据源</label>
        <t-select v-model="sqlDialog.dbid" placeholder="请选择数据源" >
          <t-option v-for="sql in sqlList " @click="sqlChange(sql)" :key="sql.id" :value="sql.id" :label="sql.name+'('+sql.dbType+')'" />
        </t-select>
    </div>
    <div class="form-item mt-8">
        <label>sql语句</label>
        <CodeEditor
          :json="false"
          :language="'sql'"
          v-model="sqlDialog.sql"
          class="mt-4"
          style="height: 100px"
        />
    </div>
    <div class="form-item mt-8">
        <label>第几页</label>
        <t-input-number
          v-model="sqlDialog.current"
          theme="normal"
          :min="1"
          placeholder="默认1"
        />
    </div>
    <div class="form-item mt-8">
        <label>每页数量</label>
        <t-input-number
          v-model="sqlDialog.pageSize"
          theme="normal"
          placeholder="20"
          :min="1"
        />
    </div>
  </t-dialog>
</template>

<script lang="ts" setup>
import {
  getCurrentInstance,
  onBeforeMount,
  onUnmounted,
  reactive,
  ref,
  toRaw,
  watch,
  onMounted,
  computed
} from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { MessagePlugin } from 'tdesign-vue-next';
import axios from 'axios';
import { debounce } from '@/services/debouce';
import { getPenTree, typeOptions, changeType } from '@/services/common';
import { searchPinyin } from '@/services/pinyin';
import { updatePen } from './pen';
import { getter, setter, queryURLParams, deepClone, getAllChildren, Pen } from '@meta2d/core';
import CodeEditor from '@/views/components/common/CodeEditor.vue';
import Actions from './Actions.vue';
import { useSelection } from '@/services/selections';
import { defaultGradientColor, defaultPureColor } from '@/services/defaults';
import { getLe5le3d, getLe5leV, getLe5le2d } from '@/services/api';
import { EllipsisIcon, MoreIcon, LinkIcon, RelativityIcon, AddRectangleIcon, SearchIcon ,DeleteIcon, ArrowRightIcon, CloseIcon, ChevronLeftDoubleIcon, AddIcon, ViewListIcon, CheckIcon, HelpCircleIcon, ErrorCircleIcon } from 'tdesign-icons-vue-next';
import { s8 } from '@/services/random';
import { importExcel } from '@/services/excel';
import { importCSV } from '@/services/file';
import { getDevices, getDeviceProperties,getSqlSourceList, doSqlCode } from '@/services/iot';

const route = useRoute();
const router = useRouter();
const { proxy } = getCurrentInstance();
const $t = proxy.$t
const {
  proxy: { $forceUpdate },
}: any = getCurrentInstance();

const props = defineProps<{
  pen: any;
}>();

const options = ref<any>([
  {
    value: '',
    content: $t('自定义'),
    divider: true,
  },
  {
    value: 'x',
    content: 'X',
    type: 'float',
    keywords: true,
  },
  {
    value: 'y',
    content: 'Y',
    type: 'float',
    keywords: true,
  },
  {
    value: 'width',
    content: $t('宽'),
    type: 'float',
    keywords: true,
  },
  {
    value: 'height',
    content: $t('高'),
    type: 'float',
    keywords: true,
  },
  {
    value: 'visible',
    content: $t('显示'),
    type: 'bool',
    keywords: true,
  },
  {
    value: 'text',
    content: $t('文字'),
    // keywords: true,
  },
  {
    value: 'deviceId',
    content: '关联设备',
    keywords: true,
  },
  {
    value: 'progress',
    content: $t('进度'),
    type: 'float',
    keywords: true,
  },
  {
    value: 'showChild',
    content: $t('状态'),
    type: 'integer',
    keywords: true,
  },
  {
    value: 'rotate',
    content: $t('旋转'),
    type: 'integer',
    keywords: true,
  },
]);

const moreOptions = ref<any>([
  {
    value: 'view',
    content: $t('查看状态'),
  },
  {
    value: 'custom',
    content: $t('自定义状态'),
    divider: true
  },
  {
    value: 'edit',
    content: $t('编辑'),
  },
  {
    value: 'delete',
    content: $t('移除'),
  },
]);

const addDataDialog = reactive<any>({
  show: false,
  data: undefined,
});

const dataBindDialog = reactive<any>({
  show: false,
  data: undefined,
});

const dataMockDialog = reactive<any>({
  show: false,
  data: undefined,
});

const ojbectDialog = reactive<any>({
  show: false,
  data: undefined,
});

const dataSetColumns = [
  {
    colKey: 'row-select',
    type: 'single',
    width: 50,
  },
  // {
  //   colKey: 'device',
  //   title: $t('设备'),
  //   ellipsis: { theme: 'light', trigger: 'context-menu' },
  // },
  {
    colKey: 'label',
    title: $t('显示名称'),
    // ellipsis: false,
    ellipsis:{overlayClassName:'le-table-popup'}
  },
  {
    colKey: 'id',
    title: $t('变量名'),
    // ellipsis: false,
    ellipsis:{overlayClassName:'le-table-popup'}
  },
  {
    colKey: 'type',
    title: $t('类型'),
    width: 100,
  },
  {
    colKey: 'mock',
    title: $t('值范围'),
    ellipsis: true,
  },
];

const operatorOptions = ref<any>([
  { label: '=', value: '=' },
  { label: '!=', value: '!=' },
  { label: '>', value: '>' },
  { label: '<', value: '<' },
  { label: '>=', value: '>=' },
  { label: '<=', value: '<=' },
  { label: $t('包含'), value: '[)' },
  { label: $t('不包含'), value: '![)' },
]);

const cProps = [
  {
    value: 'x',
    label: 'X',
  },
  {
    value: 'y',
    label: 'Y',
  },
  {
    value: 'width',
    label: $t('宽'),
  },
  {
    value: 'height',
    label: $t('高'),
  },
  {
    value: 'visible',
    label: $t('显示'),
  },
  {
    value: 'text',
    label: $t('文字'),
  },
  {
    value: 'color',
    label: $t('颜色'),
  },
  {
    value: 'background',
    label: $t('背景颜色'),
  },
  {
    value: 'progress',
    label: $t('进度'),
  },
  {
    value: 'progressColor',
    label: $t('进度颜色'),
  },
  {
    value: 'showChild',
    label: $t('状态'),
  },
  {
    value: 'checked',
    label:  $t('选中'),
  },
  {
    value: 'rotate',
    label: $t('旋转'),
  },
  {
    value: 'disabled',
    label: $t('禁用'),
  },
  {
    value: 'selectedKey',
    label: $t('单选选中值'),
  },
  {
    value: 'animateReverse',
    label: $t('连线动画反向'),
  }
];

const query = reactive<{
  current: number;
  pageSize: number;
  total: number;
  range: any[];
}>({
  current: 1,
  pageSize: 10,
  total: 0,
  range: [],
});

const triggersDialog = reactive<any>({
  show: false,
  data: undefined,
});

const penTree: any = ref([]);

let timer: any;

const changeID = (value: any) => {
  if (!value) {
    // initPenData();
    MessagePlugin.error('id 不能为空');
    return;
  }
  const oldID: string = props.pen.id;
  try {
    meta2d.changePenId(oldID, value);
    // initPenData();
  } catch (error) {
    console.warn(error.message);
    MessagePlugin.error('id 修改失败，请检查 id 是否重复');
    return;
  }
};

onBeforeMount(() => {
  // realTimesOptions - 扩展的动态数据下拉列表
  if (props.pen.realTimesOptions) {
    options.value[options.value.length - 1].divider = true;
    options.value.push(...props.pen.realTimesOptions);
  }

  timer = setInterval($forceUpdate, 1000);
});

const addRealTime = (e: any) => {
  if (e.keywords || e.value === 'text') {
    if (!props.pen.realTimes) {
      props.pen.realTimes = [];
    }

    props.pen.realTimes.push({
      label: e.content,
      key: e.value,
      type: e.type,
      keywords: e.keywords,
    });
    return;
  }

  addDataDialog.header = $t('添加动态数据');

  addDataDialog.data = {
    label: e.content,
    key: e.value,
    type: e.type,
    keywords: e.keywords,
  };
  addDataDialog.data.pen = undefined;
  if (e.keywords) {
    addDataDialog.data.label = '';
  }
  addDataDialog.show = true;
};

const onKeyBlur = () => {
  if (addDataDialog.data) {
    let value = getter(props.pen, addDataDialog.data.key);
    if (value) {
      setter(addDataDialog.data, 'value', value);
    } else {
      addDataDialog.data.value = null;
    }
  }
};

const onChangeLabel = () => {
  if (!addDataDialog.data.key) {
    addDataDialog.data.key = addDataDialog.data.label;
  }
};

const onConfirmData = () => {
  const pen = addDataDialog.data.pen || props.pen;
  if (!pen.realTimes) {
    pen.realTimes = [];
  }
  if (!addDataDialog.data.label || !addDataDialog.data.key) {
    MessagePlugin.error($t('数据名或属性名不能为空！'));
    return;
  }
  delete addDataDialog.data.pen;
  if (addDataDialog.header === $t('添加动态数据')) {
    const found = pen.realTimes.findIndex((item: any) => {
      return item.key === addDataDialog.data.key;
    });
    if (found > -1) {
      MessagePlugin.error($t('已经存在相同属性数据！'));
      return;
    }
    if(pen[addDataDialog.data.key] === undefined && addDataDialog.data.key.indexOf('.') !== -1){
      pen[addDataDialog.data.key] = getter(pen, addDataDialog.data.key);
    }
    pen.realTimes.push(addDataDialog.data);
  }

  addDataDialog.show = false;
};

const onMenuMore = (e: any, item: any, i: number) => {
  switch (e.value) {
    case 'edit':
      addDataDialog.header = $t('编辑动态数据');
      setter(item, 'value', getter(props.pen, item.key));
      addDataDialog.data = item;
      addDataDialog.show = true;
      break;
    case 'delete':
      props.pen.realTimes.splice(i, 1);
      meta2d.initBinds();
      break;
    default:
      break;
  }
};

const onBind = (item: any) => {
  dataBindDialog.data = item;
  dataBindDialog.input = '';
  dataBindDialog.selectedIds = [];
  if (item.bind && item.bind.id) {
    dataBindDialog.selectedIds.push(item.bind.id);
  }
  dataBindDialog.show = true;
  if(old){
    getDataset();
  }else{
  // getIotTree();
  // getSqlTree();
    getBindTreeData();
  }
};

const bindTreeData = ref<any>([]);

const getBindTreeData = ()=>{
  let data = [];
  const iotTree = meta2d.store.data.iot?.tree || [];
  if(iotTree.length){
    iotTree.forEach((item:any)=>{
      item.checkable = false;
    });
    data.push({
      label: '物联网平台',
      value: 'iot',
      checkable: false,
      children: iotTree,
    });
  }
  const sqlTree = meta2d.store.data.sqls || [];
  if(sqlTree.length){
    data.push({
      label: 'sql数据源',
      value: 'sql',
      checkable: false,
      children: sqlTree,
    });
  }
  const networks = meta2d.store.data.networks || [];
  if(networks.length){
    networks.forEach((item:any)=>{
      item.checkable = false;
    });
    const mqttNets =  meta2d.store.data.networks.filter((item)=>item.protocol==='mqtt');
    const wsNets =  meta2d.store.data.networks.filter((item)=>item.protocol==='websocket');
    const httpNets =  meta2d.store.data.networks.filter((item)=>item.protocol==='http');
    const SSENets =  meta2d.store.data.networks.filter((item)=>item.protocol==='SSE');
    if(mqttNets.length){
      data.push({
        label: 'MQTT',
        value: 'network',
        checkable: false,
        children: mqttNets,
      });
    }
    if(wsNets.length){
      data.push({
        label: 'Websocket',
        value: 'network',
        checkable: false,
        children: wsNets,
      });
    }
    if(httpNets.length){
      data.push({
        label: 'HTTP',
        value: 'network',
        checkable: false,
        children: httpNets,
      });
    }
    if(SSENets.length){
      data.push({
        label: 'SSE',
        value: 'network',
        checkable: false,
        children: SSENets,
      });
    }
  }
  bindTreeData.value = data;
}

const bindSearch = ref('');
const bindFilter = ref(null);
const onSearchBind = () => {
  bindFilter.value = bindSearch.value ? (node) => { return node.data.label?.indexOf(bindSearch.value) >= 0|| node.data.value?.indexOf(bindSearch.value) >= 0 }: null;
};

const bindValue = ref('');

const doBind = (value:any,context:any)=>{
  // bindValue.value = [context.node.value];
  dataBindDialog.selectedIds = [context.node.value];
  dataBindDialog.data.bind = {
    id: context.node.value,
    label: context.node.data._label|| context.node.data.label,
    class: context.node.data.class,
    token: context.node.data.token,
  }
  meta2d.initBinds();
}

const onSearchDataset = () => {
  debounce(getDataset, 300);
};

const getDataset = async () => {
  // @ts-ignore
  const data: Meta2dBackData = meta2d.data();
  dataBindDialog.sqls = data.sqls;
  if (!data.dataset) {
    return;
  }
  dataBindDialog.dataset = data.dataset.devices;
  dataBindDialog.datasetList = data.dataset.devices;
  if(dataBindDialog.device || dataBindDialog.input){
    dataBindDialog.dataset = dataBindDialog.datasetList.filter(
        (item: any) => {
          if (dataBindDialog.device && item.device !== dataBindDialog.device) {
            return;
          }

          return (
            searchPinyin(item.label, dataBindDialog.input) ||
            item.id.indexOf(dataBindDialog.input) > -1
          );
        }
      );
  }
  query.total = dataBindDialog.dataset.length;
  return;

  dataBindDialog.loading = true;
  if (data.dataset.url) {
    const ret: any = await axios.get(data.dataset.url, {
      params: {
        device: dataBindDialog.device || '',
        q: dataBindDialog.input,
        current: query.current,
        pageSize: query.pageSize,
      },
    });
    dataBindDialog.dataset = ret;
    dataBindDialog.url = true;
    query.total = ret.total;
    console.log( dataBindDialog.dataset,
    query.total);
  } else {
    dataBindDialog.url = false;
    if (!dataBindDialog.datasetList) {
      const ret:any = await axios.post(`/api/data/datasource/get`, {
        id: data.dataset.id,
      });
      if (ret?.data?.devices) {
        data.dataset.data = ret.data.devices;
        dataBindDialog.datasetList = data.dataset.data;
        const set = new Set<string>();
        for (const item of dataBindDialog.datasetList) {
          set.add(item.device);
        }
        dataBindDialog.devices = Array.from(set);
      } else {
        dataBindDialog.dataset = [];
        dataBindDialog.devices = [];
        return;
      }
    }

    if (dataBindDialog.device || dataBindDialog.input) {
      dataBindDialog.dataset = dataBindDialog.datasetList.filter(
        (item: any) => {
          if (dataBindDialog.device && item.device !== dataBindDialog.device) {
            return;
          }

          return (
            searchPinyin(item.label, dataBindDialog.input) ||
            item.id.indexOf(dataBindDialog.input) > -1
          );
        }
      );
      query.total = dataBindDialog.datasetList.length;
    } else {
      dataBindDialog.dataset = [...dataBindDialog.datasetList];
      query.total = dataBindDialog.datasetList.length;
    }
    console.log("dataBindDialog",dataBindDialog,dataBindDialog);
  }
  dataBindDialog.loading = false;
};

const onChangePagination = (pageInfo: any) => {
  // router.push({
  //   path: route.path,
  //   query: { current: pageInfo.current, pageSize: pageInfo.pageSize },
  // });
  query.current = pageInfo.current;
  query.pageSize = pageInfo.pageSize;
  getDataset();
};

const onSelectBindsChange = (value: string[], options: any) => {
  if (options.type === 'check') {
    dataBindDialog.selectedIds = value;
    dataBindDialog.data.bind = toRaw(options.selectedRowData[0]);
    if(dataBindDialog.data.bind.id){
      dataBindDialog.data.enableMock = false;
    }
    dataBindDialog.data.mock = dataBindDialog.data.bind.mock;
    dataBindDialog.data.type = dataBindDialog.data.bind.type;
    doBindInit();
  } else if (options.type === 'uncheck') {
    dataBindDialog.selectedIds = [];
    dataBindDialog.data.bind = {};
  }
};

const doBindInit = () => {
  let { id } = dataBindDialog.data;
  if (props.pen.name === 'echarts' && id?.includes('echarts.option.series')) {
    const { replaceMode } = props.pen.echarts;
    const { xAxis } = props.pen.echarts.option;

    let beforeV = getter(props.pen, id);
    if (Array.isArray(beforeV) && replaceMode === 0) {
      //追加
      setter(props.pen, id, []);
      let _key = 'echarts.option.xAxis.data';
      if (Array.isArray(xAxis) && xAxis.length) {
        _key = 'echarts.option.xAxis.0.data';
      }
      setter(props.pen, _key, []);
    }
  }
};

const dataBindonConfirm = () => {
  dataBindDialog.show = false;
  dataBindDialog.datasetList = undefined;
  meta2d.initBinds();
};

const onRemoveBind = () => {
  dataBindDialog.selectedIds = [];
  dataBindDialog.data.bind = undefined;
};

const getBindsDesc = (item: any) => {
  if (item.bind?.label) {
    return item.bind.label;
  }

  if (item.enableMock && item.mock) {
    return item.mock;
  }

  return $t('绑定变量');
};
const { selections } = useSelection();

const changeValue = (prop: string) => {
  updatePen(props.pen, prop);
  selections.pen[prop] = getter(props.pen, prop);
  if (prop === 'iframe') {
    getThumbImg();
  }
  if(prop === 'apiEnable'){
    meta2d.penNetwork(props.pen);
    meta2d.connectNetwork();
  }
};

const onTrigger = (item: any) => {
  if (!item.triggers) {
    item.triggers = [];
  }
  triggersDialog.openedCollapses = [0];
  triggersDialog.data = item;
  triggersDialog.show = true;

  penTree.value = getPenTree();
};

const onAddTrigger = () => {
  const i = triggersDialog.data.triggers.length;
  triggersDialog.data.triggers.push({
    name: $t(`状态`)+ (i + 1),
    conditionType: 'and',
    conditions: [],
    actions: [],
  });

  triggersDialog.openedCollapses.push(i);
};

const addTriggerCondition = (trigger: any) => {
  trigger.conditions.push({
    type: '',
    operator: '=',
    valueType: '',
  });
};

const onChangeTriggerTarget = (c: any) => {
  /*
  c.targetProps = [
    {
      value: 'x',
      label: 'X',
    },
    {
      value: 'y',
      label: 'Y',
    },
    {
      value: 'width',
      label: $t('宽'),
    },
    {
      value: 'height',
      label: $t('高'),
    },
    {
      value: 'visible',
      label: $t('显示'),
    },
    {
      value: 'text',
      label: $t('文字'),
    },
    {
      value: 'progress',
      label: $t('进度'),
    },
    {
      value: 'showChild',
      label: $t('状态'),
    },
    {
      value: 'rotate',
      label: $t('旋转'),
    },
  ];*/

  const target: any = meta2d.findOne(c.target);
  if (target && target.realTimes) {
    for (const item of target.realTimes) {
      const found = cProps.findIndex((elem: any) => elem.value === item.key);
      if (found < 0) {
        cProps.push({
          value: item.key,
          label: item.label,
        });
      }
    }
  }
};

const onInput = (item: any) => {
  item.label = item.value;
};

const editObject = (item: any) => {
  ojbectDialog.data = props.pen[item.key];
  ojbectDialog.item = item;
  ojbectDialog.pen = undefined;
  ojbectDialog.show = true;
};

const onOkEditOjbect = () => {
  if (ojbectDialog.data) {
    if (
      ojbectDialog.item.type === 'array' &&
      !Array.isArray(ojbectDialog.data)
    ) {
      MessagePlugin.error($t('请输入数组格式数据'));
      return;
    }
    const pen = ojbectDialog.pen || props.pen;
    pen[ojbectDialog.item.key] = deepClone(ojbectDialog.data);
    updatePen(
      pen,
      ojbectDialog.item.key
    );
    ojbectDialog.show = false;
  } else {
    MessagePlugin.error($t('请输入严格的JSON格式数据'));
  }
};

const propsDialog = reactive<any>({
  show: false,
});

// const changeValue = (prop: string) => {
//   updatePen(props.pen, prop);
//   selections.pen[prop] = getter(props.pen, prop);
//   if (prop === 'iframe$t(') {
//     getThumbImg();
//   }
// };

const getThumbImg = async () => {
  //改iframe地址后
  let arr = props.pen.iframe.split('?');
  let id = queryURLParams(arr[1]).id;
  if (!id) {
    return;
  }
  // let projection = {
  //   image: 1,
  //   _id: 1,
  //   name: 1,
  // };
  let projection = 'image,id,name';
  let res: any;
  if (arr[0].indexOf('2d.le5le') !== -1||arr[0].indexOf('le5le.com/2d') !== -1) {
    res = await getLe5le2d(id, projection);
  } else if (arr[0].indexOf('v.le5le') !== -1||arr[0].indexOf('le5le.com/v') !== -1) {
    res = await getLe5leV(id, projection);
  } else if (arr[0].indexOf('3d.le5le') !== -1||arr[0].indexOf('le5le.com/3d') !== -1) {
    res = await getLe5le3d(id, projection);
  }
  if (res) {
    props.pen.thumbImg = res.image;
    props.pen.calculative&&(props.pen.calculative.img = null);
  }
  props.pen.onRenderPenRaw?.(props.pen);
};

const preShowPropsEdit = (key: string) => {
  showPropsEdit({
    key,
    // item: {
    // key,
    type: 'code',
    label: key,
    placeholder: '支持设置动态参数，例如：{"Authorization": "Bearer ${token}"}',
    // },
  });
};

const showPropsEdit = (item: any) => {
  propsDialog.key = item.key;
  propsDialog.header = `${item.label}(${item.key})`;
  propsDialog.value = props.pen[item.key];
  propsDialog.placeholder = item.placeholder;
  propsDialog.show = true;
};

const onOkPropsEdit = () => {
  if (!propsDialog.value) {
    MessagePlugin.error($t('数据不满足json格式'));
    return;
  }
  props.pen[propsDialog.key] = propsDialog.value;
  updatePen(props.pen, propsDialog.key);
  propsDialog.show = false;
};

const codeChange = (e:any,a:any)=>{
  a.fn = null;
}

const valueChange = (e,c:any)=>{
  c.value= changeType(e);
}

const drawer = reactive<any>({
  visible: false,
});

const showDrawer = (item:any)=>{
  drawer.key = item.key;
  drawer.header = `${item.label}(${item.key})`;
  drawer.value = deepClone(props.pen[item.key]);
  drawer.placeholder = item.placeholder;
  drawer.randomkey = s8();//props.pen.id;
  drawer.visible = true;
}

const onConfirmDrawer = () => {
  if (!drawer.value) {
    MessagePlugin.error($t('数据不满足json格式'));
    return;
  }
  props.pen[drawer.key] = drawer.value;
  updatePen(props.pen, drawer.key);
};

const childrenPens = ref([]);

watch(
  () => props.pen.id,
  (newValue) => {
    childrenPens.value = [];
      // childrenKey.value = s8();
    if(props.pen.children?.length){
      childrenPens.value = getAllChildren(meta2d.store.pens[props.pen.id],meta2d.store);
    }
    getRealTimesTrigger();
  }
);

onMounted(() => {
  childrenPens.value = [];
  if(props.pen.children?.length){
    childrenPens.value = getAllChildren(meta2d.store.pens[props.pen.id],meta2d.store);
  }
  getRealTimesTrigger();
});

const getRealTimesTrigger = ()=>{
  if(!props.pen.triggers?.length){
    return;
  }
  props.pen.realTimes?.forEach((real)=>{
    let shouldBreak = false;
    props.pen.triggers.forEach((item,index)=>{
      if (shouldBreak) return;
      item.status.forEach((_item)=>{
        const trigger = _item.conditions.filter((i)=>i.key===real.key);
        if(trigger?.length){
          real.trigger = index;
          shouldBreak = true;
        }
      })
    });
  })
}

const gotoTrigger = (i:any)=>{
  if(i===undefined){
    return;
  }
  emit('tabchange',i);
}

const changeCValue = (prop: string, pen:Pen)=>{
  updatePen(pen, prop);
  selections.pen[prop] = getter(pen, prop);
  if (prop === 'iframe') {
    getThumbImg();
  }
  if(prop === 'apiEnable'){
    meta2d.penNetwork(pen);
    meta2d.connectNetwork();
  }
}

const editCObject = (item: any, pen:Pen) => {
  ojbectDialog.data = pen[item.key];
  ojbectDialog.pen = pen;
  ojbectDialog.item = item;
  ojbectDialog.show = true;
};

const addCRealTime = (e: any, pen:Pen) => {
  if (e.keywords || e.value === 'text') {
    if (!pen.realTimes) {
      pen.realTimes = [];
    }

    pen.realTimes.push({
      label: e.content,
      key: e.value,
      type: e.type,
      keywords: e.keywords,
    });
    return;
  }

  addDataDialog.header = $t('添加动态数据');
  
  addDataDialog.data = {
    label: e.content,
    key: e.value,
    type: e.type,
    keywords: e.keywords,
  };
  addDataDialog.data.pen = pen;
  if (e.keywords) {
    addDataDialog.data.label = '';
  }
  addDataDialog.show = true;
};

const onCMenuMore = (e: any, item: any, i: number, pen:any)=>{
  switch (e.value) {
    case 'edit':
      addDataDialog.header = $t('编辑动态数据');
      setter(item, 'value', getter(pen, item.key));
      addDataDialog.data = item;
      addDataDialog.data.pen = pen;
      addDataDialog.show = true;
      break;
    case 'delete':
      pen.realTimes.splice(i, 1);
      meta2d.initBinds();
      break;
    case 'custom':
      if(!pen.triggers){
        pen.triggers = [];
      }
      pen.triggers.push({
        name: $t(`状态场景`) + (pen.triggers.length + 1),
        status:[
          {
            name:$t('状态1'),
            conditionType: 'and',
            conditions: [{
              type:'',
              operator: "=",
              key: item.key,//"text",
              keyLabel: item.label,
              value: undefined
            }],
            actions: [],
          },
          {
            name:$t('状态2'),
            conditionType: 'and',
            conditions: [],
            actions: [],
          }
        ],
      });
      meta2d.active(meta2d.find(pen.id));
      emit('tabchange',pen.triggers.length-1);
      break;
    case 'view':
      meta2d.active(meta2d.find(pen.id));
      emit('tabchange',-1);
    default:
      break;
  }
}

const emit = defineEmits(['tabchange']); 

const triggerOptions = computed(() => {
  const options =   [
    {
      value: 'custom',
      content: $t('自定义状态'),
      divider: true
    },

    {
      value: 'warning',
      content: $t('条件告警'),
    },
    {
      value: 'warningAnimate',
      content: $t('条件动画'),
      divider: true
    },
    {
      value: 'mock',
      content: '本地调试',
    },
    {
      value: 'edit',
      content: $t('编辑'),
    },
    {
      value: 'delete',
      content: $t('移除'),
    },
  ]
  if( props.pen.name === "combine"&& props.pen.showChild !== undefined){
    options.splice(1,0,
    {
      value: 'switch',
      content: $t('状态切换'),
    });
  }
  
  return options
});

const addTrigger = (item:any, e:any, i:any) => {
  if(!['edit', 'delete'].includes(e.value)){
    if(!props.pen.triggers){
      props.pen.triggers = [];
    }
  }

  switch (e.value) {
    case 'edit':
      addDataDialog.header = $t('编辑动态数据');
      setter(item, 'value', getter(props.pen, item.key));
      addDataDialog.data = item;
      addDataDialog.show = true;
      break;
    case 'delete':
      props.pen.realTimes.splice(i, 1);
      meta2d.initBinds();
      break;
    case 'switch':
      props.pen.triggers.push({
        "name": "状态切换",
        "status": [
            {
              "name": $t("满足条件，切换到状态1"),
              "conditionType": "and",
              "conditions": [
                  {
                      "type": "",
                      "operator": ">=",
                      "key": item.key,
                      "keyLabel": item.label,
                      "valueType": ""
                  }
              ],
              "actions": [
                  {
                      "action": 1,
                      "params": "",
                      "value": {
                          "showChild": 1
                      },
                      "targetType": "id"
                  }
              ]
            },
            {
                "name": $t("默认显示状态"),
                "conditionType": "and",
                "conditions": [],
                "actions": [
                    {
                        "action": 1,
                        "params": "",
                        "value": {
                            "showChild": 0
                        },
                        "targetType": "id"
                    }
                ]
            }
        ]
      });
      break;
    case 'warning':
      props.pen.triggers.push({
        "name": "条件告警",
        "status": [
            {
                "name": $t("满足条件，触发告警"),
                "conditions": [
                    {
                        "type": "",
                        "operator": ">=",
                        "valueType": "",
                        "key": item.key,
                        "keyLabel":item.label,
                        "value": undefined
                    }
                ],
                "actions": [
                    {
                        "action": 1,
                        "params": "",
                        "value": {
                            "background": "red",
                        },
                        "targetType": "id"
                    }
                ],
                "conditionType": "and"
            },
            {
                "name": $t("恢复默认"),
                "conditionType": "and",
                "conditions": [],
                "actions": [
                    {
                        "action": 1,
                        "params": "",
                        "value": {
                            "background": "#0000",
                        },
                        "targetType": "id"
                    }
                ]
            }
        ]
      });
      break;
    case 'warningAnimate':
      props.pen.triggers.push({
        "name": "条件动画",
        "status": [
            {
                "name": $t("满足条件，触发动画执行"),
                "conditions": [
                    {
                        "type": "",
                        "operator": ">=",
                        "valueType": "",
                        "key": item.key,
                        "keyLabel":item.label,
                        "value": undefined
                    }
                ],
                "actions": [
                    {
                        "action": 2,
                        "params": "",
                        "value": "",
                        "targetType": "id",
                    }
                ],
                "conditionType": "and"
            },
            {
                "name": $t("恢复默认状态"),
                "conditionType": "and",
                "conditions": [],
                "actions": [
                    {
                        "action": 4,
                        "params": "",
                        "value": "",
                        "targetType": "id"
                    }
                ]
            }
        ]
      });
      break;
    case 'custom':
      props.pen.triggers.push({
        name: $t(`状态场景`) + (props.pen.triggers.length + 1),
        status:[
          {
            name:$t('状态1'),
            conditionType: 'and',
            conditions: [{
              type:'',
              operator: "=",
              key: item.key,//"text",
              keyLabel: item.label,
              value: undefined
            }],
            actions: [],
          },
          {
            name:$t('状态2'),
            conditionType: 'and',
            conditions: [],
            actions: [],
          }
        ],
      });
      break;
    case 'mock':
      dataMockDialog.data = item;
      dataMockDialog.show = true;
      break;
  }
  if(!['edit', 'delete','mock'].includes(e.value)){
    emit('tabchange',props.pen.triggers.length-1);
  }
}

const cell = ref({
  col:undefined,
  row:undefined
});

const getPenData = (e)=>{
  if(props.pen.name === 'tablePlus'){
   if(props.pen.calculative.activeRow !== undefined){
      cell.value.row = props.pen.calculative.activeRow;
      cell.value.col = undefined;
    }else if(props.pen.calculative.activeCell){
      cell.value.col = props.pen.calculative.activeCell.col;
      cell.value.row = props.pen.calculative.activeCell.row;
    }else{
      cell.value.col = undefined;
      cell.value.row = undefined;
    }
  }
}

const onQuickBind = ()=>{
  if(cell.value.row !== undefined){
    if(!props.pen.realTimes){
      props.pen.realTimes = [];
    }
    let row = cell.value.row;
    if(props.pen.colHeaders){
      row-=1;
    }
    if(cell.value.col !== undefined){
      let found = props.pen.realTimes.findIndex((item:any)=>{
        return item.key === `data.${cell.value.row}.${cell.value.col}`;
      });
      if(found === -1){
        props.pen.realTimes.push({
          label: `第${row+1}行，第${cell.value.col}列`,
          key: `data.${row}.${cell.value.col}`,
          type: 'float',
        });
        onBind(props.pen.realTimes[props.pen.realTimes.length-1]);
      }else{
        onBind(props.pen.realTimes[found]);
      }
    }else{
      let found = props.pen.realTimes.findIndex((item:any)=>{
        return item.key === `data.${cell.value.row}`;
      });
      if(found === -1){
        props.pen.realTimes.push({
          label: `第${row+1}行`,
          key: `data.${row}`,
          type: 'array',
        });
        onBind(props.pen.realTimes[props.pen.realTimes.length-1]);
      }else{
        onBind(props.pen.realTimes[found]);
      }
    }
  }
}

const dataSource = ref('');

const getDataSource = async (e) => {
  dataSource.value = '';
  if (e === 'excel') {
    let data = await importExcel();
    if (Array.isArray(data) && Array.isArray(data[0])) {
      meta2d.setValue({ id: props.pen.id, data: data, styles: [], mergeCells: [], colHeaders: false }, { doEvent: false });
    } else {
      MessagePlugin.warning($t("数据格式必需是二维数组"));
    }
  } else if (e === 'csv') {
    let data = await importCSV();
    if (Array.isArray(data) && Array.isArray(data[0])) {
      meta2d.setValue({ id: props.pen.id, data: data, styles: [], mergeCells: [], colHeaders: false }, { doEvent: false });
    } else {
      MessagePlugin.warning($t("数据格式必需是二维数组"));
    }
  } else if (e === 'api') {
    apiDialog.show = true;
  } else if (e === 'sql') {
    // getSqlTree();
    // sqlDialog.show = true;
    // props.pen.sql = true;
    sqlDialog.value.dbid = props.pen.dbid;
    sqlDialog.value.sql = props.pen.sql||'-- eg:SELECT * FROM "directory"';
    sqlDialog.value.show = true;
    sqlDialog.value.current = props.pen.pagination?.current;
    sqlDialog.value.pageSize = props.pen.pagination?.pageSize;
    sqlList.value =  await getSqlSourceList();
  }
}
const sqlDialog = ref({
  show: false,
  dbid: '',
  sql:'',
  method: 'list',
  pageSize: 10,
  current: 1,
});
const sqlList = ref([]);
const sqlChange = (sql)=>{
  props.pen.sql = sql;
}
const sqlConnect =async ()=>{
  // console.log('value',sqlDialog.value);
  // if(sqlDialog.value.method === 'exec'){
  //   let data:any = await doSqlCode({method:'exec',dbid:sqlDialog.value.dbid,sql: sqlDialog.value.sql});
  //   console.log("data",data);
  // }else if(sqlDialog.value.method === 'list'){
  props.pen.sql = sqlDialog.value.sql;
  props.pen.dbid = sqlDialog.value.dbid;
  let sql = sqlDialog.value.sql+' LIMIT '+(sqlDialog.value.pageSize||20)+(sqlDialog.value.current>1?(' OFFSET '+(sqlDialog.value.current-1)*sqlDialog.value.pageSize):'');
  // }
  let data:any =await doSqlCode({method:'list',dbid:props.pen.dbid,sql});
  if(data.error){
    MessagePlugin.error(data.detail);
  }else{
    if(data.length){
      let columns = [];
      let colWidth = 0;
      for(let key in data[0]){
        if(key === 'id'||key === '_id'){
          columns.unshift({
            colKey: key,
            text: key,
          });
        }else{
          columns.push({
            colKey: key,
            text: key,
          });
        }
        
        let len = data[0][key].length*10
        if(len>colWidth){
          colWidth = len;
        }
      }
      if(colWidth>200){
        colWidth = 200;
      }
      let _data = [];
      data.forEach((item)=>{
        // _data.push(Object.values(item))
        let itemData = [];
        columns.forEach((col)=>{
          itemData.push(item[col.colKey]);
        });
        _data.push(itemData);
      });
      meta2d.setValue({
        id:props.pen.id,
        data: _data,
        columns,
        styles:[],
        mergeCells:[],
        colWidth,
        sqlList:[],
        whiteSpace:"nowrap",
        ellipsis:true
      });
      MessagePlugin.success("导入成功");
      sqlDialog.value.show = false;
    }
   
  }
}

const changeColumns = (e)=>{
  props.pen.columns.forEach((item)=>{
    if(e.includes(item.colKey)){
      item.edited = false;
    }else{
      delete item.edited;
    }
  });
}

const apiDialog = reactive<any>({
  show: false,
});

const onConfirmAPI = async () => {
  if (!apiDialog.url) {
    MessagePlugin.warning($t('请输入API地址'));
    return;
  }
  const res: Response = await fetch(apiDialog.url, {
    headers: apiDialog.headers,
    method: apiDialog.method || 'GET',
    body: apiDialog.method === 'GET' ? undefined : JSON.stringify(apiDialog.body),
  });
  let data: any = JSON.parse(await res.text());
  if (data.data) {
    data = data.data;
  }
  if (data.list) {
    data = data.list;
  }

  if (Array.isArray(data)) {
    if (Array.isArray(data[0])) {
    } else {
      let _data = [];
      data.forEach((item) => {
        _data.push(Object.values(item));

      })
      data = _data;
    }
    if (Array.isArray(data) && Array.isArray(data[0])) {
      meta2d.setValue({ id: props.pen.id, data: data, styles: [], mergeCells: [], colHeaders: false }, { doEvent: false });
      MessagePlugin.success($t("导入成功"));
    } else {
      MessagePlugin.warning($t("数据格式必需是二维数组"));
    }
    apiDialog.show = false;
  } else {
    MessagePlugin.warning($t("数据格式必需是数组类型"));
  }
};

const leaderPen = ref(null);
const watcher = watch(
  () => props.pen.id,
  async () => {
    leaderPen.value = meta2d.store.pens[props.pen.formId];
  }
);

const moreDataDialog = reactive({
  show:false
})

onMounted(() => {
   meta2d.on('click',getPenData);
   leaderPen.value = meta2d.store.pens[props.pen.formId];
   getPenData({});
});

const old = globalThis.uiVersion === 'v20250208';

onUnmounted(() => {
  meta2d.off('click',getPenData);
  watcher();
  clearInterval(timer);
});
</script>
<style lang="postcss" scoped>
.props {
  height: 100%;

  .grid {
    grid-template-columns: 80px 110px 75px;
    padding: 0 12px;

    &.head {
      background: var(--color-background-input);
      line-height: 36px;
      margin-bottom: 6px;

      .title {
        line-height: 36px;
      }
    }
  }

  .blank {
    height: 70%;
    img {
      padding: 16px;
      opacity: 0.9;
    }
  }
  .c-titile{
    margin-top: 12px;
    color: var(--color-title);
    font-size: 12px;
    font-weight: 700;
  }
  .c-head{
    &::before{
      width: 0%;
    }
    color: var(--color);
    font-weight: 700;
  }
  .real-times{
    .label {
      width: fix-content;
      font-size: 10px;
      line-height: 28px;
      color: var(--color-desc);
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
    }
  }

  .value {
    padding-right: 8px;
    display: flex;
    align-items: center;
    justify-content: space-between;

    svg {
      flex-shrink: 0;
      margin-right: 4px;
    }

    & > div {
      /* width: 72px; */
      &.t-switch {
        width: fit-content;
        margin-left: 4px;
      }
    }

    :deep(.t-input) {
      padding-left: 4px;
      height: 26px;
      border-color: transparent;
      &:hover {
        border-color: var(--color-primary);
      }
    }
  }

  .actions {
    text-align: right;
    padding-right: 2px;
  }

  .data-list {
    :deep(.t-table__header--fixed:not(.t-table__header--multiple) > tr > th) {
      background: none;
    }

    :deep(.t-table__pagination) {
      padding-bottom: 0;
    }
  }
  /* .form-item{
    height: 32px;
  } */
}

.body {
  :deep(.t-collapse.t--border-less) {
    .t-collapse-panel__header {
      border-top: none;
      /* border-bottom: 1px solid var(--td-border-level-1-color); */
      padding: 8px 0;

      .t-input {
        border: none;
        padding-left: 0;
        font-size: 14px;
      }
    }

    .t-collapse-panel__content {
      padding: 8px 0;
    }
  }

  .title {
    position: relative;
    margin: 8px 0;

    :deep(.t-input) {
      border-color: var(--color-background-input);
      border-radius: 0;
      border-left: none;
      border-top: none;
      border-right: none;
      padding-left: 0;
      padding-bottom: 8px;
      font-size: 14px;

      &:hover {
        border-color: var(--color-border-input);
      }
    }
  }

  .head {
    margin-top: 10px;
  }

  .banner {
    background-color: var(--color-background-input);
    padding: 0 12px;
  }
}
</style>

<style lang="postcss">
.t-drawer__mask{
  /* background-color: #fff0; */
}

.t-drawer__body{
  padding:0px;
}
</style>