<script lang="ts" setup>
import icon_close_outlined from '@/assets/svg/icon_close_outlined.svg'
import icon_searchOutline_outlined from '@/assets/svg/icon_search-outline_outlined.svg'
import { reactive, ref, computed, watch, nextTick } from 'vue'
import { ElIcon, ElMessage, ElMessageBox, ElMessageBoxOptions } from 'element-plus-secondary'
import CreatDsGroup from './CreatDsGroup.vue'
import type { DsType } from './DsTypeList.vue'
import DsTypeList from './DsTypeList.vue'
import { useI18n } from '@/hooks/web/useI18n'
import EditorDetail from './EditorDetail.vue'
import ExcelDetail from './ExcelDetail.vue'
import {
  save,
  update,
  validate,
  latestUse,
  isShowFinishPage,
  checkRepeat,
  loadRemoteFile
} from '@/api/datasource'
import { Base64 } from 'js-base64'
import type { Param } from './ExcelDetail.vue'
import type { Configuration, ApiConfiguration, SyncSetting } from './option'
import { dsTypes, typeList, nameMap } from './option'
import { useRouter,useRoute } from 'vue-router'
import { uuid } from 'vue-uuid'
import { useEmitt } from '@/hooks/web/useEmitt'
import FinishPage from '../FinishPage.vue'
import { cloneDeep } from 'lodash-es'
import { useCache } from '@/hooks/web/useCache'
import Icon from '@/components/icon-custom/src/Icon.vue'
import { XpackComponent, PluginComponent } from '@/components/plugin'
import { iconDatasourceMap } from '@/components/icon-group/datasource-list'
const route = useRoute()
const router = useRouter()
const appId:any = ref('')
if (route.query.id) {
  appId.value = route.query.id
}else{
  router.push({
  path: '/application'
})
}
interface Node {
  name: string
  id: string
  type: DsType
}

interface Tree {
  [key: string]: any
}
interface Form {
  name: string
  pid?: string
  id?: string
  description: string
  type: string
  copy: boolean
  configuration?: Configuration
  apiConfiguration?: ApiConfiguration[]
  paramsConfiguration?: ApiConfiguration[]
  syncSetting?: SyncSetting
  isPlugin?: boolean
  staticMap?: any
}

const { t } = useI18n()
const creatDsFolder = ref()
const { wsCache } = useCache()
const dsLoading = ref(false)
let isFormUpdate = false
let isForm2Update = false
let isUpdate = false
const changeUpdate = val => {
  isUpdate = val
}
const state = reactive({
  datasourceTree: []
})
state.datasourceTree = typeList.map(ele => {
  return {
    name: nameMap[ele],
    type: ele
  }
})

const activeStep = ref(0)
const detail = ref()
const xpack = ref()
const excel = ref()
const excelRemote = ref()
const latestUseTypes = ref([])
const currentType = ref<DsType>('OLTP')
const filterText = ref('')
const currentDsType = ref('')
const emits = defineEmits(['refresh'])
const { emitter } = useEmitt()
const isPlugin = ref(false)
const isSupportSetKey = ref(false)
const selectDsType = (type: string) => {
  currentDsType.value = type
  activeStep.value = 1
  activeApiStep.value = 1
  nextTick(() => {
    detail?.value?.initForm(type, pluginDs.value, pluginIndex.value, isPlugin.value) ||
      xpack?.value?.invokeMethod({
        methodName: 'initForm',
        args: type
      })
    excelRemote?.value?.initForm(type)
    if (!dsTree.value) return
    currentTypeList.value
      .map(ele => ele.dbList)
      .flat()
      .some(ele => {
        if (ele.type === currentDsType.value) {
          dsTree.value.setCurrentNode(ele)
          isPlugin.value = ele['isPlugin']
          return true
        }
        return false
      })
  })
}

const handleDsNodeClick = data => {
  if (!data.type) return
  isPlugin.value = data['isPlugin']
  selectDsType(data.type)
}
const handleNodeClick = (data: Node) => {
  currentType.value = data.type
}

watch(filterText, val => {
  if (activeStep.value === 1) {
    dsTree.value.filter(val.toLocaleLowerCase())
  }
})

const dsTree = ref()
const defaultProps = {
  children: 'dbList',
  label: 'name'
}
const filterNode = (value: string, data: Tree) => {
  if (!value) return true
  return data.name.toLowerCase().includes(value)
}
const databaseList = ref([])
const currentTypeList = computed(() => {
  return typeList.map((ele, index) => {
    return { name: nameMap[ele], dbList: databaseList.value[index] }
  })
})

