<template>
  <div class="qu-table-wrap" ref="tableWrapRef">
    <div class="table-toolbar" v-if="tableButtons && tableButtons.length">
      <div class="table-toolbar-buttons">
        <el-button
          v-for="(item, index) in tableButtons"
          :key="index"
          :type="item.theme == '' ? 'primary' : item.theme"
          size="small"
          :icon="item.icon"
          :class="item.className"
          @click="$emits('buttonClick', item)"
        >{{ item.cnName }}</el-button>
      </div>
    </div>
    <el-table ref="quTabel" :data="tableData" :max-height="autoTableHeight" class="qu-table" :row-class-name="tableRowClassName"
      highlight-current-row style="width: 100%" stripe border @header-dragend="headerDragend" @select-all="selectAll"
      @select="select" @selection-change="selectionChange" @sort-change="sortChange">
      <el-table-column type="selection" width="55" v-if="showSelect" fixed />
      <el-table-column type="index" width="50" align="center" fixed v-if="showIndex">
        <template #header>
          <span @click.stop="openSetDialog" style="cursor: pointer" v-if="custom">
            <el-icon>
              <setting />
            </el-icon>
          </span>
        </template>
      </el-table-column>
      <template v-for="(header, index) in tableHeader" :key="index">
        <el-table-column :prop="header.enName" :label="header.cnName" :min-width="header.width" v-if="header.isTableShow"
          :fixed="header.fixed" :sortable="header.isSelect == 1 ? 'custom' : false"
          :show-overflow-tooltip="showOverflowTooltip">
          <template #default="scope">
            <!-- 时间类型 -->
            <template v-if="header.fieldType == 'date'">
              <el-icon>
                <timer />
              </el-icon>
              <span style="margin-left: 10px">{{
                  formatDate(scope.row[header.enName])
              }}</span>
            </template>
            <!-- select类型 -->
            <template v-else-if="header.fieldType == 'select'">
              <span class="table-tag" :style="{
                background:
                  formatSelectItem(header.enName, scope.row[header.enName])
                    .color || 'grey',
              }" v-if="
  scope.row[header.enName] !== null &&
  scope.row[header.enName] !== '' &&
  scope.row[header.enName] !== undefined
">{{
    formatSelectItem(header.enName, scope.row[header.enName])
      .label
}}</span>
            </template>
            <!-- 自定义类型 -->
            <template v-else-if="header.fieldType == 'custom'">
              <slot :name="header.enName" :row="scope.row" :$index="scope.$index" :column="scope.column">
              </slot>
            </template>

            <template v-else>
              <span>{{ scope.row[header.enName] }}</span>
            </template>
          </template>
        </el-table-column>
      </template>
      <template v-if="showActions">
        <el-table-column label="操作" fixed="right" align="center" :width="80" v-if="rowButtons.length != 0" fit>
          <template #default="scope">
            <el-popover placement="left" trigger="hover" popper-class="btn-popover">
              <template v-for="(item, index) in rowButtons" :key="index">
                <div class="row-buttons">
                  <el-button :class="[...item.className]" class="row-button" size="small" type="text" @click="
                    customCallback(
                      item,
                      { column: scope.column, row: scope.row },
                      index,
                      scope
                    )
                  ">
                    {{ item.cnName }}
                  </el-button>
                </div>
              </template>
              <template #reference>
                <el-button icon="more-filled" class="get-more" size="small" :circle="true" color="var(--color-primary)"
                  style="color: white; font-size: 14px">
                </el-button>
              </template>
            </el-popover>
          </template>
        </el-table-column>
      </template>
    </el-table>
    <el-pagination class="qu-table-pagination" v-if="showPage" v-model:currentPage="pageProps.page"
      :page-size="pageProps.rows" :page-sizes="[10, 20, 50, 100]" small="small" :background="true"
      layout="total, prev, pager, next,sizes" :total="pageProps.records" @size-change="handleSizeChange"
      @current-change="handleCurrentChange"></el-pagination>
    <el-drawer v-model="showSetDialog" title="设置表格属性" direction="rtl" :before-close="closeSetDialog" size="40%"
      :close-on-click-modal="false">
      <p>勾选需要显示的列，拖动列名进行排序。</p>
      <div class="custom-table-header">
        <ul class="header-list">
          <draggable v-model="custTableHeader" item-key="enName" @change="customSortChange">
            <template #item="{ element }">
              <li class="list-item" :key="element.enName">
                <div class="item-check">
                  <el-checkbox v-model="element.isTableShow" :true-label="1" :false-label="0">
                  </el-checkbox>
                </div>
                <div class="item-label">
                  <span>{{ element.cnName }}</span>
                  <div class="item-bg" :style="{ width: element.width + 'px' }"></div>
                </div>
                <div class="item-required">
                  <span></span>
                </div>
                <div class="item-set-width">
                  <span>宽度</span>
                  <el-input-number :min="20" v-model="element.width" :controls="false">
                  </el-input-number>
                  <span>px</span>
                </div>
              </li>
            </template>
          </draggable>
        </ul>
      </div>
      <template #footer>
        <div style="flex: auto">
          <el-button @click="showSetDialog = false">取消</el-button>
          <el-button type="primary" @click="confirmClick">确定</el-button>
        </div>
      </template>
    </el-drawer>
  </div>
