<template>
  <MegaModal
    width="100%"
    wrap-class-name="select-cp-modal-wrap"
    :visible="visible"
    :mask-closable="false"
    :destroy-on-close="false"
    :title="$t('SELECT_COMPONENT')"
    :dialog-style="{ top: 0, height: '100%', paddingBottom: 0 }"
    @cancel="handleCloseDrawer"
    @ok="handleOk"
  >
    <MegaTableQueryFilter
      :query-param="queryParamForm"
      :query-param-item="queryParamItem"
      @query="querySearch"
      @reset="queryReset"
    />

    <a-row type="flex" :gutter="1" class="select-cp-content">
      <a-col :span="15" class="select-cp__left">
        <div class="select-cp__left-wrap">
          <a-list
            type="flex"
            :grid="{ gutter: 22, column: 3, justify: 'space-around' }"
            :data-source="cpList"
            :pagination="{
              pageSize,
              showSizeChanger: true,
              showQuickJumper: true,
              showTotal: (total) => $t('TOTAL_RECORD').replace('{}', total),
              pageSizeOptions: ['9', '18', '30'],
              current: currentPage,
              total: total,
              onChange: handlePageChange,
              onShowSizeChange: handlePageChange,
            }"
          >
            <a-list-item slot="renderItem" slot-scope="item">
              <a-card
                class="cp-card"
                :class="{ active: activedCp.id === item.id }"
                @click.stop="() => handleActived(item)"
              >
                <div class="cp-card-icon">
                  <MegaIcon
                    v-if="item.icon"
                    :type="item.icon"
                    :size="50"
                  ></MegaIcon>
                </div>
                <div class="cp-card-info">
                  <div class="title">{{ item.componentName }}</div>
                  <div class="tips">{{ item.remark }}</div>
                </div>
                <div
                  class="cp-card-checked"
                  :class="{ active: selectedCpKeys.includes(item.id) }"
                  @click.stop="() => handleSelected(item)"
                >
                  <a-icon type="check-circle" theme="filled" />
                </div>
              </a-card>
            </a-list-item>
          </a-list>
        </div>
      </a-col>
      <a-col :span="9" class="select-cp__right">
        <div class="title">{{ $t("COMPONENT_ATTRIBUTES") }}</div>
        <MegaForm
          style="padding: 12px 14px"
          :query-param="cpAttrForm"
          :query-param-item="cpAttrFormItem"
        />
      </a-col>
    </a-row>
  </MegaModal>
</template>
<script>
import cloneDeep from "lodash/cloneDeep";
import {
  Modal as MegaModal,
  Icon as MegaIcon,
  Form as MegaForm,
  TableQueryFilter as MegaTableQueryFilter,
} from "@mega-design/ui-vue";
import ApiConstant from "@/api/ApiConstant";
import { formatJson } from "@/utils/formatter";