const getDatasourceTypes = () => {
  const arr = [[], [], [], [], []]
  dsTypes.forEach(item => {
    const index = typeList.findIndex(ele => ele === item.catalog)
    if (index !== -1) {
      arr[index].push(item)
    }
  })
  databaseList.value = arr.map(ele => {
    return ele.sort((a, b) => {
      return a.name.toLowerCase().charCodeAt(0) - b.name.toLowerCase().charCodeAt(0)
    })
  })
}
getDatasourceTypes()

const pluginIndex = ref('')
const pluginDs = ref([])
const loadDsPlugin = data => {
  pluginDs.value = data
  data.forEach(item => {
    const { name, category, type, icon, extraParams, staticMap } = item
    const node = {
      name,
      catalog: category,
      type,
      icon,
      extraParams,
      isPlugin: true,
      staticMap
    }
    const index = typeList.findIndex(ele => ele === node.catalog)
    if (index !== -1) {
      databaseList.value[index].push(node)
    }
  })
}
const getPluginStatic = type => {
  const arr = pluginDs.value.filter(ele => {
    return ele.type === type
  })
  return pluginIndex.value
    ? pluginIndex.value
    : arr && arr.length > 0
    ? arr[0].staticMap?.index
    : null
}

const getLatestUseTypes = () => {
  latestUse({}).then(res => {
    latestUseTypes.value = res.data
  })
}
getLatestUseTypes()

const activeApiStep = ref(0)

const setNextStep = () => {
  activeApiStep.value = activeStep.value + 1
  if (
    (currentDsType.value.includes('API') || currentDsType.value === 'ExcelRemote') &&
    activeStep.value === 1
  )
    return
  activeStep.value = activeStep.value + 1
}

const next = () => {
  if (currentDsType.value === '') {
    ElMessage.error(t('datasource.select_type'))
    return
  }

  if (
    form.apiConfiguration?.length === 0 &&
    currentDsType.value.includes('API') &&
    activeStep.value !== 2
  ) {
    ElMessage.error(t('data_source.cannot_be_empty_table'))
    return
  }

  if (currentDsType.value.includes('ExcelRemote') && activeStep.value !== 2) {
    const validate = excelRemote.value.validateExcel()
    if (validate) {
      setNextStep()
    }
    return
  }

  if (currentDsType.value.includes('API') && activeStep.value !== 2) {
    const validateFrom = detail.value.submitForm()
    validateFrom(val => {
      if (val) {
        setNextStep()
      }
    })
    return
  }

  setNextStep()
}

const complete = (params, successCb, finallyCb) => {
  excel?.value?.saveExcelDs(
    params,
    () => {
      pid.value = params.pid
      successCb()
    },
    finallyCb
  )
  excelRemote?.value?.saveExcelDs(
    params,
    () => {
      pid.value = params.pid
      successCb()
    },
    finallyCb
  )
  return
}

const showFinishPage = ref(false)
const dsInfo = reactive({
  name: '',
  id: ''
})

const createDataset = () => {
  router.push({
    path: '/datasetForm',
    query: {
      datasourceId: dsInfo.id,
      appId:appId.value
    }
  })
}
const backToDatasourceList = () => {
  visible.value = false
  emits('refresh')
  showFinishPage.value = false
}
const continueCreating = () => {
  showFinishPage.value = false
  init(null, pid.value)
}

const handleShowFinishPage = ({ id, name, pid }) => {
  isShowFinishPage()
    .then(res => {
      if (editDs.value || !res.data) {
        emits('refresh')
        visible.value = false
        return
      } else {
        showFinishPage.value = true
        Object.assign(dsInfo, { id, name })
      }
    })
    .finally(() => {
      pid.value = pid
    })
}

emitter.on('showFinishPage', handleShowFinishPage)

const prev = () => {
  prevConfirm()
}

const prevConfirm = () => {
  if (
    (currentDsType.value.includes('API') || currentDsType.value === 'ExcelRemote') &&
    activeApiStep.value === 2
  ) {
    activeApiStep.value = 1
    activeStep.value = 1
    return
  }

  if (activeStep.value === 1) {
    currentDsType.value = ''
  }
  activeStep.value = activeStep.value - 1
}

