<template>
  <el-popover
    ref="popover"
    :key="prop"
    placement="bottom"
    width="340"
    trigger="click"
    :class="{ 'has-filter': hasFilter() }"
    @show="onPopoverShow"
  >
    <!-- 搜索条 -->
    <div v-show="!['datetime', 'daterange'].includes(htmlType)" class="flex">
      <el-input
        v-model="searchKey"
        class="mb5 flex-1"
        placeholder="请输入"
        @keyup.enter.native="handleFilterSearch"
      />
      <div class="ml-3 flex">
        <el-tooltip content="降序" placement="top">
          <i
            class="el-icon-sort-down mr-5px"
            style="font-size: 18px; color: #409eff; cursor: pointer"
            @click="handleSort('desc')"
          />
        </el-tooltip>
        <el-tooltip content="升序" placement="top">
          <i
            class="el-icon-sort-up mr-5px"
            style="font-size: 18px; color: #409eff; cursor: pointer"
            @click="handleSort('asc')"
          />
        </el-tooltip>
        <el-tooltip content="反选" placement="top">
          <i
            class="el-icon-refresh-left"
            style="font-size: 18px; color: red; cursor: pointer"
            @click="handleInvertSelection"
          />
        </el-tooltip>
      </div>
    </div>

    <!-- 日期范围 -->
    <div v-if="['datetime', 'daterange'].includes(htmlType)" class="mb5">
      <div class="demonstration mb-5px">按日期查询</div>
      <el-date-picker
        v-model="dateRangeValue"
        type="datetimerange"
        range-separator="至"
        start-placeholder="开始"
        end-placeholder="结束"
        format="yyyy-MM-dd HH:mm:ss"
        :default-time="['00:00:00', '23:59:59']"
        style="width: 95%"
        @change="dateChange"
      />
    </div>

    <!-- 多选列表 -->
    <div v-else class="mb5">
      <el-table
        ref="multipleTable"
        :data="filteredList"
        size="mini"
        height="250"
        @selection-change="handleSelectionChange"
        @row-click="handleClickRow"
      >
        <el-table-column type="selection" width="50" />
        <el-table-column
          prop="column"
          :label="label || '数据'"
          show-overflow-tooltip
        >
          <template slot-scope="{ row }">
            <dict-tag
              v-if="dictType"
              :type="dictType"
              :value="row.column"
              size="small"
            />
            <span v-else>{{ row.column }}</span>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div v-if="total > 0" class="mt5">
        <el-pagination
          background
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          :page-size.sync="pageSize"
          :current-page.sync="pageNo"
          style="min-width: 300px; overflow-x: auto"
          :page-sizes="[20, 50, 100, 200]"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </div>

    <!-- 按钮 -->
    <div class="mt10 text-right">
      <el-button size="small" @click="filterCancel()">重置</el-button>
      <el-button type="primary" size="small" @click="filterConfirm"
        >筛选</el-button
      >
    </div>

    <!-- 触发元素 -->
    <template slot="reference">
      <span v-if="$slots.reference">
        <slot name="reference" />
      </span>
      <span v-else>{{ label }}</span>
    </template>
  </el-popover>
</template>

<script>
import { getFilterListInQuery } from "@/api/common";

