<!--
 * @description: 设置组件关联的公共组件
 * @Date: 2023-01-04 14:42:51
 * @Author: xing.heng
 * @LastEditors: wujian
 * @LastEditTime: 2023-06-02 15:35:43
-->
<template>
  <div>
    <div class="data-setting-data-box">
      <div class="lc-field-head">
        <div class="lc-field-title">
          组件联动
        </div>
      </div>
      <div class="lc-field-body">
        <div class="select-item select-item-title">
          <span class="input-wrap">目标组件</span>
          <span class="input-wrap">操作</span>
        </div>
        <div
          v-for="(field, index) in config.linkage.components"
          :key="index"
          class="select-item"
          :class="{ 'select-item-active': field.componentKey === activeCode }"
          @mouseenter="chooseComponent(field)"
        >
          <div class="input-wrap">
            <el-form-item
              label-width="0px"
            >
              <el-select
                v-model="field.componentKey"
                popper-class="bs-el-select"
                class="bs-el-select"
                size="mini"
                @change="changeComponent(...arguments, index)"
              >
                <el-option
                  v-for="item in allComponentsExpectSelf(config.code)"
                  :key="item.componentKey"
                  :label="item.name"
                  :value="item.componentKey"
                  :disabled="currentLinkComponentKey.includes(item.componentKey)"
                />
              </el-select>
            </el-form-item>
          </div>
          <div class="input-wrap">
            <div
              class="select-line-icon option-add"
              @click="setRelation(field)"
            >
              <el-tooltip
                effect="dark"
                content="组件联动设置"
                placement="top"
              >
                <i class="el-icon-setting" />
              </el-tooltip>
            </div>
            <div
              class="select-line-icon option-delete"
              @click="deleteLinkComponents(index)"
            >
              <i class="el-icon-remove-outline" />
            </div>
          </div>
        </div>
        <el-button
          v-block
          type="primary"
          @click="addLinkComponents"
        >
          新增联动组件
        </el-button>
      </div>
    </div>
    <RelationSetting
      :setting-visible.sync="settingVisible"
      :config-map="configMap"
      :source-field-list="sourceFieldList"
      :target-field-list="targetFieldList"
      @updateConfig="updateConfig"
    />
  </div>
</template>
<script>
import RelationSetting from './RelationSetting.vue'
import { cloneDeep } from 'lodash'
import { mapState } from 'vuex'
export default {
  name: 'ComponentRelation',
  components: {
    RelationSetting
  },
  directives: {
    block: {
      bind (el, binding) {
        el.style.width = binding.value || '100%'
      }
    }
  },
  props: {
    config: {
      type: Object,
      default: () => {}
    },
    // 当前组件的联动字段
    sourceFieldList: {
      type: Array,
      default: () => [
        // {
        //   label: '字段1',
        //   value: 'field1'
        // }
      ]
    }
  },
  data () {
    return {
      // 关联设置弹窗
      settingVisible: false,
      cloneDeepConfig: cloneDeep(this.config),
      configMap: {},
      targetFieldList: [],
      activeCode: null
    }
  },
  computed: {
    ...mapState({
      chartList: state => state.bigScreen.pageInfo.chartList
    }),
    // 当前已经关联的组件key
    currentLinkComponentKey () {
      return this.config.linkage.components?.map(item => item.componentKey) || []
    }
  },
  mounted () {
  },
  beforeDestroy () {
  },
  methods: {
    /**
     * @description: 获取除自己之外的所有组件
     */
    allComponentsExpectSelf (code) {
      let layouts = cloneDeep(this.chartList)
      const tabComponents = []
      layouts?.map((ly) => {
        if (ly.type === 'Tabs') {
          ly?.tabList?.map(com => {
            tabComponents.push(com.chart)
          })
        }
      })
      layouts = layouts?.filter(item => item.code !== code && item?.option?.displayOption?.dataAllocation?.enable)
      layouts = [...layouts, ...tabComponents]?.map(item => ({
        name: item.title,
        componentKey: item.code
      }))
      return layouts
    },
    /**
     * @description: 添加关联组件
     */
    addLinkComponents () {
      this.config.linkage.components.push({
        componentKey: '',
        maps: []
      })
    },
    /**
     * @description: 删除关联组件
     */
    deleteLinkComponents (index) {
      this.config.linkage.components.splice(index, 1)
    },
    /**
     * @description: 改变关联组件
     */
    changeComponent (componentKey, index) {
      this.$set(
        this.config.linkage.components,
        index,
        {
          componentKey,
          maps: []
        }
      )
    },
    /**
     * @description: 设置关联弹窗打开
     */
    setRelation (configMap) {
      this.settingVisible = true
      // 如果是tab页内部组件，先平铺
      let layouts = cloneDeep(this.chartList)
      const tabComponents = []
      layouts?.map((ly) => {
        if (ly.type === 'Tabs') {
          ly?.tabList?.map(com => {
            tabComponents.push(com.chart)
          })
        }
      })
      layouts = layouts?.filter(item => item?.option?.displayOption?.dataAllocation?.enable)
      layouts = [...layouts, ...tabComponents]
      this.targetFieldList = layouts.find(
        item => item.code === configMap.componentKey
      )?.inParams?.map(item => ({
        label: item.name,
        value: item.code
      }))
      this.configMap = cloneDeep(configMap)
    },
    /**
     * @description: 更新关联配置
     */
    updateConfig (configMapConfig) {
      const index = this.config.linkage.components?.findIndex(
        item => item.componentKey === configMapConfig.componentKey
      )
      this.$set(
        this.config.linkage.components,
        index,
        configMapConfig
      )
    },
    /**
     * @description: 选择组件
     */
    chooseComponent (field) {
      this.activeCode = field?.componentKey
    }
  }
}
</script>