const handleSubmit = param => {
  const validateFrom = param.validate
  if (param.eventName === 'saveDs') {
    validateFrom(val => {
      if (val) {
        doSaveDs(param.args)
      }
    })
  } else {
    validateFrom(val => {
      if (val) {
        doValidateDs(param.args)
      }
    })
  }
}

const validateDS = () => {
  const request = JSON.parse(JSON.stringify(form)) as unknown as Omit<
    Form,
    'configuration' | 'apiConfiguration'
  > & {
    configuration: string
    apiConfiguration: string
  }
  if (currentDsType.value.includes('API')) {
    if (form.apiConfiguration.length === 0) {
      ElMessage.error(t('data_source.add_data_table'))
      return
    }
    let apiItems = []
    apiItems = apiItems.concat(request.apiConfiguration)
    if (request.paramsConfiguration) {
      apiItems = apiItems.concat(request.paramsConfiguration)
    }
    request.configuration = Base64.encode(JSON.stringify(apiItems))
    request.syncSetting.startTime = new Date(request.syncSetting.startTime).getTime()
    request.syncSetting.endTime = new Date(request.syncSetting.endTime).getTime()
  } else {
    request.configuration = Base64.encode(JSON.stringify(request.configuration))
  }
  if (isPlugin.value && !currentDsType.value.includes('API')) {
    xpack?.value?.invokeMethod({
      methodName: 'submitForm',
      args: [{ eventName: 'validateDs', args: request }]
    })
  } else {
    let validateFrom = detail?.value?.submitForm()
    if (excelRemote?.value?.submitForm()) {
      validateFrom = excelRemote?.value?.submitForm()
    }
    validateFrom(val => {
      if (val) {
        doValidateDs(request)
      }
    })
  }
}

const doValidateDs = request => {
  dsLoading.value = true
  if (currentDsType.value === 'ExcelRemote') {
    let excelRequest = JSON.parse(JSON.stringify(form2.configuration))
    excelRequest.datasourceId = form2.id || 0
    excelRequest.editType = form2.editType
    excelRequest.userName = Base64.encode(excelRequest.userName)
    excelRequest.passwd = Base64.encode(excelRequest.passwd)
    return loadRemoteFile(excelRequest)
      .then(res => {
        dsLoading.value = false
        if (!res) {
          ElMessage.warning(res.msg)
          return
        }
        if (res?.code !== 0) {
          ElMessage.warning(res.msg)
          return
        }
        ElMessage.success(t('datasource.validate_success'))
        dsLoading.value = false
      })
      .catch(() => {
        ElMessage.error(t('data_source.verification_failed'))
        dsLoading.value = false
      })
  }
  validate(request)
    .then(res => {
      if (res.data.type.includes('API')) {
        let error = 0
        const status = JSON.parse(res.data.status) as Array<{ status: string; name: string }>
        for (let i = 0; i < status.length; i++) {
          if (status[i].status === 'Error') {
            error++
          }
          for (let j = 0; j < form.apiConfiguration.length; j++) {
            if (status[i].name === form.apiConfiguration[j].name) {
              form.apiConfiguration[j].status = status[i].status
            }
          }
        }
        if (error === 0) {
          ElMessage.success(t('datasource.validate_success'))
        } else {
          ElMessage.error(t('data_source.verification_failed'))
        }
      } else {
        ElMessage.success(t('datasource.validate_success'))
      }
    })
    .finally(() => {
      dsLoading.value = false
    })
}

const typeTitle = computed(() => {
  if (!currentDsType.value) {
    return ''
  }
  let str = ''
  databaseList.value.some(ele => {
    return ele.some(itx => {
      if (itx.type === currentDsType.value) {
        str = itx.name
        return true
      }
      return false
    })
  })
  return str
})