export default {
  name: "FilterColumnInQuery",
  props: {
    prop: { type: String, required: true },
    label: { type: String, default: "" },
    activeFilters: { type: Object, default: () => ({}) },
    orderType: { type: String, default: "" },
    paramList: { type: Array, default: () => [] },
    dictType: { type: String, default: null },
    queryId: { type: String, default: null },
    htmlType: { type: String, default: "input" },
    isClear: { type: Boolean, default: false },
  },
  data() {
    return {
      searchKey: "",
      dateRangeValue: "",
      currentRows: [],
      allSelectedColumns: new Set(), // 保存选中的column值，确保跨分页唯一性
      filterData: [],
      loading: false,
      isFirstLoad: true,
      // 分页相关
      pageNo: 1,
      pageSize: 50,
      total: 0,
    };
  },
  computed: {
    originalList() {
      if (
        Array.isArray(this.filterData) &&
        this.filterData.length > 0 &&
        typeof this.filterData[0] === "string"
      ) {
        return this.filterData.map((item) => ({
          column: item,
          rawData: { [this.prop]: item },
        }));
      }
      return this.filterData.reduce((acc, cur) => {
        const val = cur[this.prop];
        const has = acc.some((i) => i.column === val);
        if (!has && val !== undefined && val !== null) {
          acc.push({ column: val, rawData: cur });
        }
        return acc;
      }, []);
    },
    filteredList() {
      // 先进行搜索过滤
      let filtered = this.originalList;
      if (this.searchKey.trim()) {
        filtered = this.originalList.filter((item) =>
          String(item.column)
            .toLowerCase()
            .includes(this.searchKey.toLowerCase())
        );
      }

      // 更新总数
      this.total = filtered.length;

      // 再进行分页
      const start = (this.pageNo - 1) * this.pageSize;
      const end = start + this.pageSize;
      return filtered.slice(start, end);
    },
  },
  watch: {
    // isClear(val) {
    //   console.log("监听到了isClear发生了变化");
    //   if (val) this.filterCancel(true);
    // },
  },
  // created() {
  //   console.log(
  //     `[%c子%c] created   ${this.prop}  ${Date.now()}`,
  //     "color:green",
  //     ""
  //   );
  // },
  // mounted() {
  //   console.log(
  //     `[%c子%c] mounted   ${this.prop}  ${Date.now()}`,
  //     "color:green",
  //     ""
  //   );
  // },
  beforeDestroy() {
    // console.log("[子] beforeDestroy", this.prop);
    /* 1. 清跨页集合 */
    this.allSelectedColumns.clear();
    /* 2. 清当前页选中 */
    this.currentRows = [];
    /* 3. 清搜索框 */
    this.searchKey = "";
    /* 4. 把“空结果”通知父组件，防止残留高亮 */
    // this.$emit("select-data", [], this.prop, this.htmlType);
  },
  // destroyed() {
  //   console.log(
  //     `[%c子%c] destroyed ${this.prop}  ${Date.now()}`,
  //     "color:red",
  //     ""
  //   );
  // },
  methods: {
    /* ---- 工具方法 ---- */
    hasFilter() {
      return !!(
        this.activeFilters[this.prop] && this.activeFilters[this.prop].length
      );
    },

    /* ---- 生命周期 ---- */
    async onPopoverShow() {
      console.log("onPopoverShow被调用");
      this.$nextTick(() => this.$refs.seachRef?.focus());
      if (this.isFirstLoad || this.searchKey) {
        await this.fetchFilterListInQueryManage(true);
        this.isFirstLoad = false;
      } else {
        await this.fetchFilterListInQueryManage(false);
      }
      this.restoreSelections();
    },
    // 直接在组件 methods 里放这一个即可
    formatDateTimeRange(range) {
      if (!Array.isArray(range) || range.length < 2) {
        throw new Error("formatDateTimeRange: 需要包含两个元素的数组");
      }
      const pad = (n) => String(n).padStart(2, "0");
      const format = (d) => {
        const date = new Date(d);
        const Y = date.getFullYear();
        const M = pad(date.getMonth() + 1);
        const D = pad(date.getDate());
        const h = pad(date.getHours());
        const m = pad(date.getMinutes());
        const s = pad(date.getSeconds());
        return `${Y}-${M}-${D} ${h}:${m}:${s}`;
      };
      return [format(range[0]), format(range[1])];
    },

    /* ---- 数据获取 ---- */
    async fetchFilterListInQueryManage(reload) {
      console.log(
        "fetchFilterListInQueryManage被调用，htmlType:",
        this.htmlType
      );
      if (["datetime", "daterange"].includes(this.htmlType)) return;
      try {
        this.loading = true;
        const params = {
          currentField: this.prop,
          paramList: this.paramList,
          id: this.queryId,
        };
        Object.keys(this.activeFilters).forEach((k) => {
          if (this.activeFilters[k]?.length) {
            params[k] = this.activeFilters[k].map((i) => i.column).join(",");
          }
        });
        console.log("调用getFilterListInQuery，参数:", params);
        const { data } = await getFilterListInQuery(params);
        this.filterData = data || [];
        console.log("获取筛选数据成功，filterData:", this.filterData);
      } catch (error) {
        console.error("获取筛选数据失败:", error);
      } finally {
        this.loading = false;
      }
    },

    /* ---- 排序 ---- */
    handleSort(order) {
      const arr = [...this.filterData];
      arr.sort((a, b) => {
        const valA = parseFloat(a[this.prop]) || a;
        const valB = parseFloat(b[this.prop]) || b;
        return order === "asc" ? valA - valB : valB - valA;
      });
      this.filterData = arr;
    },

    /* ---- 反选 ---- */
    handleInvertSelection() {
      if (this.filteredList.length > 200) {
        this.$message.warning("反选数据量太大，请先筛选或手动选择!");
        return;
      }
      const all = this.filteredList;
      const selected = this.currentRows;
      const inverted = all.filter(
        (row) => !selected.some((s) => s.column === row.column)
      );
      this.toggleSelection(inverted);
      this.currentRows = inverted;
    },

    /* ---- 多选处理 ---- */
    handleSelectionChange(selection) {
      // 获取当前页的所有column值
      const currentPageColumns = new Set(
        this.filteredList.map((item) => item.column)
      );

      // 移除currentRows中当前页已存在的选中数据（避免重复）
      this.currentRows = this.currentRows.filter(
        (item) => !currentPageColumns.has(item.column)
      );

      // 添加当前页新选中的数据
      this.currentRows.push(...selection);

      // 更新allSelectedColumns集合
      this.allSelectedColumns.clear();
      this.currentRows.forEach((item) =>
        this.allSelectedColumns.add(item.column)
      );
    },
    handleClickRow(row) {
      const checked = this.allSelectedColumns.has(row.column);

      if (checked) {
        // 取消选中
        this.allSelectedColumns.delete(row.column);
        this.currentRows = this.currentRows.filter(
          (item) => item.column !== row.column
        );
        this.$refs.multipleTable.toggleRowSelection(row, false);
      } else {
        // 添加选中
        this.allSelectedColumns.add(row.column);
        this.currentRows.push(row);
        this.$refs.multipleTable.toggleRowSelection(row, true);
      }
    },
    toggleSelection(rows) {
      const table = this.$refs.multipleTable;
      table.clearSelection();
      this.$nextTick(() =>
        rows.forEach((r) => table.toggleRowSelection(r, true))
      );
    },
    restoreSelections() {
      this.$nextTick(() => {
        const table = this.$refs.multipleTable;
        if (!table) return;
        table.clearSelection();

        // 根据allSelectedColumns恢复当前页的选中状态
        this.filteredList.forEach((item) => {
          if (this.allSelectedColumns.has(item.column)) {
            table.toggleRowSelection(item, true);
          }
        });
      });
    },

    /* ---- 日期 ---- */
    dateChange(val) {
      this.currentRows = [
        {
          column: this.formatDateTimeRange(val),
          isRange: true,
          rawData: { [this.prop]: this.formatDateTimeRange(val) },
        },
      ];
    },

    /* ---- 按钮 ---- */
    handleClose() {
      // this.$nextTick(() => {
      //   // 把焦点还给搜索图标，防止 aria-hidden 作用在聚焦元素
      //   this.$el.closest("th").querySelector(".svg-icon")?.focus();
      // });
    },
    filterConfirm() {
      console.log("调用了筛选方法");
      // 先移除焦点
      this.removeFocusSafely();

      // 触发事件
      this.$emit("select-data", this.currentRows, this.prop, this.htmlType);

      // 关闭弹窗
      this.$refs.popover.doClose();

      // 延迟处理焦点
      this.$nextTick(() => {
        this.focusTriggerElement();
      });
    },
    filterCancel(flag) {
      console.log("调用了重置方法");
      this.searchKey = "";
      this.dateRangeValue = "";
      this.currentRows = [];
      // 先移除焦点
      this.removeFocusSafely();

      this.$emit("select-data", [], this.prop, this.htmlType);
      this.$refs.popover.doClose();
      this.isFirstLoad = true;

      // 延迟处理焦点
      this.$nextTick(() => {
        this.focusTriggerElement();
      });
    },
    // 安全移除焦点的方法
    removeFocusSafely() {
      const activeElement = document.activeElement;
      if (activeElement && activeElement.blur) {
        activeElement.blur();
      }
    },

    // 将焦点移回触发元素
    focusTriggerElement() {
      setTimeout(() => {
        // 找到弹窗的触发元素（通常是表头的筛选图标）
        const trigger =
          this.$el
            .closest("th")
            ?.querySelector(".el-table__column-filter-trigger") ||
          this.$el.closest("th")?.querySelector(".svg-icon") ||
          this.$el.closest("th")?.querySelector("i");

        if (trigger && trigger.focus) {
          trigger.focus();
        }
      }, 100); // 给弹窗关闭动画一点时间
    },
    handleFilterSearch() {
      this.fetchFilterListInQueryManage();
    },

    /* ---- 分页处理 ---- */
    handleSizeChange(val) {
      this.pageSize = val;
      this.pageNo = 1; // 切换每页条数时重置页码
      this.restoreSelections(); // 重新恢复选中状态
    },

    handleCurrentChange(val) {
      this.pageNo = val;
      this.restoreSelections(); // 重新恢复选中状态
    },
  },
};
</script>

<style scoped>
.demonstration {
  color: #409eff;
}
.mb5 {
  margin-bottom: 5px;
}
.mt10 {
  margin-top: 10px;
}
.text-right {
  text-align: right;
}
.flex {
  display: flex;
}
.flex-1 {
  flex: 1;
}
.ml-3 {
  margin-left: 12px;
}
.mr-5px {
  margin-right: 5px;
}
</style>
