<template>
  <el-dialog
    :model-value="modelValue"
    append-to-body
    @close="cancel"
    @open="handleOpen"
  >
    <el-row>
      <el-table
        ref="tableRef"
        v-loading="loading"
        :data="dataList"
        @select="handleSelect"
        @select-all="handleSelectAll"
      >
        <el-table-column
          v-if="!readonly"
          align="center"
          type="selection"
          width="55"
        />
        <el-table-column
          v-for="item in tableStruct"
          :key="item.label || item.prop"
          :label="item.label"
          :prop="item.prop"
          align="center"
        >
          <template v-if="item.operate" #default="{ row }">
            <el-button
              v-for="button in item.operate"
              :key="button.label"
              :icon="button.icon"
              :type="button.type"
              link
              size="small"
              @click="button.onClick(row)"
            >
              {{ button.label }}
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <pagination
        v-show="total > 0"
        v-model:limit="queryParams.pageSize"
        v-model:page="queryParams.pageNum"
        :total="total"
        @pagination="getList"
      />
    </el-row>

    <template #footer>
      <div class="dialog-footer">
        <el-button v-if="!readonly" type="primary" @click="confirmSelect"
          >确认</el-button
        >
        <el-button @click="cancel">取 消</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script name="TableSelect" setup>
import { nextTick, reactive, ref, toRefs, watchEffect } from "vue";
import { cloneDeep } from "lodash-es";
import Pagination from "@/components/Pagination/index.vue";

const props = defineProps({
  list: {
    type: Array,
    default: [],
  },
  tableStruct: {
    type: Array,
    default: [],
  },
  readonly: {
    type: Boolean,
    default: false,
  },
  requestMethod: {
    type: Function,
    required: true,
  },
  selectKey: {
    required: true,
  },
  modelValue: {
    type: Boolean,
  },
});
const { list } = toRefs(props);

const emit = defineEmits(["update:modelValue", "confirm-select"]);

const loading = ref(false);
const dataList = ref([]);
const total = ref(0);
const open = ref(false);
const selectedProperties = ref([]);
const ids = ref([]);
const data = reactive({
  queryParams: {
    pageNum: 1,
    pageSize: 10,
  },
});

const { queryParams } = toRefs(data);
const tableRef = ref();

watchEffect(() => {
  ids.value = selectedProperties.value.map((el) => el[props.selectKey]);
});

const handleOpen = () => {
  if (list.value) {
    selectedProperties.value = cloneDeep(list.value);
  }
  getList();
};

function getList() {
  loading.value = true;
  props.requestMethod(queryParams.value).then((response) => {
    dataList.value = response.rows;
    total.value = response.total;
    loading.value = false;
    setRowSelected();
  });
}

const cancel = () => {
  selectedProperties.value = [];
  emit("update:modelValue", false);
};

/*监听单选事件*/
const handleSelect = (selection, row) => {
  const isCheck =
    selection.findIndex((el) => el[props.selectKey] === row[props.selectKey]) >
    -1;
  if (isCheck) {
    /*添加选中*/
    const isIdNotExist =
      selectedProperties.value.findIndex(
        (el) => el[props.selectKey] === row[props.selectKey]
      ) === -1;
    if (isIdNotExist) {
      selectedProperties.value.push(row);
    }
  } else {
    /*移除选中*/
    selectedProperties.value = selectedProperties.value.filter(
      (el) => el[props.selectKey] !== row[props.selectKey]
    );
  }
};

/*监听全选事件*/
const handleSelectAll = (selection) => {
  if (selection.length > 0) {
    /*全选*/
    for (const selectionElement of selection) {
      /*添加选中*/
      const isIdNotExist =
        selectedProperties.value.findIndex(
          (el) => el[props.selectKey] === selectionElement[props.selectKey]
        ) === -1;
      if (isIdNotExist) {
        selectedProperties.value.push(selectionElement);
      }
    }
  } else {
    /*全不选*/
    for (const dataElement of dataList.value) {
      /*移除选中*/
      selectedProperties.value = selectedProperties.value.filter(
        (el) => el[props.selectKey] !== dataElement[props.selectKey]
      );
    }
  }
};

/*选择模式下, 将选过的设为选中状态*/
const setRowSelected = () => {
  nextTick(() => {
    for (const id of ids.value) {
      dataList.value.forEach((el) => {
        if (el[props.selectKey] === id) {
          if (tableRef.value) {
            tableRef.value.toggleRowSelection(el, true);
          }
        }
      });
    }
  });
};

const confirmSelect = () => {
  emit("confirm-select", selectedProperties.value);
};

defineExpose({
  getList,
});
</script>

<style lang="scss" scoped>
:deep(.el-table__header) {
  .el-table-column--selection {
    .el-checkbox {
      //visibility: hidden;
    }
  }
}
</style>