const saveDS = () => {
  isUpdate = false
  const request = JSON.parse(JSON.stringify(form)) as unknown as Omit<
    Form,
    'configuration' | 'apiConfiguration'
  > & {
    configuration: string
    apiConfiguration: string
  }

  if (currentDsType.value === 'Excel') {
    excel.value.uploadStatus(false)
    if (!excel.value.sheetFile?.name) {
      excel.value.uploadStatus(true)
      return
    }
    const validate = excel.value.submitForm()
    validate(val => {
      if (val) {
        if (editDs.value) {
          complete(null, null, null)
        } else {
          creatDsFolder.value.createInit('datasource', { id: pid.value }, '', form2.name)
        }
      }
    })
    return
  }

  if (currentDsType.value === 'ExcelRemote') {
    const validate = excelRemote.value.submitForm()
    validate(val => {
      if (val) {
        const validateApi = excelRemote?.value?.submitSyncSettingForm()
        validateApi(v => {
          if (v) {
            if (editDs.value && form2.id) {
              complete(null, null, null)
            } else {
              creatDsFolder.value.createInit('datasource', { id: pid.value }, '', form2.name)
            }
          }
        })
      }
    })
    return
  } else if (currentDsType.value.includes('API')) {
    for (let i = 0; i < request.apiConfiguration.length; i++) {
      if (
        request.apiConfiguration[i].deTableName === '' ||
        request.apiConfiguration[i].deTableName === undefined ||
        request.apiConfiguration[i].deTableName === null
      ) {
        request.apiConfiguration[i].deTableName =
          'api_' +
          request.apiConfiguration[i].name +
          '_' +
          uuid.v1().replaceAll('-', '').substring(0, 10)
      }
      request.apiConfiguration[i].jsonFields = []
      for (let j = 0; j < request.apiConfiguration[i].fields.length; j++) {
        request.apiConfiguration[i].fields[j].value = []
      }
    }
    let apiItems = []
    apiItems = apiItems.concat(request.apiConfiguration)
    if (request.paramsConfiguration) {
      apiItems = apiItems.concat(request.paramsConfiguration)
    }
    request.configuration = Base64.encode(JSON.stringify(apiItems))
    request.syncSetting.startTime = new Date(request.syncSetting.startTime).getTime()
    request.syncSetting.endTime = new Date(request.syncSetting.endTime).getTime()
  } else {
    request.configuration = Base64.encode(JSON.stringify(request.configuration))
  }
  if (isPlugin.value && !currentDsType.value.includes('API')) {
    xpack?.value?.invokeMethod({
      methodName: 'submitForm',
      args: [{ eventName: 'saveDs', args: request }]
    })
  } else {
    const validate = detail?.value?.submitForm()
    request.apiConfiguration = ''
    validate(val => {
      if (val) {
        if (currentDsType.value.includes('API')) {
          const validateApi = detail?.value?.submitApiForm()
          validateApi(v => {
            if (v) {
              doSaveDs(request)
            }
          })
        } else {
          doSaveDs(request)
        }
      }
    })
  }
}

const doSaveDs = request => {
  if (editDs.value && form.id) {
    let options = {
      confirmButtonType: 'danger',
      type: 'warning',
      autofocus: false,
      showClose: false,
      tip: ''
    }
    request.appId = appId.value

    checkRepeat(request).then(res => {
      let method = request.id === '' ? save : update
      if (res) {
        ElMessageBox.confirm(t('datasource.has_same_ds'), options as ElMessageBoxOptions).then(
          () => {
            if (dsLoading.value === true) {
              return
            }
            dsLoading.value = true
            method(request)
              .then(res => {
                if (res !== undefined) {
                  handleShowFinishPage({ id: res.id, name: res.name })
                  ElMessage.success(t('data_source.source_saved_successfully'))
                }
              })
              .finally(() => {
                dsLoading.value = false
              })
          }
        )
      } else {
        if (dsLoading.value === true) {
          return
        }
        dsLoading.value = true
        method(request)
          .then(res => {
            if (res !== undefined) {
              handleShowFinishPage({ id: res.id, name: res.name })
              ElMessage.success(t('data_source.source_saved_successfully'))
            }
          })
          .finally(() => {
            dsLoading.value = false
          })
      }
    })
  } else {
    creatDsFolder.value.createInit('datasource', { id: pid.value, request }, '', form.name)
  }
}

const defaultForm = {
  id: '',
  name: '',
  description: '',
  type: 'API',
  apiConfiguration: [],
  paramsConfiguration: [],
  enableDataFill: false
}
const defaultForm2 = {
  type: '',
  id: '0',
  editType: 0,
  name: '',
  creator: '',
  configuration: {}
}
const origin = reactive<Form>(cloneDeep(defaultForm))
const form = reactive<Form>(cloneDeep(defaultForm))
const form2 = reactive<Param>(cloneDeep(defaultForm2))

const visible = ref(false)
const editDs = ref(false)
const pid = ref('0')

watch(
  () => form,
  () => {
    if (isFormUpdate) {
      changeUpdate(true)
    }
  },
  { deep: true }
)

watch(
  () => form2,
  () => {
    if (isForm2Update) {
      changeUpdate(true)
    }
  },
  { deep: true }
)

