<template>
  <div class="table-container" ref="tableContainerRef">
    <a-table
      size="small"
      :loading="loading"
      :row-selection="enableRowSelection ? rowSelection : undefined"
      :data-source="tableData"
      :columns="columns"
      :pagination="paginationConfig"
      :scroll="scrollConfig"
      :row-key="rowKey"
      @change="handleTableChange"
    >
      <!-- 透传插槽，支持自定义列内容 -->
      <template v-for="slot in Object.keys($slots)" #[slot]="scope" :key="slot">
        <slot :name="slot" v-bind="scope"></slot>
      </template>
    </a-table>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch, nextTick } from "vue";
import { calcTableScrollY } from "@/utils/index";

// --- Types ---
interface Props {
  columns: any[];
  scrollY?: string | number; // 优先使用传入的固定值
  listUrl: (params: any) => Promise<any>;
  data?: any[];
  enableRowSelection?: boolean;
  rowKey?: string;
  searchParams?: Record<string, any>;
  defaultPageSize?: number;
  getCheckboxProps?: (record: any) => any;
  transformData?: (res: any) => { records: any[]; total: number };
}

const props = withDefaults(defineProps<Props>(), {
  enableRowSelection: false,
  rowKey: "id",
  data: () => [],
  searchParams: () => ({}),
  defaultPageSize: 20,
  getCheckboxProps: undefined,
  transformData: undefined,
  scrollY: undefined,
});

const emit = defineEmits<{
  (e: "data-loaded", params: any, data: any): void;
  (e: "selection-change", selectedRowKeys: string[], selectedRows: any[]): void;
}>();

// --- State ---
const loading = ref(false);
const tableData = ref<any[]>([]);
const total = ref(0);
const page = ref(1);
const size = ref(props.defaultPageSize);
const selectedRowKeys = ref<string[]>([]);
const selectedRows = ref<any[]>([]);
const lastFilter = ref<Record<string, any> | undefined>(undefined);
const tableContainerRef = ref<any>(null);
const tableScrollY = ref<number>(0); // ✅ 新增：存储容器高度

// --- Computed Scroll Config ---
const scrollConfig = computed(() => {
  const config: any = {
    x: "100%",
  };

  // 1. 如果父组件传入了固定的 scrollY，优先使用
  if (props.scrollY !== undefined && props.scrollY !== null) {
    config.y = props.scrollY;
  }
  // 2. 否则，如果检测到容器有高度，则使用容器高度作为滚动高度
  else if (tableScrollY.value > 0) {
    config.y = tableScrollY.value;
  }

  return config;
});

// --- Row Selection ---
const rowSelection = computed(() => ({
  selectedRowKeys: selectedRowKeys.value,
  onChange: (keys: string[], rows: any[]) => {
    selectedRowKeys.value = keys;
    selectedRows.value = rows;
    emit("selection-change", keys, rows);
  },
  getCheckboxProps: props.getCheckboxProps
    ? props.getCheckboxProps
    : (record: any) => ({}),
}));

// --- Pagination Config ---
const paginationConfig = computed(() => ({
  total: total.value,
  current: page.value,
  pageSize: size.value,
  showSizeChanger: true,
  showQuickJumper: true,
  showTotal: (total: number) => `共 ${total} 条`,
  pageSizeOptions: ["20", "50", "100"],
}));

// --- Methods ---
const getList = async (filter?: Record<string, any>) => {
  if (props.data.length > 0) return;
  loading.value = true;
  tableData.value = [];
  total.value = 0;
  if (filter !== undefined) {
    lastFilter.value = filter;
  }
  try {
    const params = {
      ...props.searchParams,
      skip: page.value,
      take: size.value,
      filter: lastFilter.value,
    };

    const res = await props.listUrl(params);

    let finalRecords: any[] = [];
    let finalTotal: number = 0;

    if (props.transformData) {
      const result = props.transformData(res);
      finalRecords = result.records || [];
      finalTotal = result.total || 0;
    } else {
      finalRecords = res?.data?.records || res?.data || [];
      finalTotal = res?.data?.total || res?.total || 0;
    }

    tableData.value = finalRecords;
    total.value = finalTotal;
    emit("data-loaded", params, { records: finalRecords, total: finalTotal });
  } catch (error) {
    console.error("Fetch table data error:", error);
    tableData.value = [];
    total.value = 0;
  } finally {
    loading.value = false;
  }
};

const handleTableChange = (pag: any) => {
  page.value = pag.current;
  size.value = pag.pageSize;
  getList();
};

const reset = () => {
  page.value = 1;
  size.value = props.defaultPageSize;
  selectedRowKeys.value = [];
  selectedRows.value = [];
  getList();
};

const refresh = () => {
  getList();
};

const clearSelection = () => {
  selectedRowKeys.value = [];
  selectedRows.value = [];
};
defineExpose({
  loading,
  getList,
  reset,
  refresh,
  tableData,
  clearSelection,
  getSelected: () => ({
    keys: selectedRowKeys.value,
    rows: selectedRows.value,
  }),
});

watch(
  () => props.searchParams,
  () => {
    page.value = 1;
    getList();
  },
  { deep: true }
);
const observer = new ResizeObserver(() => {
  tableScrollY.value = calcTableScrollY(tableContainerRef.value);
});
onMounted(() => {
  nextTick(() => {
    tableScrollY.value = calcTableScrollY(tableContainerRef.value);
    if (tableContainerRef.value) {
      observer.observe(tableContainerRef.value);
    }
  });
  if (props.data && props.data.length > 0) {
    tableData.value = props.data || [];
  }
});
</script>

<style scoped lang="scss"></style>