</template>
<script>
export default {
  name: "qu-table",
};
</script>
<script setup>
import { ref, computed, getCurrentInstance, watch, onMounted, onBeforeUnmount, nextTick } from "vue";
import { useRoute } from "vue-router";
import draggable from "vuedraggable";
const props = defineProps({
  // 表格表头
  tableHeader: Array,
  // 表格数据
  tableData: Array,
  // 行按钮显示/隐藏
  showActions: {
    type: Boolean,
    default: true,
  },
  // 表格行按钮
  rowButtons: {
    type: Array,
    default: () => [],
  },
  // 表格高度
  height: {
    type: Number,
    default: 200,
  },
  // 复选框 显示/隐藏
  showSelect: {
    type: Boolean,
    default: false,
  },
  showIndex: {
    type: Boolean,
    default: true,
  },
  // 设置不同的行状态 success-row / warning-row
  tableRowClassName: {
    type: Function,
  },
  // 自定义表头 显示/隐藏
  custom: {
    type: Boolean,
    default: true,
  },
  // 分页 显示/隐藏
  showPage: {
    type: Boolean,
    default: true,
  },
  // 分页配置
  pageProps: {
    type: Object,
    default: {
      page: 1,
      size: 20,
      records: 0,
    },
  },
  showOverflowTooltip: {
    type: Boolean,
    default: false,
  },
  // 表格顶部操作按钮（可选，不传则不显示）
  tableButtons: {
    type: Array,
    default: () => [],
  },
});
// 定义emits方法
const $emits = defineEmits([
  "fetchTableAttr",
  "update:tableHeader",
  "fetchHandAllSelection",
  "selectionChange",
  "select",
  "sortChange",
  "pageChange",
  "rowButtonClick",
  "buttonClick",
]);
// 自动高度计算
const tableWrapRef = ref();
const observedHeight = ref(0);
let resizeObserver = null;

const autoTableHeight = computed(() => {
  if (observedHeight.value > 0) return observedHeight.value;
  return props.height;
});

const calcTableHeight = () => {
  const wrap = tableWrapRef.value;
  if (!wrap || !wrap.parentElement) return;
  // 用父容器高度计算，避免循环
  const parentHeight = wrap.parentElement.clientHeight;
  if (parentHeight <= 0) return;
  const toolbar = wrap.querySelector('.table-toolbar');
  const pagination = wrap.querySelector('.qu-table-pagination');
  const toolbarH = toolbar ? toolbar.offsetHeight : 0;
  const paginationH = pagination ? pagination.offsetHeight : 0;
  const available = parentHeight - toolbarH - paginationH;
  if (available > 100) {
    observedHeight.value = available;
  }
};