const init = (nodeInfo: Form | Param, id?: string, res?: object, supportSetKey: boolean) => {
  isPlugin.value = nodeInfo?.isPlugin
  pluginIndex.value = isPlugin.value ? nodeInfo?.staticMap?.index : null
  isSupportSetKey.value = supportSetKey
  editDs.value = !!nodeInfo
  showFinishPage.value = false

  if (!!nodeInfo) {
    if (nodeInfo.type.startsWith('Excel')) {
      Object.assign(form2, cloneDeep(nodeInfo))
    } else {
      Object.assign(form, cloneDeep(nodeInfo))
      Object.assign(origin, cloneDeep(nodeInfo))
      if (form.hasOwnProperty('configuration') && form.configuration.urlType == undefined) {
        form.configuration.urlType = 'hostName'
      }
      if (form.hasOwnProperty('configuration') && form.configuration.sshType == undefined) {
        form.configuration.sshType = 'password'
      }
    }
    pid.value = nodeInfo.pid || '0'
  } else {
    Object.assign(form2, cloneDeep(defaultForm2))
    Object.assign(form, cloneDeep(defaultForm))
    pid.value = id || '0'
  }
  activeStep.value = Number(editDs.value)
  activeApiStep.value = activeStep.value

  visible.value = true
  nextTick(() => {
    isForm2Update = true
    isFormUpdate = true
  })
  if (!!nodeInfo) {
    nextTick(() => {
      currentDsType.value = nodeInfo.type
      activeStep.value = 1
      activeApiStep.value = activeStep.value
      if (!!res) {
        nextTick(() => {
          excel.value.appendReplaceExcel(res)
        })
      }
      nextTick(() => {
        detail?.value?.clearForm()
        excelRemote?.value?.clearForm()
        xpack?.value?.invokeMethod({
          methodName: 'clearForm',
          args: []
        })
      })
    })
  }
}

const drawTitle = computed(() => {
  const { id, editType, creator } = form2
  if (creator && id && currentDsType.value == 'Excel') {
    return editType === 1 ? t('data_source.append_data') : t('data_source.replace_data')
  }
  if (currentDsType.value == 'ExcelRemote') {
    return editDs.value
      ? !form2.id
        ? t('data_source.copy_data_source')
        : t('datasource.modify')
      : t('data_source.create_data_source')
  }
  return editDs.value
    ? !form.id
      ? t('data_source.copy_data_source')
      : t('datasource.modify')
    : t('data_source.create_data_source')
})

const beforeClose = () => {
  if (wsCache.get('ds-new-success')) {
    emits('refresh')
    wsCache.set('ds-new-success', false)
  }
  if (
    !showFinishPage.value &&
    ((!editDs.value && activeStep.value !== 0) || isUpdate) &&
    !(JSON.stringify(form) === JSON.stringify(origin))
  ) {
    ElMessageBox.confirm(t('data_source.want_to_exit'), {
      confirmButtonText: t('dataset.confirm'),
      cancelButtonText: t('common.cancel'),
      showCancelButton: true,
      confirmButtonType: 'primary',
      type: 'warning',
      autofocus: false,
      showClose: false
    }).then(() => {
      visible.value = false
    })
  } else {
    visible.value = false
  }
}

defineExpose({
  init
})
</script>

