<template>
    <slot name="default" :data="data" :current="localPageCurrent" :total="total" :hasmore="hasmore" :loading="loading" :error="error">
    </slot>
</template>

<script setup lang="uts">	import { ref, watch, onMounted } from 'vue';
	import supa from './aksupainstance.uts';
	import { AkSupaSelectOptions } from './aksupa.uts'
	import { AkReqResponse } from '@/uni_modules/ak-req/index.uts';
	import { toUniError } from '@/utils/utils.uts';
	const props = defineProps({
		collection: {
			type: String,
			default: ''
		},
		filter: {
			type: UTSJSONObject,
			default: () => ({}),
		},
		field: {
			type: String,
			default: '*'
		},
		where: Object,
		orderby: String,
		pageData: {
			type: String,
			default: 'add',
		},
		pageCurrent: {
			type: Number,
			default: 1,
		},
		pageSize: {
			type: Number,
			default: 10,
		},
		/*"exact" | "planned" | "estimated" */
		getcount: { 
			type: String,
			default: '', 
		},
		getone: {
			type: Boolean,
			default: false,
		},
		loadtime: {
			type: String,
			default: 'auto',
		},
		datafunc: Function,
		// RPC 函数名，当使用 RPC 时，collection 参数可以为空
		rpc: {
			type: String,
			default: ''
		},
		// RPC 参数，用于传递给 RPC 函数的额外参数
		params: {
			type: UTSJSONObject,
			default: () => ({})
		}
	});
	const emit = defineEmits<{
		(e : 'process-data', val : UTSJSONObject) : void,
		(e : 'load', val : any[]) : void,
		(e : 'error', val : any) : void
	}>();

	const data = ref<any[]>([]);
	const loading = ref(false);
	const error = ref<any>('');
	const total = ref(0);
	const hasmore = ref(true);

	// Use local refs for pagination state to avoid mutating props directly
	const localPageCurrent = ref(props.pageCurrent);
	const localPageSize = ref(props.pageSize);

	type Pagination = {
		count : Number;
		current : Number;
		size : Number;
	};

	let pagination = { total: 0 };

	let hasMoreData = true;


	/**
	 * Unified data loading method
	 * @param {UTSJSONObject} opt
	 *   opt.append Whether to append data
	 *   opt.clear Whether to clear data
	 *   opt.page Specify page number
	 */	const fetchData = async (opt : UTSJSONObject) => {
		loading.value = true;
		error.value = '';
		
		// 检查是否为 RPC 调用
		const isRpcCall = props.rpc != null && props.rpc.length > 0;
		
		// 只有在非 RPC 调用时才检查 collection
		if (!isRpcCall && (props.collection == null || props.collection.trim() == '')) {
			error.value = 'collection/table 不能为空';
			loading.value = false;
			return;
		}
		
		// RPC 调用时检查 rpc 参数
		if (isRpcCall && (props.rpc == null || props.rpc.trim() == '')) {
			error.value = 'rpc 函数名不能为空';
			loading.value = false;
			return;
		}try {
		// Platform-specific parameter extraction for UTSJSONObject compatibility
		let append: boolean = false
		let clear: boolean = false
		let page: number = localPageCurrent.value
		
		// #ifdef APP-ANDROID || APP-IOS
		// Native platform: use UTSJSONObject methods
		append = opt.getBoolean('append') ?? false
		clear = opt.getBoolean('clear') ?? false
		page = opt.getNumber('page') ?? localPageCurrent.value
		// #endif
		
		// #ifndef APP-ANDROID || APP-IOS
		// Web platform: direct property access
		append = (opt as any)['append'] as boolean ?? false
		clear = (opt as any)['clear'] as boolean ?? false
		page = (opt as any)['page'] as number ?? localPageCurrent.value
		// #endif

		// Update local pagination state
		localPageCurrent.value = page;
		localPageSize.value = props.pageSize;

		// Build query options
		let selectOptions : AkSupaSelectOptions = {
			limit: localPageSize.value,
			order: props.orderby,
			columns: props.field,
		};
		if (props.getcount != null && props.getcount.length > 0) {
			selectOptions['getcount'] = props.getcount;
		}				let result: any;
		if (isRpcCall) {
			// 支持rpc调用 - RPC方法只接受functionName和params两个参数
			// 将filter、params和selectOptions合并为rpcParams
			const rpcParams = new UTSJSONObject();
			
			// 首先添加props.params中的参数
			if (props.params != null) {
				const paramsKeys = UTSJSONObject.keys(props.params);
				for (let i = 0; i < paramsKeys.length; i++) {
					const key = paramsKeys[i];
					
					// #ifdef APP-ANDROID || APP-IOS
					// Native platform: use UTSJSONObject methods
					rpcParams.set(key, props.params.get(key));
					// #endif
					
					// #ifndef APP-ANDROID || APP-IOS
					// Web platform: direct property access
					rpcParams.set(key, (props.params as any)[key]);
					// #endif
				}
			}
			
			// 然后添加filter中的参数（可能会覆盖params中的同名参数）
			if (props.filter != null) {
				// Platform-specific filter handling for UTSJSONObject compatibility
				const filterKeys = UTSJSONObject.keys(props.filter);
				for (let i = 0; i < filterKeys.length; i++) {
					const key = filterKeys[i];
					
					// #ifdef APP-ANDROID || APP-IOS
					// Native platform: use UTSJSONObject methods
					rpcParams.set(key, props.filter.get(key));
					// #endif
					
					// #ifndef APP-ANDROID || APP-IOS
					// Web platform: direct property access
					rpcParams.set(key, (props.filter as any)[key]);
					// #endif
				}
			}
			
			// 添加分页和排序参数
			if (selectOptions.limit != null) rpcParams.set('limit', selectOptions.limit);
			if (selectOptions.order != null) rpcParams.set('order', selectOptions.order);
			if (selectOptions.columns != null) rpcParams.set('columns', selectOptions.columns);
			if (selectOptions.getcount != null) rpcParams.set('getcount', selectOptions.getcount);
			
			result = await supa.rpc(props.rpc, rpcParams);
		} else {
			// Query data
			result = await supa.select_uts(props.collection, props.filter, selectOptions);
		}
		// headers 判空
		let countstring = '';
		let headers:UTSJSONObject = result.headers != null ? result.headers : {};
		if (headers != null) {
			if (typeof headers.getString == 'function') {
				let val = headers.getString('content-range');
				if (val != null && typeof val == 'string') {
					countstring = val;
				}
			} else if (headers['content-range'] != null) {
				// 类型断言为 string，否则转为 string
				countstring = `${headers['content-range']}`;
			}
		}		
		console.log(countstring)		
		if (countstring != null && countstring != '') {
			try {
				const rangeParts = countstring.split('/')
				if (rangeParts.length == 2) {
					// 检查第二部分是否为数字（不是 '*'）
					const totalPart = rangeParts[1].trim()
					if (totalPart !== '*' && !isNaN(parseInt(totalPart))) {
						total.value = parseInt(totalPart)
						console.log('Total count from header:', total.value)
						pagination.total = total.value;
						
						const rangeValues = rangeParts[0].split('-')
						if (rangeValues.length == 2) {
							const end = parseInt(rangeValues[1])
							hasmore.value = end < total.value - 1
							hasMoreData = hasmore.value
						}					} else {
						// 当总数未知时（返回 *），设置默认值
						console.log('Total count unknown (*), using default pagination logic')
						total.value = 0
						pagination.total = 0
						// 根据当前返回的数据量判断是否还有更多数据
						hasmore.value = Array.isArray(result.data) && (result.data as any[]).length >= localPageSize.value
						hasMoreData = hasmore.value
					}
				}
			} catch (e) {
				console.error('Failed to parse content-range header', e)
			}		} else {
			// 当没有 content-range header 时，根据返回的数据量判断分页
			console.log('No content-range header, using data length for pagination')
			total.value = 0
			pagination.total = 0
			// 如果返回的数据量等于页面大小，可能还有更多数据
			hasmore.value = Array.isArray(result.data) && (result.data as any[]).length >= localPageSize.value
			hasMoreData = hasmore.value
		}
		// data 判空
		// UTS 平台下无 UTSArray.fromAny，需兼容
		let items: Array<any> = (Array.isArray(result.data)) ? result.data as Array<any> : Array<any>();		
		try {
            // emit('process-data', items != null ? items : []);
			console.log(result)
			
			// Manually create UTSJSONObject from AkReqResponse for cross-platform compatibility
			const prodata = new UTSJSONObject()
			prodata.set('status', result.status)
			prodata.set('data', result.data)
			prodata.set('headers', result.headers)
			prodata.set('error', result.error)
			prodata.set('total', total.value)
			
			emit('process-data', prodata);
        } catch (e) {
            console.error('emit process-data error', e);
        }

        if (clear) {
            data.value = [];
        }
        if (append) {
            if(Array.isArray(items)) {
                data.value = ([] as any[]).concat(data.value, items);
            }
        } else {
            data.value = items as any[];
        }
        pagination.total = total.value;
        hasMoreData = Array.isArray(items) && items.length == localPageSize.value;    } catch (err : any) {
        // 使用标准化错误处理
        const uniError = toUniError(err, 'An error occurred while fetching data')

        try {
            emit('error', uniError);
        } catch (e) {
            console.error('emit error event error', e);
        }
    } finally {
        loading.value = false;
    }
	};

	// 页码变更统一通过 fetchData
	const handlePageChange = (page : number) => {
		fetchData({ page: page, clear: true, append: false } as UTSJSONObject);
	};
	// 主动加载数据，支持清空
	const loadData = (opt : UTSJSONObject) => {
		console.log('loadData')
		
		// Platform-specific parameter extraction for UTSJSONObject compatibility
		let clear: boolean = true
		
		// #ifdef APP-ANDROID || APP-IOS
		// Native platform: use UTSJSONObject methods
		clear = opt.getBoolean('clear') ?? true
		// #endif
		
		// #ifndef APP-ANDROID || APP-IOS
		// Web platform: direct property access
		clear = (opt as any)['clear'] as boolean ?? true
		// #endif
		
		fetchData({ clear, append: false, page: 1 } as UTSJSONObject);
	};
	
	const refresh = () => {
		console.log('refresh')
		const clear = true;
		fetchData({ clear, append: false, page: 1 } as UTSJSONObject);
	};

	// 加载更多，自动追加
	const loadMore = () => {
		if (hasMoreData) {
			const nextPage = props.pageCurrent + 1;
			fetchData({ append: true, clear: false, page: nextPage } as UTSJSONObject);
		}
	};



	if (props.loadtime === 'auto' || props.loadtime === 'onready') {
		onMounted(() => {
			fetchData({} as UTSJSONObject);
		});
	}


	// watch(data, (newValue : any) => {
	// 	emit('load', newValue);
	// });
	watch(error, (newValue : any) => {
		if (newValue != null) {
			emit('error', newValue);
		}
	});
	// Documented exposed methods for parent components
	/**
	 * Exposed methods:
	 * - loadData(opt?): Load data, optionally clearing previous data
	 * - loadMore(): Load next page and append
	 */
	defineExpose({ loadData,refresh, loadMore,hasmore,total });
</script>

<style scoped>
	/* 添加您的样式 */
</style>