<!--
 * @Date: 2022-03-24 09:55:13
 * @LastEditTime: 2022-05-16 09:55:51
 * @LastEditors: your name
 * @Description: 服务管理-编辑服务
 * have a nice day!
-->

<template>
  <div class="service-edit">
    <div class="scrollbar">
      <el-row :gutter="24">
        <el-col :span="16">
          <div class="part part-top">
            <header class="title">
              <p class="manageTitle">服务</p>
              <el-button
                size="small"
                type="primary"
                class="btn-save"
                @click="btnSaveClickHandler"
              >保存</el-button>
            </header>
            <main class="content">
              <el-form
                ref="serviceForm"
                class="service-form"
                :model="serviceForm"
                label-position="right"
                label-width="72px"
                size="mini"
              >
                <el-form-item
                  label="服务名称"
                  prop="serviceName"
                >
                  <el-input
                    v-model="serviceForm.serviceName"
                    width="240px"
                    placeholder="请输入服务名称"
                    clearable
                  />
                </el-form-item>
                <el-form-item label="是否同步">
                  <el-radio-group v-model="serviceForm.isAsynchronous">
                    <el-radio :label="0">是</el-radio>
                    <el-radio :label="1">否</el-radio>
                  </el-radio-group>
                </el-form-item>
                <el-form-item
                  label="服务描述"
                  prop="serviceDescribe"
                >
                  <el-input
                    v-model="serviceForm.serviceDescribe"
                    placeholder="请输入描述"
                    type="textarea"
                    :autosize="{ minRows: 5, maxRows: 5 }"
                    resize="none"
                    clearable
                  />
                </el-form-item>
              </el-form>
            </main>
          </div>
        </el-col>
        <el-col :span="8">
          <div class="part part-top">
            <header class="title">
              <p class="manageTitle">部署机器</p>
            </header>
            <main class="content">
              <div class="scrollbar">
                <template v-if="nodeList.length">
                  <el-row :gutter="16">
                    <el-col :span="8">
                      <div class="service-edit-card">
                        <div
                          class="card-btn-add"
                          @click="showOperateDialog('node')"
                        >
                          <i class="el-icon-plus" />
                        </div>
                      </div>
                    </el-col>
                    <el-col
                      v-for="node in checkedNodeList"
                      :key="node.deployNodeID"
                      :span="8"
                    >
                      <div class="service-edit-card">
                        <div
                          class="card-btn-close"
                          @click="showDeleteDialog(node, 'node')"
                        >
                          <i class="el-icon-close" />
                        </div>
                        <div class="card-header">
                          <span>{{ node.deployNodeName }}</span>
                        </div>
                      </div>
                    </el-col>
                  </el-row>
                </template>
                <template v-else>
                  <NoData />
                </template>
              </div>
            </main>
          </div>
        </el-col>
        <el-col :span="8">
          <div class="part">
            <header class="title">
              <p class="manageTitle">输入</p>
            </header>
            <main class="content first-content">
              <el-form
                ref="inputForm"
                class="input-form"
                :model="inputForm"
                label-position="right"
                label-width="72px"
                size="mini"
              >
                <el-form-item
                  label="来源"
                  prop="protocolID"
                >
                  <el-select v-model="inputForm.protocolID">
                    <el-option
                      v-for="protocol in protocolList"
                      :key="protocol.protocolID"
                      :value="protocol.protocolID"
                      :label="protocol.protocolName"
                    />
                  </el-select>
                </el-form-item>
                <el-form-item
                  label="并发线程数"
                  prop="threads"
                  label-width="86px"
                >
                  <el-input
                    v-model="inputForm.threads"
                    width="166px"
                    placeholder="请输入并发线程数"
                    clearable
                  />
                </el-form-item>
                <el-form-item
                  label="来源配置"
                  prop="connectConfig"
                >
                  <el-input
                    v-model="inputForm.connectConfig"
                    placeholder="请输入来源配置"
                    type="textarea"
                    :autosize="{ minRows: 4, maxRows: 4 }"
                    resize="none"
                    clearable
                  />
                </el-form-item>
              </el-form>
            </main>
            <header class="title">
              <p class="manageTitle">源数据</p>
            </header>
            <main class="content second-content">
              <div class="scrollbar">
                <template v-if="sourceList.length">
                  <el-row :gutter="16">
                    <el-col :span="8">
                      <div class="service-edit-card">
                        <div
                          class="card-btn-add"
                          @click="showOperateDialog('source')"
                        >
                          <i class="el-icon-plus" />
                        </div>
                      </div>
                    </el-col>
                    <el-col
                      v-for="source in checkedSourceList"
                      :key="source.sourceDataID"
                      :span="8"
                    >
                      <div class="service-edit-card">
                        <div
                          class="card-btn-close"
                          @click="showDeleteDialog(source, 'source')"
                        >
                          <i class="el-icon-close" />
                        </div>
                        <div class="card-header">
                          <span>{{ source.dataName }}</span>
                        </div>
                      </div>
                    </el-col>
                  </el-row>
                </template>
                <template v-else>
                  <NoData />
                </template>
              </div>
            </main>
          </div>
        </el-col>
        <el-col :span="8">
          <div class="part">
            <header class="title">
              <p class="manageTitle">数据处理</p>
            </header>
            <main class="content">
              <div class="scrollbar">
                <template v-if="processList.length">
                  <el-row :gutter="16">
                    <el-col :span="8">
                      <div class="service-edit-card">
                        <div
                          class="card-btn-add"
                          @click="showOperateDialog('process')"
                        >
                          <i class="el-icon-plus" />
                        </div>
                      </div>
                    </el-col>
                    <el-col
                      v-for="process in checkedProcessList"
                      :key="process.id"
                      :span="8"
                    >
                      <div class="service-edit-card">
                        <div
                          class="card-btn-close"
                          @click="showDeleteDialog(process, 'process')"
                        >
                          <i class="el-icon-close" />
                        </div>
                        <div class="card-header">
                          <span>{{ process.processName }}</span>
                        </div>
                      </div>
                    </el-col>
                  </el-row>
                </template>
                <template v-else>
                  <NoData />
                </template>
              </div>
            </main>
          </div>
        </el-col>
        <el-col :span="8">
          <div class="part">
            <header class="title">
              <p class="manageTitle">数据输出</p>
              <el-button
                size="small"
                type="primary"
                class="btn-white"
                @click="showOperateDialog('output')"
              >新增</el-button>
            </header>
            <main class="content">
              <div class="scrollbar">
                <el-row :gutter="16">
                  <el-col
                    v-for="outputTarget in outputList"
                    :key="outputTarget.serviceOutputID"
                    :span="24"
                  >
                    <div
                      class="service-edit-card"
                      style="height: 160px"
                    >
                      <div
                        class="card-btn-close"
                        @click="showDeleteDialog(outputTarget, 'output')"
                      >
                        <i class="el-icon-close" />
                      </div>
                      <div class="card-header">
                        <span>{{ outputTargetProtocolName(outputTarget.protocolID) }}</span>
                        <i
                          class="icon-edit"
                          @click="btnEditClickHandler(outputTarget, 'output')"
                        />
                      </div>
                      <div class="card-main">
                        <div class="flex">
                          <div class="left">目标配置：</div>
                          <div
                            class="multiple-ellipsis"
                            :title="outputTarget.dataOutputConfig"
                          >{{ outputTarget.dataOutputConfig }}</div>
                        </div>
                        <span>{{ outputTargetDataName(outputTarget.targetdataID) }}</span>
                      </div>
                    </div>
                  </el-col>
                </el-row>
              </div>
            </main>
          </div>
        </el-col>
      </el-row>
    </div>
    <Dialog
      :flag="operateDialogVisible"
      width="500px"
    >
      <template v-if="['node', 'source', 'process'].includes(operateDialogType)">
        <div class="dialog-checkbox">
          <div class="title">{{ dataInMap(operateDialogType, 'title') }}</div>
          <main class="content">
            <el-checkbox-group v-model="tempCheckedKeys">
              <el-checkbox
                v-for="item in dataInMap(operateDialogType, 'list')"
                :key="item[dataInMap(operateDialogType, 'key')]"
                :label="item[dataInMap(operateDialogType, 'key')]"
              >{{ item[dataInMap(operateDialogType, 'label')] }}</el-checkbox>
            </el-checkbox-group>
          </main>
          <div class="foot">
            <el-button
              size="medium"
              type="primary"
              class="r25 r26"
              @click="checkedSubmitHandler"
            >提交</el-button>
            <el-button
              size="medium"
              class="r26"
              @click="hideOperateDialog"
            >取消</el-button>
          </div>
        </div>
      </template>
      <template v-if="operateDialogType === 'output'">
        <div id="dialog-form">
          <div class="title">数据输出编辑</div>
          <main class="content">
            <el-form
              ref="outputForm"
              class="output-form"
              :model="outputForm"
              label-position="right"
              label-width="72px"
              size="mini"
            >
              <el-form-item
                label="协议类型"
                prop="protocolID"
              >
                <el-select v-model="outputForm.protocolID">
                  <el-option
                    v-for="item in protocolList"
                    :key="item.protocolID"
                    :value="item.protocolID"
                    :label="item.protocolName"
                  />
                </el-select>
              </el-form-item>
              <el-form-item
                label="协议配置"
                prop="dataOutputConfig"
              >
                <el-input
                  v-model="outputForm.dataOutputConfig"
                  type="textarea"
                  placeholder="请输入协议配置"
                  :autosize="{ minRows: 4, maxRows: 4 }"
                  resize="none"
                  clearable
                />
              </el-form-item>
              <el-form-item
                label="目标数据"
                prop="targetdataID"
              >
                <el-select v-model="outputForm.targetdataID">
                  <el-option
                    v-for="item in targetList"
                    :key="item.targetdataID"
                    :value="item.targetdataID"
                    :label="item.tdataName"
                  />
                </el-select>
              </el-form-item>
              <el-form-item
                label="输出条件"
                prop="outputCondition"
              >
                <el-input
                  v-model="outputForm.outputCondition"
                  type="textarea"
                  placeholder="请输入输出条件"
                  :autosize="{ minRows: 4, maxRows: 4 }"
                  resize="none"
                  clearable
                />
              </el-form-item>
            </el-form>
          </main>
          <div class="foot">
            <el-button
              size="medium"
              type="primary"
              class="r25 r26"
              @click="outputSubmitHandler"
            >提交</el-button>
            <el-button
              size="medium"
              class="r26"
              @click="hideOperateDialog"
            >取消</el-button>
          </div>
        </div>
      </template>
    </Dialog>
    <!--删除弹框-->
    <Dialog :flag="deleteDialogVisible">
      <div class="dialog-delete">
        <div class="del-title">删除{{ dataInMap(deleteDialogType, 'deleteTitle') }}</div>
        <div class="content er">
          <div class="log">
            你是否确认删除{{ delObj[dataInMap(deleteDialogType, 'label')] || '这一项' }}？
          </div>
        </div>
        <div class="del-foot right t30">
          <el-button
            size="medium"
            class="r25 r26"
            type="danger"
            @click="deleteSubmitHandler"
          >删除</el-button>
          <el-button
            size="medium"
            class="r26"
            @click="hideDeleteDialog"
          >取消</el-button>
        </div>
      </div>
    </Dialog>
  </div>