onMounted(() => {
  nextTick(() => {
    calcTableHeight();
    if (tableWrapRef.value?.parentElement) {
      resizeObserver = new ResizeObserver(() => calcTableHeight());
      resizeObserver.observe(tableWrapRef.value.parentElement);
    }
  });
});

onBeforeUnmount(() => {
  resizeObserver?.disconnect();
});

// 定义数据
const showSetDialog = ref(false); //自定义表头 弹窗  隐藏/显示
let custTableHeader = ref([]); //自定义表头数据
const quTabel = ref(); //表格ref
const { $common } = getCurrentInstance().appContext.config.globalProperties;

let selectItems = ref([]);
const selectItemsColors = ["#22c55e", "#f59e0b", "#ef4444", "#6366f1", "#8b5cf6", "#ec4899", "#6b7280", "#f97316", "#06b6d4", "#a16207", "#9ca3af"];
let route = useRoute()
watch(
  () => [props.tableHeader, props.tableData],
  (newVal) => {
    if (newVal[0].length != 0) {
      selectItems.value = $common.selectItems(newVal[0]);
    }
  },
  { immediate: true }
);

const formatDate = (dateStamp) => {
  const date = dateStamp ? $common.fomatDateTime(dateStamp) : "-";
  return date;
};
// 格式化select字段
const formatSelectItem = (headerName, columnValue) => {
  const items = selectItems.value[headerName];
  let label = "",
    colorIndex = 0;
  if (items && items.length != 0) {
    items.map((item, index) => {
      if (item.key == columnValue) {
        label = item.value;
        colorIndex = index;
      }
    });
  }
  return { label, color: selectItemsColors[colorIndex] };
};
// 自定义表格字段排序
const customSortChange = e => {
  // TODO 自定义表格字段排序 尚未测试通过
  // console.log(custTableHeader.value);
  // custTableHeader.value[e.]
  // 相邻位置的两个 互换排序值、
  // 如果位置由小->大 两个位置中间的排序值 -1
  // 如果位置由大->小 两个位置中间的排序值 +1
  // const { newIndex, oldIndex } = e.moved
  // custTableHeader.value[newIndex].orderBy = props.tableHeader[newIndex].orderBy
  // if (oldIndex - newIndex == 1 || newIndex - oldIndex == 1) {
  //   console.log('相邻位置');

  //   custTableHeader.value[oldIndex].orderBy = props.tableHeader[oldIndex].orderBy
  // } else if (oldIndex > newIndex) {
  //   console.log('由大->小');
  //   for (let i = newIndex + 1; i <= oldIndex; i++) {
  //     custTableHeader.value[i].orderBy++
  //   }
  // } else if (oldIndex < newIndex) {
  //   console.log('由小->大');
  //   for (let i = oldIndex; i < newIndex; i++) {
  //     custTableHeader.value[i].orderBy--
  //   }
  // }

}
// 打开自定义表头弹窗
const openSetDialog = () => {
  custTableHeader.value = JSON.parse(JSON.stringify(props.tableHeader));
  showSetDialog.value = true;
};
// 设置自定义表头数据
const confirmClick = () => {
  $emits("fetchTableAttr", custTableHeader.value);
  $emits("update:tableHeader", custTableHeader.value);
  // localStorage.setItem(route.name + 'Fields', JSON.stringify(custTableHeader.value))
  showSetDialog.value = false;
};
// 关闭自定义表头弹窗 清空自定义表头数据
const closeSetDialog = () => {
  showSetDialog.value = false;
  custTableHeader.value = [];
};
// 拖动列宽重置表头数据
const headerDragend = (newWidth, oldWidth, column, event) => {
  // console.log(newWidth, oldWidth, column, event);
  let loalTableHeader = JSON.parse(JSON.stringify(props.tableHeader));
  loalTableHeader.map((item, index) => {
    if (item.enName == column.property) {
      item.width = newWidth;
    }
  });
  $emits("update:tableHeader", loalTableHeader);
};
// 手动勾选全部chekcbox时触发
const selectAll = (selection) => {
  $emits("fetchHandAllSelection", selection);
};
const select = (selection, row) => {
  // console.log(selection, row);
  $emits("select", selection, row);
};

