<template>
    <a-table :customRow="customRow" class="ant-table-striped"
        :row-class-name="(_, index) => (index % 2 === 1 ? 'table-striped' : null)" row-key="id" :columns="columns"
        :data-source="data" :loading="loading" :pagination="pagination" :row-selection="rowSelection">
        <template #operation="{ record }">
            <slot :record="record"></slot>
        </template>
    </a-table>
</template>
<script setup>
import { defineProps, defineExpose, ref, computed, onMounted, defineEmits, nextTick } from "vue";
import { useRowsPageNoInit } from "@/api/request";
import { useResetRef } from "@/utils/useCommon";

const props = defineProps({
    type: {
        type: String,
        default: ""
    },
    columns: {
        type: Array,
        default: () => []
    },
    url: {
        type: String,
        default: ""
    },
    pageKey: {
        type: String,
        default: "pageNo"
    },
    params: {
        type: Object,
        default: () => ({})
    },
    init: {
        type: Boolean,
        default: true
    },
    request: {
        type: Function,
        default: useRowsPageNoInit
    }
});
const emit = defineEmits(["update:params", "update:selectedRowKeys", "update:selectedRows"]);
const rowSelectKeys = ref([]);
const selectsData = ref([]);
const params = useResetRef({ [props.pageKey]: 1, pageSize: 10 });
const postParam = computed(() => ({ ...params.value, ...props.params }));

const { data, loading, total, fetch: onFetch } = props.request(props.url, postParam);

const rowSelection = computed(() => (props.type ? {
    type: props.type,
    columnWidth: 20,
    selectedRowKeys: rowSelectKeys.value,
    onChange: onSelectChange,
    preserveSelectedRowKeys: true,
} : null));

const customRow = (record) => ({
    onClick: () => {
        if (props.type === "checkbox") {
            if (rowSelectKeys.value.some(t => t === record.id)) {
                rowSelectKeys.value = rowSelectKeys.value.filter(t => t !== record.id);
                selectsData.value = selectsData.value.filter(t => t.id !== record.id);
            } else {
                rowSelectKeys.value.push(record.id);
                selectsData.value.push(record);
            }
        } else {
            rowSelectKeys.value = [record.id];
            selectsData.value = [record];
        }
        emit("update:selectedRowKeys", [...rowSelectKeys.value]);
        emit("update:selectedRows", [...selectsData.value]);
    }
});

onMounted(() => props.init && nextTick(onFetch));

function onSelectChange(e, l) {
    rowSelectKeys.value = e;
    selectsData.value = l;
    emit("update:selectedRowKeys", e);
    emit("update:selectedRows", l);
}

const pagination = computed(() => ({
    total: total.value,
    showSizeChanger: false,
    current: params.value[props.pageKey],
    pageSize: params.value.pageSize,
    onChange: changePagination,
}));
const changePagination = (e) => {
    params.value[props.pageKey] = e;
    nextTick(onFetch);
};

function reset(v) {
    params.reset();
    v && emit("update:params", { ...v });
    nextTick(onFetch);
}

function resetSelected() {
    rowSelectKeys.value = [];
    selectsData.value = [];
    emit("update:selectedRowKeys", []);
    emit("update:selectedRows", []);
}

function clear(v) {
    rowSelectKeys.value = [];
    selectsData.value = [];
    params.reset();
    v && emit("update:params", { ...v });
    emit("update:selectedRowKeys", []);
    emit("update:selectedRows", []);
}

const toLoading = () => loading.value = true;

function remove(i) {
    rowSelectKeys.value.splice(i, 1);
    selectsData.value.splice(i, 1);
    emit("update:selectedRowKeys", rowSelectKeys.value);
    emit("update:selectedRows", selectsData.value);
}

const fetch = () => nextTick(onFetch);

defineExpose({ fetch, reset, resetSelected, clear, toLoading, remove });

</script>