</template>

<script>
import NoData from '@/components/nodata'
import Dialog from '@/layout/components/Dialog'
import query from './mixins/query'
import operate from './mixins/operate'

const keyMap = {
  node: {
    title: '部署机器选择',
    deleteTitle: '机器',
    key: 'deployNodeID',
    label: 'deployNodeName',
    list: 'nodeList',
    checked: 'checkedNodeKeys',
    operate: 'updateServiceNode'
  },
  source: {
    title: '源数据',
    deleteTitle: '源数据',
    key: 'sourceDataID',
    label: 'dataName',
    list: 'sourceList',
    checked: 'checkedSourceKeys',
    operate: 'updateServiceSource'
  },
  process: {},
  output: {
    deleteTitle: '输出目标',
    key: 'serviceOutputID',
    list: 'outputList',
    operate: 'updateServiceOutput'
  }
}

export default {
  components: { NoData, Dialog },
  mixins: [query, operate],
  data() {
    return {
      serviceID: Number(this.$route.query.serviceID),
      operateDialogType: null,
      delObj: {},
      deleteDialogType: null,
      tempCheckedKeys: [],
      serviceForm: {
        serviceName: '',
        isAsynchronous: null,
        serviceDescribe: ''
      },
      inputForm: {
        protocolID: null,
        threads: null,
        connectConfig: ''
      },
      outputForm: {
        protocolID: null,
        dataOutputConfig: '',
        targetdataID: null,
        outputCondition: '',
        serviceOutputID: null
      },
      targetList: [],
      protocolList: [],
      nodeList: [],
      checkedNodeKeys: [],
      serviceAndNodeList: [],
      sourceList: [],
      checkedSourceKeys: [],
      serviceAndSourceList: [],
      processList: [],
      checkedProcessKeys: [],
      outputList: []
    }
  },
  computed: {
    // 获取各关联项的标题、键名、操作方法等
    dataInMap() {
      return function (type, keyType) {
        if (type === null) {
          return null
        }
        if (['title', 'deleteTitle', 'key', 'label'].includes(keyType)) {
          return keyMap[type][keyType]
        } else {
          return this[keyMap[type][keyType]]
        }
      }
    },
    operateDialogVisible() {
      return Boolean(this.operateDialogType)
    },
    deleteDialogVisible() {
      return Boolean(this.deleteDialogType)
    },
    checkedNodeList() {
      return this.nodeList.filter(item => this.checkedNodeKeys.includes(item.deployNodeID))
    },
    checkedSourceList() {
      return this.sourceList.filter(item => this.checkedSourceKeys.includes(item.sourceDataID))
    },
    checkedProcessList() {
      return this.processList.filter(item => this.checkedProcessKeys.includes(item.processName))
    },
    // 从协议列表中根据协议ID获取协议名称
    outputTargetProtocolName() {
      return function (protocolID) {
        return this.protocolList.find(protocol => protocol.protocolID === protocolID).protocolName
      }
    },
    // 从目标数据列表中根据目标数据ID获取目标数据名称
    outputTargetDataName() {
      return function (targetdataID) {
        return this.targetList.find(target => target.targetdataID === targetdataID).tdataName
      }
    }
  },
  methods: {
    // 服务信息保存
    async btnSaveClickHandler() {
      this.$refs['serviceForm'].validate(valid => {
        if (!valid) return
      })
      this.$refs['inputForm'].validate(valid => {
        if (!valid) return
      })
      await this.updateService()
      this.queryAll()
    },
    // 关联编辑-显示弹框
    showOperateDialog(type) {
      if (['node', 'source', 'process'].includes(type)) {
        this.tempCheckedKeys = [...this.dataInMap(type, 'checked')]
      }
      this.operateDialogType = type
    },
    btnEditClickHandler(obj, type) {
      // Object.keys(this.outputForm).forEach(key => {
      //   this.outputForm[key] = obj[key]
      // })
      this.outputForm = obj
      this.showOperateDialog(type)
    },
    // 关联编辑-提交
    async checkedSubmitHandler() {
      const addKeys = this.tempCheckedKeys.filter(
        key => !this.dataInMap(this.operateDialogType, 'checked').includes(key)
      )
      const removeKeys = this.dataInMap(this.operateDialogType, 'checked').filter(
        key => !this.tempCheckedKeys.includes(key)
      )
      const createArr = addKeys.map(key => this.dataInMap(this.operateDialogType, 'operate')('create', key))
      const deleteArr = removeKeys.map(key => this.dataInMap(this.operateDialogType, 'operate')('delete', key))
      try {
        await Promise.all([...createArr, ...deleteArr])
        this.$message.success('成功')
        await this.queryAll()
        this.hideOperateDialog()
      } catch (error) {
        this.$message.error(error)
      }
    },
    // 服务输出项新增/编辑
    async outputSubmitHandler() {
      const outputTarget = {
        ...this.outputForm
      }
      try {
        let message
        if (outputTarget.serviceOutputID !== null) {
          message = await this.updateServiceOutput('update', outputTarget)
        } else {
          message = await this.updateServiceOutput('create', outputTarget)
        }
        this.$message.success(message ?? '成功')
        await this.queryAll()
        this.hideOperateDialog()
      } catch (error) {
        this.$message.error(error)
      }
    },
    // 关联编辑-隐藏弹框
    hideOperateDialog() {
      if (this.operateDialogType === 'output') {
        this.$refs['outputForm'].resetFields()
      }
      this.operateDialogType = null
    },
    // 关联删除-显示弹框
    showDeleteDialog(obj, type) {
      this.delObj = obj
      this.deleteDialogType = type
    },
    // 关联删除-提交
    async deleteSubmitHandler() {
      const operate = this.dataInMap(this.deleteDialogType, 'operate')
      let message
      try {
        if (this.deleteDialogType === 'output') {
          message = await operate('delete', this.delObj)
        } else {
          message = await operate('delete', this.delObj[this.dataInMap(this.deleteDialogType, 'key')])
        }
        this.$message.success(message ?? '成功')
        await this.queryAll()
        this.hideDeleteDialog()
      } catch (error) {
        this.$message.error(error)
      }
    },
    // 关联删除-隐藏弹框
    hideDeleteDialog() {
      this.deleteDialogType = null
      this.delObj = {}
    }
  }
}
</script>