// 选择项发生变化时触发
const selectionChange = (selection) => {
  $emits("selectionChange", selection);
};
// 清除选中项
const clearSelection = () => {
  quTabel.value.clearSelection();
};
// 选中指定行
const toggleRowSelection = (row, selected) => {
  quTabel.value.toggleRowSelection(row, selected);
};
// 排序
const sortChange = ({ column, prop, order }) => {
  // console.log({ column, prop, order });
  const sortObj = {
    sidx: order ? prop : "id",
    sord: order == "ascending" ? "asc" : "desc",
  };
  $emits("sortChange", sortObj);
};
// 当分页条数变化时触发
const handleSizeChange = (rows) => {
  const { page } = props.pageProps;
  $emits("pageChange", { page, rows });
};
// 当分页页码变化时触发
const handleCurrentChange = (page) => {
  const { rows } = props.pageProps;
  $emits("pageChange", { page, rows });
};
const customCallback = ($column, obj, index, scope) => {
  $emits("rowButtonClick", {
    ...obj,
    index,
    $column,
    scopeIndex: scope.$index,
  });
};
const getSelectionRows = () => {
  console.log(quTabel);
  return quTabel.value.getSelectionRows();
};
defineExpose({
  clearSelection,
  toggleRowSelection,
  getSelectionRows,
});
</script>

<style lang="scss" scoped>
.qu-table-wrap {
  width: 100%;
  height: 100%;
  background: var(--color-bg-card);
  display: flex;
  flex-direction: column;
}

.qu-table-pagination {
  padding: 10px var(--spacing-sm) 2px;
  flex-shrink: 0;
}

.table-toolbar {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  padding: var(--spacing-xs) var(--spacing-sm);

  .table-toolbar-buttons {
    display: flex;
    gap: var(--spacing-xs);
  }
}

.qu-table {
  flex: 1;
  min-height: 0;

  :deep(.el-table__header) th .cell {
    white-space: nowrap;
  }

  :deep(.warning-row) {
    td.el-table__cell {
      background: var(--el-color-warning-light-9) !important;
    }
  }

  :deep(.success-row) {
    td.el-table__cell {
      background: var(--el-color-success-light-9) !important;
    }
  }

  .table-tag {
    padding: 2px 8px;
    color: #fff;
    border-radius: var(--radius-sm);
    font-size: var(--font-size-xs);
  }

  // 表格底部分隔修饰——区分表格与分页，标识滚动边界
  &::after {
    content: '';
    display: block;
    height: 3px;
    background: linear-gradient(to right, var(--color-primary-bg), var(--color-primary-light), var(--color-primary-bg));
    border-radius: 0 0 var(--radius-md) var(--radius-md);
  }
}

:deep(.el-drawer) {
  .el-drawer__header {
    margin-bottom: 0;
  }
}

.custom-table-header {
  .header-list {
    list-style: none;
    margin: 0;
    padding: 0;

    .list-item {
      display: flex;
      align-items: center;
      // padding: 5px 0;
      height: 40px;
      // box-sizing: border-box;
      border-bottom: 1px solid #f2f2f2;

      .item-check {
        width: 30px;
      }

      .item-label {
        flex: 1;
        position: relative;
        height: 80%;
        overflow: hidden;

        >span {
          z-index: 2;
          position: relative;
          line-height: 32px;
          padding-left: 10px;
          box-sizing: border-box;
        }

        .item-bg {
          position: absolute;
          background-color: rgb(194, 194, 194);
          top: 0;
          left: 0;
          height: 100%;
          z-index: 1;
        }
      }

      .item-required {
        width: 50px;
      }

      .item-set-width {
        width: 130px;

        .el-input-number {
          width: 80px;
          margin: 0 5px;
        }
      }
    }
  }
}
</style>
