<template>
	<view class="yTable">
		<kevyloading v-if="loading" type="bsm-loader" color="#618af8" transparent></kevyloading>

		<wd-table :data="list" :border="true">
			<slot></slot>
		</wd-table>

		<wd-pagination v-model="query.page" :total="total" :page-size="query.pageSize" @change="handleChange" show-icon
			show-message />
	</view>
</template>

<script setup>
import { ref } from 'vue';
import kevyloading from "@/components/kevy-loading/kevy-loading";

/**
 * @typedef {Object} Props
 * @property {Function} apiObj - The API function to fetch data.
 * @property {Object} params - Additional parameters for the API call.
 */

/**
 * @typedef {Object} Query
 * @property {number} page - The current page.
 * @property {number} pageSize - The page size.
 */

/** @type {Props} */
const props = defineProps({
	apiObj: {
		type: Function,
		default: () => (() => { })
	},
	params: {
		type: Object,
		default: () => ({})
	}
});

/** @type {Query} */
const query = ref({
	page: 1,
	pageSize: 20
});

/** @type {Ref<boolean>} */
const loading = ref(false);

/** @type {Ref<number>} */
const total = ref(0);

/** @type {Ref<Array>} */
const list = ref([]);

/**
 * Function to fetch data from the API.
 * 
 * @returns {Promise<void>} - Asynchronous function.
 */
const getData = async () => {
	loading.value = true;
	const res = await props.apiObj({
		...query.value,
		...props.params
	});

	query.value.pageSize = res.data.pageSize;
	total.value = res.data.total;
	list.value = res.data.rows;
	loading.value = false;
};

// Initial data fetch
getData();

/**
 * Function to update data with optional parameters.
 * 
 * @param {Object} upParams - Optional parameters for the update.
 * @returns {Promise<void>} - Asynchronous function.
 */
const upData = async (upParams = {}) => {
	loading.value = true;
	query.value.page = 1;
	query.value.pageSize = 20;

	const res = await props.apiObj({
		...query.value,
		...props.params,
		...upParams
	});

	query.value.pageSize = res.data.pageSize;
	total.value = res.data.total;
	list.value = res.data.rows;
	loading.value = false;
};

/**
 * Function to handle change events, updating the page and fetching data.
 * 
 * @param {Object} event - The event object containing the new value.
 */
function handleChange({ value }) {
	query.value.page = value;
	getData();
}

/**
 * Expose the `upData` function to the parent component.
 */
defineExpose({
	upData
});

</script>

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