<style lang="scss" scoped>
.service-edit {
  margin: 0 -24px;
  padding-bottom: 16px;
  overflow: hidden;
  .scrollbar {
    height: calc(100vh - 120px);
    padding: 0 24px;
    overflow-x: hidden;
    overflow-y: auto;
    ::v-deep .part {
      height: 640px;
      padding: 26px 24px 0 24px;
      background: #ffffff;
      box-shadow: 0px 3px 3px 0px rgba(0, 0, 0, 0.1);
      border-radius: 4px;
      &.part-top {
        height: 296px;
        margin-bottom: 24px;
        overflow: hidden;
      }
      .title {
        display: flex;
        justify-content: space-between;
        margin-bottom: 24px;
        &:nth-of-type(2) {
          margin-top: 10px;
        }
        .manageTitle {
          height: 32px;
          line-height: 30px;
        }
        .el-button {
          width: 64px;
          height: 32px;
          border: none;
          &.btn-white {
            background-color: #ffffff;
            border: 1px solid #92ace2;
            color: #2d67e3;
          }
          &:hover {
            background-color: #487be8;
            color: #ffffff;
          }
        }
      }
      label,
      span,
      button,
      input,
      optgroup,
      select,
      textarea {
        font-family: Helvetica, Microsoft YaHei;
        font-size: 14px;
        font-weight: 400;
      }
      label {
        color: #303133;
      }
      input {
        color: #101116;
      }
      .el-input__inner,
      .el-textarea__inner {
        padding-left: 8px;
        padding-right: 8px;
      }
      .el-radio {
        font-weight: 400;
      }
      .content {
        margin: 0;
        &:not(.first-content) {
          height: calc(100% - 32px - 24px);
        }
        &.second-content {
          height: calc(100% - 297px);
        }
        > .scrollbar {
          margin: -12px -24px 0 0;
          padding: 12px 24px 28px 0;
          height: calc(100% + 12px);
          > .el-row > .el-col {
            margin-bottom: 16px;
            .service-edit-card {
              height: 80px;
              padding: 16px 14px 0 16px;
              background: #f5f7fa;
              box-shadow: 0px 3px 3px 0px rgba(0, 0, 0, 0.1);
              border-radius: 4px;
              position: relative;
              font-family: Helvetica, 'Microsoft YaHei';
              .card-btn-add {
                margin: -16px -14px 0 -16px;
                height: calc(100% + 16px);
                border: 1px dashed #9ebbf7;
                cursor: pointer;
                position: relative;
                .el-icon-plus {
                  font-size: 32px;
                  color: #9ebbf7;
                  position: absolute;
                  top: 50%;
                  left: 50%;
                  margin: -16px -16px;
                }
              }
              .card-btn-close {
                position: absolute;
                top: -12px;
                right: -12px;
                z-index: 10;
                width: 24px;
                height: 24px;
                line-height: 24px;
                text-align: center;
                background: #000000;
                opacity: 0.8;
                border-radius: 50%;
                color: #ffffff;
                cursor: pointer;
              }
              .card-header {
                display: flex;
                justify-content: flex-start;
                color: #101116;
                font-size: 14px;
                margin-bottom: 30px;
                .icon-edit {
                  width: 14px;
                  height: 14px;
                  display: inline-block;
                  background-repeat: no-repeat;
                  background-size: cover;
                  transition: all 0.3s;
                  margin-left: 16px;
                  cursor: pointer;
                  background-image: url('../../../../assets/status/ic_edit_default.png');
                  &:hover {
                    background-image: url('../../../../assets/status/ic_edit_hovar.png');
                  }
                }
              }
              .card-main {
                font-size: 14px;
                font-family: Helvetica, Microsoft YaHei;
                color: #101116;
                .flex {
                  height: 32px;
                  margin-bottom: 23px;
                  .left {
                    padding-right: 9px;
                  }
                  .multiple-ellipsis {
                    flex: 1;
                    display: -webkit-box;
                    overflow: hidden;
                    text-overflow: ellipsis;
                    word-break: break-all;
                    -webkit-box-orient: vertical;
                    -webkit-line-clamp: 2;
                  }
                }
              }
            }
          }
        }
      }
      &:nth-last-child(1) .content > .scrollbar > .el-row > .el-col {
        margin-bottom: 24px;
        &:nth-last-child(1) {
          margin-bottom: 0;
        }
      }
    }
  }
  ::v-deep .service-form {
    display: flex;
    flex-wrap: wrap;
    .el-form-item {
      margin-bottom: 25px;
      .el-form-item__label {
        padding-right: 16px;
      }
      &:nth-child(2) {
        margin-left: 80px;
        flex: 1;
        .el-form-item__label {
          margin-right: 9px;
        }
      }
      &:nth-child(3) {
        width: 100%;
      }
    }
  }
  ::v-deep .input-form {
    display: flex;
    flex-wrap: wrap;
    .el-form-item {
      margin-bottom: 25px;
      .el-form-item__label {
        padding-right: 16px;
      }
      &:nth-child(2) {
        margin-left: 54px;
        flex: 1;
      }
      &:nth-child(3) {
        width: 100%;
      }
    }
  }
  .dialog-checkbox {
    .content {
      margin-left: 16px;
      .el-checkbox-group {
        margin-right: 24px;
        .el-checkbox {
          margin-bottom: 24px;
          font-family: Helvetica, Microsoft YaHei;
          color: #303133;
        }
      }
    }
  }
  ::v-deep #dialog-form .el-select .el-input__inner {
    width: 100%;
  }
}
</style>
