<template>
  <div class="y-table-container">
    <div class="y-table-name">
      <div class="title">{{ title }}</div>
    </div>
    <div class="y-table-filter">
      <div
        v-for="(item, index) in filterConfig"
        :key="index"
        class="filter-item"
      >
        <span>{{ item.label }}：</span>
        <!-- 选择框 -->
        <a-select
          v-if="item.type === 'select'"
          class="input-item"
          placeholder="请选择"
          :options="item.options"
          allow-clear
          show-search
          :filter-option="filterOption"
          v-model:value="filterData[item.name]"
          @change="toFilt"
        ></a-select>
        <!-- 输入框 -->
        <a-input
          v-else-if="item.type === 'text'"
          class="input-item"
          placeholder="请输入"
          allow-clear
          v-model:value="filterData[item.name]"
          @change="toFilt"
        />
        <!-- 日期范围 -->
        <a-range-picker
          v-else-if="item.type === 'time'"
          class="date-item"
          v-model:value="filterData[item.name]"
          @change="toFilt"
        />
        <!-- 带时分的日期范围 -->
        <a-range-picker
          v-else-if="item.type === 'date_time'"
          class="date-time-item"
          v-model:value="filterData[item.name]"
          show-time
          format="YYYY-MM-DD HH:mm"
          @change="toFilt"
        />
        <!-- 数值区间 -->
        <div
          v-else-if="item.type === 'number_range' && filterData[item.name]"
          class="number_range_box"
        >
          <a-input-number
            placeholder="最小值"
            style="width: 140px"
            v-model:value="filterData[item.name].min"
            @change="toFilt"
          />
          <span class="divider"> - </span>
          <a-input-number
            placeholder="最大值"
            style="width: 140px"
            v-model:value="filterData[item.name].max"
            @change="toFilt"
          />
        </div>
      </div>
      <div v-if="isExport" class="filter-item">
        <a
          :href="`${YCODE_BASEURL}/api/v1/preview/export?preview_id=${previewId}&filter=${JSON.stringify(getFilter())}`"
          target="_blank"
          ><a-button type="primary"><CloudDownloadOutlined />导出</a-button></a
        >
      </div>
    </div>
    <div class="y-table-content">
      <a-table
        :columns="columnConfig"
        :data-source="dataList"
        :pagination="false"
        :scroll="{ x: 1000, y: `calc(100vh - 280px)` }"
        size="small"
        bordered
      >
        <template #bodyCell="{ column, record }">
          <a-image
            v-if="column.show_type === 'img'"
            :src="record[column.dataIndex]"
            :width="160"
          />
          <a
            v-else-if="column.show_type === 'link'"
            target="_blank"
            :href="record[column.dataIndex]"
            >{{ record[column.dataIndex] }}</a
          >
          <div
            v-else-if="column.show_type === 'richText'"
            v-html="record[column.dataIndex]"
          ></div>
          <template v-else>{{ record[column.dataIndex] }}</template>
        </template>
      </a-table>
      <a-pagination
        v-model:current="pageState.page"
        :total="total"
        :page-size="pageState.perPage"
        :hide-on-single-page="false"
        :show-size-changer="false"
        size="small"
        class="pagination-box"
        :show-total="total => `共 ${total} 条`"
        @change="pageChange"
      />
    </div>
  </div>
</template>

<script setup>
import { reactive, ref, watch } from "vue";
import { useDebounceFn } from "@vueuse/core";
import { cloneDeep } from "lodash-es";
import { CloudDownloadOutlined } from "@ant-design/icons-vue";

const YCODE_BASEURL = import.meta.env.VITE_YCODE_BASEURL

const props = defineProps({
  previewId: {
    type: Number,
    default: null,
  },
  filterConfig: {
    type: Array,
    default: () => [],
  },
  columnConfig: {
    type: Array,
    default: () => [],
  },
  dataList: {
    type: Array,
    default: () => [],
  },
  total: {
    type: Number,
    default: 0,
  },
  title: {
    type: String,
    default: "",
  },
  isExport: {
    type: Number,
    default: 0,
  },
});
const emit = defineEmits(["toFilt"]);

const filterData = ref({});

const pageState = reactive({
  page: 1,
  perPage: 20,
});

watch(() => props.filterConfig, (newVal) => {
  newVal.forEach((item) => {
    // 给数值区间类型赋初始值，防止报错
    if (item.type === 'number_range' && !filterData.value[item.name]) {
      filterData.value[item.name] = {
        min: undefined,
        max: undefined,
      };
    }
  });
}, { immediate: true });

const filterOption = (input, option) => {
  return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
};

const getFilter = () => {
  const cloneFilter = cloneDeep(props.filterConfig);
  const filter = cloneFilter
    .filter((item) => {
      return filterData.value[item.name] !== undefined && filterData.value[item.name] !== null;
    })
    .map((item) => {
      if (item.type === 'time' && filterData.value[item.name]) {
        // 日期类型的参数
        return {
          name: item.name,
          type: item.type,
          start_time: filterData.value[item.name][0].format('YYYY-MM-DD'),
          end_time: filterData.value[item.name][1].format('YYYY-MM-DD'),
        };
      } else if (item.type === 'date_time' && filterData.value[item.name]) {
        // 带时分的日期类型参数
        return {
          name: item.name,
          type: item.type,
          start_time: filterData.value[item.name][0].format('YYYY-MM-DD HH:mm') + ':00',
          end_time: filterData.value[item.name][1].format('YYYY-MM-DD HH:mm') + ':59',
        };
      } else if (item.type === 'number_range') {
        // 数值区间
        return {
          name: item.name,
          type: item.type,
          min: filterData.value[item.name].min ? String(filterData.value[item.name].min) : '',
          max: filterData.value[item.name].max ? String(filterData.value[item.name].max) : '',
        };
      } else {
        return {
          name: item.name,
          type: item.type,
          value: filterData.value[item.name],
        };
      }
    });
  return filter
};

const getData = () => {
  emit("toFilt", {
    filter: getFilter(),
    page: pageState.page,
    perPage: pageState.perPage,
  });
};

const toFilt = useDebounceFn(() => {
  pageState.page = 1
  getData();
}, 500);

const pageChange = () => {
  getData();
};
</script>

<style lang="less" scoped>
.y-table-name {
  margin-bottom: 10px;
  display: none;
  .title {
    font-size: 18px;
    font-weight: bold;
  }
}
.y-table-filter {
  display: flex;
  flex-wrap: wrap;
}
.filter-item {
  margin-right: 10px;
  margin-bottom: 6px;
  font-size: 14px;
}
.input-item {
  width: 180px;
}
.date-item {
  width: 240px;
}
.date-time-item {
  width: 300px;
}
.number_range_box {
  display: inline-flex;
  align-items: center;

  .divider {
    margin: 0 4px;
  }
}
.y-table-content {
  margin-top: 10px;
}
.pagination-box {
  text-align: center;
  margin-top: 10px;
}
</style>
