<template>
  <div>
    <a-card v-if="$slots.default" :bordered="false"
      :bodyStyle="{ padding: '20px 16px 0 16px', marginBottom: '16px', background: 'var(--background-color) !important', borderRadius: '4px' }">
      <slot></slot>
    </a-card>
    <a-card :title="title || $store.menus.title" :bordered="false" :bodyStyle="{ padding: '16px 16px 0px 16px' }">
      <template #extra>
        <a-space :size="16">
          <a-button type="primary" v-for="(item, i) in primaryButtons" :key="item.title"
            @click="handle(item.tag || item.click, item.title)">
            <paas-icon :icon="item.icon" />
            {{ item.title }}
          </a-button>
          <!-- 刷新数据按钮 -->
          <a-tooltip title="刷新数据">
            <a-button shape="circle" @click="refreshData">
              <sync-outlined />
            </a-button>
          </a-tooltip>
          <!-- 密度控制下拉菜单 -->
          <a-dropdown>
            <template #overlay>
              <a-menu @click="handleDensityChange">
                <a-menu-item key="small">
                  <a-radio :checked="currentSize === 'small'">紧密</a-radio>
                </a-menu-item>
                <a-menu-item key="middle">
                  <a-radio :checked="currentSize === 'middle'">默认</a-radio>
                </a-menu-item>
                <a-menu-item key="large">
                  <a-radio :checked="currentSize === 'large'">宽松</a-radio>
                </a-menu-item>
              </a-menu>
            </template>
            <a-tooltip title="表格密度">
              <a-button shape="circle">
                <column-height-outlined />
              </a-button>
            </a-tooltip>
          </a-dropdown>
          <!-- 分页锁定下拉菜单 -->
          <a-dropdown>
            <template #overlay>
              <a-menu @click="handlePaginationLockChange">
                <a-menu-item key="locked">
                  <a-radio :checked="paginationLocked">锁定分页</a-radio>
                </a-menu-item>
                <a-menu-item key="unlocked">
                  <a-radio :checked="!paginationLocked">解锁分页</a-radio>
                </a-menu-item>
              </a-menu>
            </template>
            <a-tooltip title="分页锁定">
              <a-button shape="circle">
                <lock-outlined v-if="paginationLocked" />
                <unlock-outlined v-else />
              </a-button>
            </a-tooltip>
          </a-dropdown>
          <!-- 列设置下拉菜单 -->
          <a-dropdown :trigger="['click']">
            <template #overlay>
              <a-menu>
                <a-menu-item v-for="(col, index) in originColumns" :key="'show_' + index">
                  <a-checkbox
                    v-if="col && (col.title || (col.slots && col.slots.title)) && col.dataIndex !== 'tableIndex'"
                    v-model:checked="col.visible" @change="handleColumnVisibleChange">
                    {{ col.title || (col.slots && col.slots.title) || (col.slots && col.key) || `列${index + 1}` }}
                  </a-checkbox>
                </a-menu-item>
              </a-menu>
            </template>
            <a-tooltip title="列设置">
              <a-button shape="circle">
                <setting-outlined />
              </a-button>
            </a-tooltip>
          </a-dropdown>
        </a-space>
      </template>
      <a-table :size="currentSize" ref="table" :data-source="dataList" :columns="filteredColumns"
        @change="pageClick" :pagination="noPage ? false : page" :row-key="id" :scroll="scroll" :bordered="border"
        :row-selection="checkbox ? rowSelection : undefined" :customRow="customRow" :locale="{ emptyText: emptyText }"
        :class="{ 'striped-table': stripe }" v-bind="$attrs">
        <!-- 操作列和序号列 -->
        <template #bodyCell="{ column, record, index }">
          <template v-if="column.key === 'action'">
            <a v-for="(item, i) in actionButtons" :key="item.tag || item.click"
              @click="handle(item.tag || item.click, item.title, record)">
              <a-divider type="vertical" style="padding:0;margin:0 6px" v-if="i > 0" />
              {{ item.title }}
            </a>
          </template>
          <template v-else-if="column.dataIndex === 'tableIndex'">
            {{ index + 1 + (page.current - 1) * page.pageSize }}
          </template>
        </template>
      </a-table>
    </a-card>
  </div>
</template>

<script>
import { ColumnHeightOutlined, LockOutlined, SettingOutlined, SyncOutlined, UnlockOutlined } from '@ant-design/icons-vue';
import { message, Modal } from 'ant-design-vue';