export default {
  components: {
    MegaTableQueryFilter,
    MegaModal,
    MegaIcon,
    MegaForm,
  },
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    multiple: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      queryParamForm: {
        componentName: undefined,
        componentType: undefined,
      },
      checked: true,
      currentPage: 1,
      pageSize: 9,
      total: 0,
      cpList: [],
      form: {
        facStationId: "",
        remark: "",
      },

      stationOptions: [],

      activedCp: {}, // actived 组件
      cpAttrForm: {}, // actived 组件属性列表
      cpAttrFormItem: {},

      selectedCps: [], // selected 组件
    };
  },
  computed: {
    queryParamItem() {
      return this.$observable("queryParamItem", {
        componentName: {
          itemType: "input",
          label: () => this.$t("COMPONENT_NAME"),
        },
        componentType: {
          itemType: "select",
          label: () => this.$t("COMPONENT_TYPE"),
          options: [],
          optionsProps: {
            label: "label",
            value: "value",
          },
        },
      });
    },
    selectedCpKeys() {
      return this.selectedCps.map((item) => item.id);
    },
  },
  watch: {
    visible: {
      handler(value) {
        value && this.querySearch();
      },
      immediate: true,
    },
  },
  created() {
    this.beforeSearch();
  },
  methods: {
    handlePageChange(current, pageSize) {
      this.currentPage = current;
      this.pageSize = pageSize;
      this.querySearch();
    },
    beforeSearch() {
      return Promise.all([
        this.getDictByCode("DIC:IDE:COMPONENT_TYPE"), // 组件类型
      ]).then((res) => {
        this.queryParamItem.componentType.options = res[0]?.data?.data || [];
      });
    },
    querySearch() {
      this.$axios
        .get(`${ApiConstant.PREFIX_CORE}/api/idewebcomponent/search`, {
          params: {
            ...this.queryParamForm,
            page: this.currentPage,
            size: this.pageSize,
          },
        })
        .then((res) => {
          this.cpList = res.data.data.records;
          this.total = Number(res.data.data.total);
        });
    },
    queryReset() {
      this.queryParamForm.componentName = undefined;
      this.queryParamForm.componentType = undefined;
      this.querySearch();
    },
    handleActived(item) {
      this.activedCp = cloneDeep(item);
      this.$set(this, "cpAttrForm", {});
      this.$set(this, "cpAttrFormItem", {});
      // 获取组件属性
      this.$axios
        .get(
          `${ApiConstant.PREFIX_CORE}/api/idewebcomponent/get-by-id/${item.id}`
        )
        .then((res) => {
          res.data.data.attributeList?.forEach(async (attr) => {
            let value = attr.defaultValue || undefined;
            if (["Float", "Integer"].includes(attr.attrValueType)) {
              value = Number(value || 0) || undefined;
            } else if (attr.attrValueType === "Boolean") {
              value = value === "true";
            } else if (attr.attrValueType === "Array") {
              try {
                value = formatJson(value) || [];
              } catch (_err) {
                value = [];
              }
            } else if (typeof value === "object") {
              value = value.trim();
            }
            this.$set(this.cpAttrForm, attr.attrKey, value);

            const formItem = {
              label: () => this.$t(attr.attrName),
              rules: [],
            };
            // itemType
            if (attr.inputMode !== "MANUAL") {
              formItem.itemType = "select";
              formItem.options = [];
              formItem.optionsProps = {
                label: "label",
                value: "value",
              };
            }
            if (["Float", "Integer"].includes(attr.attrValueType)) {
              formItem.itemType = "inputNumber";
            }
            // rules
            if (attr.attrMust === "Y") {
              formItem.rules.push("required");
            }
            // 请求
            if (attr.inputMode === "DICT") {
              try {
                const response = await this.$axios.get(
                  `${ApiConstant.PREFIX_CORE}/api/sys/dict-data/${attr.valueSource}`
                );
                formItem.options = response.data.data || [];
              } catch (_e) {}
            } else if (attr.inputMode === "INTERFACE") {
              try {
                const response = await this.$axios.get(attr.valueSource);
                formItem.options = response.data.data || [];
              } catch (_e) {}
            }

            this.$set(this.cpAttrFormItem, attr.attrKey, formItem);
          });
        });
    },
    handleSelected(item) {
      // 设置 actived cp 的属性值
      if (
        this.selectedCps.length &&
        this.selectedCps[this.selectedCps.length - 1].id === this.activedCp?.id
      ) {
        this.$set(
          this.selectedCps[this.selectedCps.length - 1],
          "attrs",
          this.cpAttrForm
        );
      }
      const index = this.selectedCps.findIndex((cp) => cp.id === item.id);
      const tmp = cloneDeep(item);
      tmp.attrs = cloneDeep(this.cpAttrForm);
      if (index > -1) {
        this.selectedCps.splice(index, 1);
      } else if (this.multiple) {
        this.selectedCps.push(tmp);
      } else {
        this.selectedCps = [tmp];
      }
    },
    handleCloseDrawer() {
      this.$emit("update:visible", false);
    },
    handleOk() {
      // 设置 actived cp 的属性值
      if (
        this.selectedCps.length &&
        this.selectedCps[this.selectedCps.length - 1].id === this.activedCp?.id
      ) {
        this.$set(
          this.selectedCps[this.selectedCps.length - 1],
          "attrs",
          this.cpAttrForm
        );
      }
      this.$emit("confirm", this.selectedCpKeys, this.selectedCps);
      this.$emit("update:visible", false);
    },
  },
};
</script>

<style lang="less">
.select-cp-modal-wrap {
  height: 100%;
  .ant-modal-content {
    height: 100%;
  }
  .ant-modal-body {
    padding: 0;
  }
  .mega-design-pro-table-search-query-filter {
    border-bottom: 10px solid #f0f2f5;
  }
  .select-cp-content {
    width: 100%;
    height: calc(100% - 70px);
  }
  .select-cp__left {
    position: relative;
    height: 100%;
    &-wrap {
      padding: 24px 0 24px 24px;
      height: 100%;
      .ant-list {
        position: relative;
        height: 100%;
        .ant-spin-nested-loading {
          padding-right: 24px;
          height: calc(100% - 60px);
          overflow-y: auto;
        }
        .ant-list-pagination {
          padding-right: 24px;
        }
      }
    }
    .cp-card {
      height: 114px;
      border-radius: 8px 8px 8px 8px;
      border: 1px solid #dfe2e8;
      box-shadow: 0 1px 10px 1px rgba(22, 35, 62, 0.2);
      transition: all 0.2s;
      .ant-card-body {
        display: flex;
        padding: 20px 24px;
        cursor: pointer;
      }
      &-icon {
        color: @primary-color;
      }
      &-info {
        flex: 1;
        padding: 0 12px;
        .title {
          font-size: 16px;
          margin-bottom: 8px;
        }
        .tips {
          display: -webkit-box;
          opacity: 0.68;
          text-overflow: ellipsis;
          overflow: hidden;
          -webkit-line-clamp: 2;
          -webkit-box-orient: vertical;
        }
      }
      &-checked {
        width: 24px;
        font-size: 24px;
        margin-top: -6px;
        color: fade(@text-color, 20%);
        &.active {
          color: #006896;
        }
      }
      &.active {
        background: #006896;
        .cp-card-icon,
        .cp-card-info,
        .cp-card-checked.active {
          color: #fff;
        }
      }
    }
  }
  .select-cp__right {
    position: relative;
    background-color: #f4f7f9;
    &::before {
      content: "";
      position: absolute;
      width: 1px;
      height: 100%;
      left: -0.5px;
      top: 0;
      background-color: #efecec;
    }
    .title {
      background-color: #f5f5f5;
      font-weight: 700;
      font-size: 16px;
      height: 48px;
      line-height: 48px;
      padding: 0 24px;
      border-bottom: 1px solid #ebebeb;
    }
  }
}
</style>