<template>
  <el-drawer
    :close-on-click-modal="false"
    size="calc(100% - 100px)"
    modal-class="datasource-drawer-fullscreen"
    direction="btt"
    :before-close="beforeClose"
    :show-close="false"
    v-model="visible"
  >
    <template #header="{ close }">
      <span>{{ drawTitle }}</span>
      <div v-if="!editDs" class="flex-center" style="width: 100%">
        <el-steps custom style="max-width: 500px; flex: 1" :active="activeStep" align-center>
          <el-step>
            <template #title>
              {{ t('deDataset.select_data_source') }}
            </template>
          </el-step>
          <el-step>
            <template #title>
              {{ t('data_source.configuration_information') }}
            </template>
          </el-step>
        </el-steps>
      </div>
      <el-icon @click="close" class="datasource-close">
        <Icon name="icon_close_outlined"><icon_close_outlined class="svg-icon" /></Icon>
      </el-icon>
    </template>
    <div class="datasource" v-loading="dsLoading">
      <div class="ds-type-select" v-if="!editDs">
        <div class="title">
          <el-input
            :placeholder="t('chart.search')"
            class="m24 w100"
            v-model="filterText"
            clearable
          >
            <template #prefix>
              <el-icon>
                <Icon name="icon_search-outline_outlined"
                  ><icon_searchOutline_outlined class="svg-icon"
                /></Icon>
              </el-icon>
            </template>
          </el-input>
        </div>
        <template v-if="activeStep === 0">
          <p
            :class="currentType === 'latestUse' && 'active'"
            @click="handleNodeClick({ type: 'latestUse', name: 'latestUse', id: 'latestUse' })"
            class="list-item_primary"
          >
            {{ t('data_source.recently_created') }}
          </p>
          <el-divider />
          <p
            :class="currentType === 'all' && 'active'"
            @click="handleNodeClick({ type: 'all', name: 'all', id: 'all' })"
            class="list-item_primary"
          >
            {{ t('data_source.all') }}
          </p>
          <div
            :key="ele.name"
            @click="handleNodeClick(ele)"
            v-for="ele in state.datasourceTree"
            class="list-item_primary"
            :class="currentType === ele.type && 'active'"
          >
            <span :title="ele.name" class="label">{{ ele.name }}</span>
          </div>
        </template>
        <el-tree
          :expand-on-click-node="false"
          menu
          v-if="activeStep > 0"
          ref="dsTree"
          :data="currentTypeList"
          nodeKey="name"
          :props="defaultProps"
          :filter-node-method="filterNode"
          @node-click="handleDsNodeClick"
        >
          <template #default="{ node, data }">
            <span class="custom-tree-node flex-align-center">
              <el-icon v-if="!!data.catalog" class="icon-border" style="width: 18px; height: 18px">
                <Icon v-if="data['isPlugin']" :static-content="data.icon"></Icon>
                <Icon v-else
                  ><component class="svg-icon" :is="iconDatasourceMap[data.type]"></component
                ></Icon>
              </el-icon>
              <span :title="node.label" class="label-tooltip">{{ node.label }}</span>
            </span>
          </template>
        </el-tree>
      </div>
      <div class="ds-editor" :class="editDs && 'edit-ds'">
        <div v-show="activeStep !== 0 && !editDs" class="ds-type-title">
          {{ typeTitle }}
        </div>
        <div class="editor-content" :class="(activeStep === 0 || editDs) && 'type-title'">
          <ds-type-list
            v-show="activeStep === 0"
            :filter-text="filterText.toLocaleLowerCase()"
            @select-ds-type="selectDsType"
            :current-type="currentType"
            :latest-use-types="latestUseTypes"
          ></ds-type-list>
          <editor-detail
            ref="detail"
            :form="form"
            :is-plugin="isPlugin"
            :plugin-ds="pluginDs"
            :plugin-index="pluginIndex"
            :editDs="editDs"
            :active-step="activeApiStep"
            :is-supportSetKey="isSupportSetKey"
            v-if="
              activeStep !== 0 &&
              currentDsType &&
              !currentDsType.startsWith('Excel') &&
              visible &&
              (!isPlugin || currentDsType.startsWith('API'))
            "
          ></editor-detail>
          <plugin-component
            :jsname="getPluginStatic(currentDsType)"
            ref="xpack"
            :form="form"
            :editDs="editDs"
            :active-step="activeApiStep"
            @submitForm="handleSubmit"
            v-if="
              activeStep !== 0 &&
              currentDsType &&
              currentDsType !== 'Excel' &&
              visible &&
              isPlugin &&
              !currentDsType.startsWith('API')
            "
          >
          </plugin-component>
          <template v-if="activeStep !== 0 && currentDsType == 'Excel'">
            <excel-detail
              :editDs="editDs"
              :is-supportSetKey="isSupportSetKey"
              ref="excel"
              :param="form2"
            ></excel-detail>
          </template>
          <template v-if="activeStep !== 0 && currentDsType == 'ExcelRemote'">
            <excel-remote-detail
              :editDs="editDs"
              :is-supportSetKey="isSupportSetKey"
              ref="excelRemote"
              :active-step="activeApiStep"
              :form="form2"
            ></excel-remote-detail>
          </template>
        </div>
      </div>
      <div class="editor-footer">
        <el-button secondary @click="beforeClose"> {{ t('common.cancel') }}</el-button>
        <el-button
          v-show="!(activeStep === 0 || (editDs && activeApiStep <= 1))"
          secondary
          @click="prev"
        >
          {{ t('common.prev') }}</el-button
        >
        <el-button
          v-show="activeStep === 1 && currentDsType !== 'Excel'"
          secondary
          @click="validateDS"
        >
          {{ t('datasource.validate') }}</el-button
        >
        <el-button
          v-show="
            (activeStep === 0 &&
              !currentDsType.startsWith('API') &&
              currentDsType !== 'ExcelRemote') ||
            (activeApiStep !== 2 &&
              (currentDsType.startsWith('API') || currentDsType === 'ExcelRemote'))
          "
          type="primary"
          @click="next"
        >
          {{ t('common.next') }}</el-button
        >
        <el-button
          v-show="
            (activeStep === 1 &&
              !currentDsType.startsWith('API') &&
              currentDsType !== 'ExcelRemote') ||
            (activeApiStep === 2 &&
              (currentDsType.startsWith('API') || currentDsType === 'ExcelRemote'))
          "
          type="primary"
          @click="saveDS"
        >
          {{ t('common.save') }}</el-button
        >
      </div>
      <FinishPage
        @continue-creating="continueCreating"
        @back-to-datasource-list="backToDatasourceList"
        @create-dataset="createDataset"
        :name="dsInfo.name"
        v-if="showFinishPage"
      ></FinishPage>

      <XpackComponent
        jsname="L2NvbXBvbmVudC9wbHVnaW5zLWhhbmRsZXIvRHNDYXRlZ29yeUhhbmRsZXI="
        @load-ds-plugin="loadDsPlugin"
      />
    </div>
  </el-drawer>
  <creat-ds-group
    @handle-show-finish-page="handleShowFinishPage"
    @finish="complete"
    ref="creatDsFolder"
  ></creat-ds-group>