export default {
  name: "PaasPageTable",
  inheritAttrs: false, // 禁用自动继承，手动控制透传
  components: {
    SettingOutlined,
    SyncOutlined,
    ColumnHeightOutlined,
    LockOutlined,
    UnlockOutlined
  },
  inject: {
    parentMethods: {
      from: 'parentMethods',
      default: () => ({}),
    },
  },
  props: {
    initLoad: { type: Boolean, default: true },
    size: { default: "middle" },
    showButton: { default: 1 },
    checkbox: { default: false },
    height: { type: [Number, String], default: 0 }, // 表格高度
    border: { type: Boolean, default: false }, // 是否显示边框
    stripe: { type: Boolean, default: false }, // 是否斑马纹
    params: {},
    title: { type: String, default: '' },
    columns: { type: Array, default: () => [] },
    id: { default: "id" },
    getDataList: { type: Function, default: null },
    path: String,
    module: String,
    noPage: { default: false },
    scroll: { type: Object, default: () => ({ x: 300 }) },
    emptyText: { type: String, default: '暂无数据' }, // 空状态文案
  },
  data() {
    return {
      url: '',
      loading: false,
      dataList: [],
      selectedRows: [],
      selectedRowKeys: [],
      page: {
        current: 1,
        pageSize: 10,
        total: 0,
        showQuickJumper: true,
        style: { marginTop: '10px' },
        pageSizeOptions: ["10", "20", "50", "100", "200", "500"],
      },
      originColumns: [], // 保存原始列配置
      currentSize: this.getTableSizeFromStore(), // 从store获取表格尺寸设置
      paginationLocked: this.getPaginationLockFromStore(), // 从store获取分页锁定状态
    };
  },
  computed: {
    queryData() {
      return this.$store.queryData;
    },
    // 根据可见性过滤列，并添加序号列
    filteredColumns() {
      // 序号列定义
      const indexColumn = {
        title: '序号',
        dataIndex: 'tableIndex',
        key: 'tableIndex',
        width: 55,
        fixed: 'left'
      };

      // 过滤出可见的列
      const visibleColumns = this.originColumns.filter(col => col && col.visible !== false);

      // 检查是否已经有序号列，如果没有则添加
      const hasIndexColumn = visibleColumns.some(col => col.dataIndex === 'tableIndex');
      if (!hasIndexColumn) {
        return [indexColumn, ...visibleColumns];
      }
      return visibleColumns;
    },
    current() {
      return this.path || this.$store.menus.current;
    },
    menuData() {
      return this.$store.menus.data;
    },
    buttons() {
      return this.$store.buttons;
    },
    primaryButtons() {
      return this.buttons.filter(v => v.state == 1);
    },
    actionButtons() {
      return this.buttons.filter(v => v.state != 1);
    },
    rowSelection() {
      return {
        selectedRowKeys: this.selectedRowKeys,
        onChange: this.handleRowSelectionChange,
        type: this.checkbox ? 'checkbox' : 'radio',
      };
    },
    tableBodyStyle() {
      if (!this.height || this.height === 0) return {};
      const height = typeof this.height === 'number' ? `${this.height}px` : this.height;
      return { height, overflow: 'auto' };
    },
  },
  mounted() {
    this.$store.setSee(false);
    this.url = this.module ? `${this.module}/page` : `${this.$route.path}/page`;
    this.$bus.on("loadData", this.refreshData);
    // 初始化原始列数据
    this.initializeOriginColumns();
    if (this.initLoad) {
      this.loadData();
    }
  },
  beforeUnmount() {
    this.$bus.off("loadData", this.refreshData);
  },
  methods: {
    getTableSizeFromStore() {
      // 从 store 获取表格密度设置，如果没有则使用默认值
      const savedSize = localStorage.getItem('tableSize') || this.size || 'middle';
      return savedSize;
    },
    saveTableSizeToStore(size) {
      // 将表格密度设置保存到 store
      localStorage.setItem('tableSize', size);
    },
    getPaginationLockFromStore() {
      // 从 store 获取分页锁定状态，如果没有则使用默认值
      const savedLock = localStorage.getItem('paginationLocked');
      return savedLock != 'false';
    },
    savePaginationLockToStore(locked) {
      // 将分页锁定状态保存到 store
      localStorage.setItem('paginationLocked', locked);
    },
    initializeOriginColumns() {
      if (!this.columns || !Array.isArray(this.columns)) {
        this.originColumns = [];
        return;
      }

      // 初始化原始列数据，为每列添加可见性属性
      this.originColumns = this.columns.map((col, index) => {
        if (!col) {
          return {
            visible: false,
          };
        }

        // 检查列是否有有效标题或插槽标题
        const hasValidTitle = col.title || (col.slots && col.slots.title);
        // 检查列是否有有效标识符
        const hasValidIdentifier = col.dataIndex || col.key || col.title;

        return {
          ...col,
          visible: Boolean((col.visible !== false) && hasValidTitle && hasValidIdentifier), // 确保是布尔值
        };
      });
    },
    refreshData() {
      this.loadData();
    },
    handleRowSelectionChange(keys, rows) {
      this.selectedRowKeys = keys;
      this.selectedRows = rows;
    },
    handleColumnVisibleChange() {
      // 不使用 $forceUpdate() 避免潜在的 DOM 问题，而是通过改变响应式数据来触发更新
      // 由于 filteredColumns 是计算属性，修改 originColumns 中的 visible 属性会自动触发更新
      this.originColumns = this.originColumns.map(col => {
        if (col) {
          return {
            ...col,
            visible: Boolean(col.visible) // 确保 visible 属性是布尔值
          };
        }
        return col;
      });
    },
    handleDensityChange({ key }) {
      this.currentSize = key;
      this.saveTableSizeToStore(key);
    },
    handlePaginationLockChange({ key }) {
      const locked = key === 'locked';
      this.paginationLocked = locked;
      this.savePaginationLockToStore(locked);
      if (!locked) {
        // 解锁时重置页码到第一页
        this.page.current = 1;
        this.loadData();
      }
    },
    customRow(record) {
      return {
        onDblclick: () => {
          message.success("选中行新增");
          this.selectedRows = record;
        },
      };
    },
    pageClick(pagination) {
      this.page = pagination;

      // 如果分页锁定，将所有参数（包括分页数据）缓存到queryData中
      if (this.paginationLocked) {
        const allParams = {
          ...this.$store.queryData[this.current],
          ...this.params,
          page: { current: pagination.current, size: pagination.pageSize }
        };
        this.$store.setQueryData(allParams);
      }

      this.loadData();
    },
    loadData() {
      if (this.loading) return;
      this.loading = true;

      if (this.paginationLocked && this.$store.queryData[this.current]?.page) {
        this.page = {
          current: this.$store.queryData[this.current].page.current,
          pageSize: this.$store.queryData[this.current].page.size || 10,
          size: this.$store.queryData[this.current].page.size
        };
      } else {
        this.page.current = 1;
      }
      const query = {
        ...this.$store.queryData[this.current],
        ...this.params,
        page: this.page,
      };

      const fetch = this.getDataList ? this.getDataList(query) : this.$post(this.url, query);
      fetch
        .then(res => this.bindData(res.data?.data))
        .catch(err => {
          console.error('加载数据失败:', err);
        })
        .finally(() => (this.loading = false));
    },
    bindData(data) {
      this.dataList = data?.rows || [];
      this.page.total = data?.total || 0;
    },
    handle(cliName, title, data) {
      if (data) this.selectedRows = data;
      this.$store.setAction(cliName);
      this.$store.setSee(false);
      const func = this.$parent[cliName] || this.parentMethods?.[cliName] || this[cliName];
      if (typeof func === 'function') {
        func(this.selectedRows);
      } else {
        console.error("按钮事件方法未找到：", cliName);
      }
    },
    getColumnId() {
      let data = Array.isArray(this.selectedRows) ? this.selectedRows.at(-1) : this.selectedRows;
      if (!data) {
        if (this.$store.forms.action !== "add") message.warn("请选中任意列表数据");
        return null;
      }
      if (Array.isArray(this.id)) {
        return this.id.map(item => data[item]).join("&");
      }
      return data[this.id];
    },
    add() {
      const id = this.getColumnId();
      this.$store.setSee(false);
      this.$store.setSubTitle("创建");
      this.$router.push(id ? { path: this.current + "/form", query: { id } } : this.current + "/form");
    },
    edit() {
      const id = this.getColumnId();
      if (!id) return;
      this.$store.setSee(false);
      this.$store.setSubTitle("编辑");
      this.$router.push({ path: this.current + "/form", query: { id } });
    },
    see() {
      const id = this.getColumnId();
      if (!id) return;
      this.$store.setSubTitle("查看");
      this.$store.setSee(true);
      this.$router.push({ path: this.current + "/form", query: { id } });
    },
    del() {
      const id = this.getColumnId();
      if (!id) return;
      const url = this.module ? `${this.module}/${id}` : `${this.current}/${id}`;
      Modal.confirm({
        title: "确定删除？",
        okText: "确定",
        cancelText: "取消",
        onOk: () => this.$delete(url).then(res => this.$dyAlert(res.data, false)),
      });
    },
  },
  watch: {
    // 监听外部 columns 的变化，同步更新 originColumns
    columns: {
      handler(newColumns) {
        if (!newColumns || !Array.isArray(newColumns)) return;

        // 保留现有的可见性设置
        const existingVisibility = {};
        if (this.originColumns) {
          this.originColumns.forEach(col => {
            if (col) {
              existingVisibility[col.dataIndex || col.key || col.title] = col.visible;
            }
          });
        }

        this.originColumns = newColumns.map((col, index) => {
          if (!col) return { visible: false };

          const identifier = col.dataIndex || col.key || col.title || ('_' + index.toString());
          return {
            ...col,
            visible: Boolean(existingVisibility[identifier] !== undefined
              ? existingVisibility[identifier]
              : (col.visible !== false)), // 确保是布尔值
          };
        });
      },
      deep: true
    }
  }
};
</script>

<style scoped>
.striped-table :deep(.ant-table-tbody tr:nth-child(odd)) {
  background-color: var(--background-color) !important;
}
</style>