<template>
  <el-popover
    ref="popover"
    placement="bottom"
    width="340"
    trigger="click"
    @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"
        style="width: 95%"
        @change="dateChange"
      />
    </div>

    <!-- 多选列表 -->
    <div v-else class="mb5" style="max-height: 350px; overflow: auto">
      <el-table
        ref="multipleTable"
        :data="filteredList"
        size="mini"
        height="350"
        @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>

    <!-- 按钮 -->
    <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: [],
      filterData: [],
      loading: false,
      isFirstLoad: true,
    };
  },
  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() {
      if (!this.searchKey.trim()) return this.originalList;
      return this.originalList.filter((item) =>
        String(item.column).toLowerCase().includes(this.searchKey.toLowerCase())
      );
    },
  },
  watch: {
    isClear(val) {
      if (val) this.filterCancel(true);
    },
  },
  methods: {
    /* ---- 生命周期 ---- */
    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) {
      this.currentRows = selection;
    },
    handleClickRow(row) {
      const checked = this.currentRows.some((s) => s.column === row.column);
      this.$refs.multipleTable.toggleRowSelection(row, !checked);
    },
    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();
        this.currentRows.forEach((r) => {
          const target = this.filteredList.find((i) => i.column === r.column);
          if (target) table.toggleRowSelection(target, true);
        });
      });
    },

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

    /* ---- 按钮 ---- */
    filterConfirm() {
      this.$emit("select-data", this.currentRows, this.prop, this.htmlType);
      this.$refs.popover.doClose();
    },
    filterCancel(flag) {
      this.searchKey = "";
      this.dateRangeValue = "";
      this.currentRows = [];
      if (!flag) {
        this.$emit("select-data", [], this.prop, this.htmlType);
        this.$refs.popover.doClose();
        this.isFirstLoad = true;
      }
    },
    handleFilterSearch() {
      this.fetchFilterListInQueryManage();
    },
  },
};
</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>