</template>

<style lang="less">
.datasource-drawer-fullscreen {
  z-index: 1000 !important;

  .ed-drawer__body {
    padding: 0;
  }

  .ed-drawer__header > :first-child {
    flex: none;
    width: auto;
  }

  .ed-drawer__header {
    border-color: #4f5052;
    justify-content: space-between;
  }

  .datasource-close {
    cursor: pointer;
  }
  .editor-step {
    position: relative;
    .ed-steps {
      width: 500px;
    }
    .ed-step.is-center .ed-step__line {
      width: 80px;
      right: 40px;
      z-index: 5;
      left: calc(100% - 40px);
    }

    .ed-step__icon.is-icon {
      width: auto;
      position: relative;
      z-index: 0;
    }

    .ed-step__head.is-finish::after {
      right: calc(100% - 66px);
      top: 44%;
    }

    .ed-step__head.is-process .ed-step__icon {
      background-color: transparent;
      .step-icon {
        .icon {
          background: var(--ed-color-primary);
        }
      }
    }

    .ed-step__head.is-finish .ed-step__icon {
      background-color: transparent;
      .step-icon {
        .icon {
          border: 1px solid var(--ed-color-primary);
        }
      }
    }

    .ed-step__head.is-wait .ed-step__icon {
      background-color: transparent;
      .step-icon {
        .icon {
          color: #8f959e;
          border: 1px solid #8f959e;
        }
      }
    }

    .step-icon {
      display: flex;
      padding: 0 48px;
      align-items: center;
      .icon {
        width: 28px;
        height: 28px;
        line-height: 27px;
        border-radius: 50%;
      }
      .title {
        margin-left: 8px;
        color: #ffffff;
        font-size: 14px;
        font-weight: 400;
        line-height: 22px;
      }
    }
  }
  .datasource {
    width: 100%;
    height: 100%;
    // background: #fff;
    position: relative;

    .custom-tree-node {
      .ed-icon {
        margin-right: 8px;
      }
    }
    .ds-type-select {
      width: 279px;
      height: calc(100% - 64px);
      padding: 16px 7px;
      border-right: 1px solid #4f5052;
      float: left;
      overflow-y: auto;

      .icon-border {
        font-size: 18px;
        margin-right: 8px;
      }
      .title {
        display: flex;
        justify-content: space-between;
        font-family: var(--de-custom_font, 'PingFang');
        font-size: 14px;
        font-weight: 500;
        color: var(--TextPrimary, #1f2329);
        box-sizing: border-box;
        flex-wrap: wrap;
        position: sticky;
        top: 0;
        left: 24px;
        z-index: 5;
        padding: 0 17px;
        &::before {
          content: '';
          width: 100%;
          height: 24px;
          top: -24px;
          position: absolute;
          z-index: 5;
          left: 0;
          // background: white;
        }
      }
      .ed-divider--horizontal {
        margin: 4px 0 4px 16px;
        width: calc(100% - 34px);
        border-color: #4f5052;
      }

      .m24 {
        margin-bottom: 8px;
      }
      .w100 {
        width: 100%;
      }
      .list-item_primary {
        position: relative;
        padding: 8px 17px;
        font-weight: 500;
        font-size: 14px;
        color: #fff;
      }
      .list-item_primary:hover {
         background: rgba(255, 255, 255, 0.1);
      }
    }
    .ds-editor {
      float: left;
      width: calc(100% - 279px);
      height: calc(100% - 64px);

      &.edit-ds {
        width: 100%;
      }

      .ds-type-title {
        width: 100%;
        padding: 16px 24px;
        color: #fff;
        font-family: var(--de-custom_font, 'PingFang');
        font-size: 16px;
        font-style: normal;
        font-weight: 500;
        line-height: 24px;
        border-bottom: 1px solid #4f5052;
      }

      .editor-content {
        padding: 16px 24px;
        height: calc(100vh - 278px);
        overflow-y: auto;

        &.type-title {
          height: calc(100vh - 221px);
        }
      }
    }
    .editor-footer {
      height: 64px;
      display: flex;
      align-items: center;
      justify-content: flex-end;
      width: 100%;
      padding-right: 24px;
      float: left;
      border-top: 1px solid #4f5052;
      .ed-button.is-secondary{
        color: #F2F4F5;
        background-color: #212121;
        border: 1px solid #363636;
      }
      .ed-button--primary{
        background-color: #0089ff;
        border: 1px solid #0089ff;
      }
    }
  }
}
</style>
<style >
.ed-drawer__header{
  color: #fff;
}
.ed-textarea__inner{
  background: rgba(37, 38, 38, 1);
  color: #fff;
}
.ed-radio__label{
  color: #fff;
}
.ed-radio__input.is-checked+.ed-radio__label{
  color: #fff;
}
.list-item_primary.active {
  background: rgb(23, 64, 99);
}
.ed-tree-node.is-current.is-menu>:nth-child(1) {
  background: rgb(23, 64, 99);
  color: #fff;
}
.ed-textarea__inner{
  box-shadow: none;
  border: 1px solid #434343;
}
.ed-input__wrapper {
    background-color: rgba(37, 38, 38, 1);
    box-sizing: border-box;
    border: none !important;
    border-radius: 4px;
    box-shadow: none;
    border: 1px solid #636363;
}
.ed-textarea .ed-input__count {
  color: #636363;
  background: transparent;
}
.ed-input-number--light:not(.is-disabled).is-controls-right .ed-input-number__decrease:not(.is-disabled), .ed-input-number--light:not(.is-disabled).is-controls-right .ed-input-number__increase:not(.is-disabled){
  border-color: #5f5f5f;
  background-color: #434343 !important;
}
.editor-detail .is-controls-right > span{
  background-color: #434343 !important;
}
.ed-input-number.is-controls-right .ed-input-number__decrease{
  border-left: 1px solid #5f5f5f;
}
.ed-input-number--light .ed-input-number__decrease.is-disabled .ed-icon, .ed-input-number--light .ed-input-number__increase.is-disabled .ed-icon{
  color: #fff !important;
}
.ed-input-number--light .ed-input-number__decrease .ed-icon{
  color: #fff;
}
.ed-input-number--light .ed-input-number__increase .ed-icon{
  color: #fff;
}
.ed-radio__inner{
  background: transparent;
  border-color: #636363;
}
.ed-radio__input.is-checked .ed-radio__inner {
  border-color: #0089ff;
  background: #0089ff;
}
.ed-radio__inner::after{
  background: rgb(33,33,33);
}
.de-expand{
  color: #0089ff;
}
.ed-checkbox__inner{
  background: transparent;
  border-color: #636363;
}
.ed-checkbox__input.is-checked .ed-checkbox__inner {
  background-color: #0089ff;
  border-color: #0089ff;
}
.ed-message-box{
  background: #212121;
}
.ed-message-box__content{
  color: #ffffff;
}
.ed-message-box__btns .ed-button--primary{
  background: #0089ff;
  border-color: #0089ff;
}
.ed-message-box__btns .ed-button.is-secondary{
  color: #F2F4F5 !important;
  background-color: #212121 !important;
  border: 1px solid #434343 !important;
}
.ed-form-item.is-error .ed-input__wrapper {
  box-shadow: none !important;
  border: 1px solid #f54a45 !important;
}
</style>