<style scoped lang="scss">
::v-deep .el-tabs__nav-scroll {
  display: flex;
  justify-content: center;
}

::v-deep .el-tabs__nav-wrap::after {
  height: 0;
}

::v-deep .el-collapse-item__header {
  background: #f2f3f5;
  height: 32px;
  padding: 0 12px;
}

::v-deep .el-collapse-item__content {
  padding-bottom: 0;
}

.lc-field-body {
  padding: 12px;
}

::v-deep .el-tabs__nav-scroll {
  display: flex;
  justify-content: center;
}

::v-deep .el-tabs__nav-wrap::after {
  height: 0;
}

.design-tab-warp {
  padding: 10px;
}
::v-deep.el-tabs--top {
  height: 100%;
}
::v-deep .el-tabs__content {
  height: calc(100% - 40px);
  overflow-y: auto;
}
.setting-body {
  height: 100%;
}
// 筛选条件的按钮样式
.add-filter-box {
  position: relative;
  .add-filter {
    margin-left: 90px;
    margin-bottom: 10px;
  }
  .add-filter-btn {
    position: absolute;
    top: 0;
  }
}
.select-item {
  display: flex;
  margin-bottom: 8px;
  cursor: pointer;
  align-items: center;
  border: 1px solid #fff;
  padding: 4px;

  .input-wrap {
    flex: 1;
    display: flex;
    justify-content: center;
    margin-right: 2px;

    ::v-deep.el-form-item {
      margin-bottom: 0 !important;
    }

    .el-input-number--mini {
      width: 90px !important;
    }
  }
  .input-wrap_left {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: left;
  }

  .select-line-icon {
    width: 30px;
    font-size: 18px;
    cursor: pointer;
    text-align: center;
  }

  .option-delete {
    color: #f56c6c;
  }
}
.select-item-active {
  border: 1px solid var(--bs-el-color-primary);
  background: var(--bs-el-background-3);
}
// 修改设置面板样式
.data-setting-box{
  .data-setting-data-box{
    .lc-field-head{
      height: 30px;
      .lc-field-title{
        position: relative;
        padding-left: 12px;
        line-height: 30px;
        height: 30px;
        &:after{
          position: absolute;
          left: 0;
          top: 50%;
          transform: translateY(-50%);
          content: '';
          width: 4px;
          height: 14px;
          background-color: var(--bs-el-color-primary);
        }
      }
    }
  }
}
</style>
