export interface CustomRequestConfig {
	headers ?: { [key : string] : string };
	params ?: { [key : string] : any };
	data ?: any;
	timeout ?: number;
	// Add other uni.request options as needed
	[key : string] : any; // Allow additional properties
}

export interface RequestConfig extends CustomRequestConfig {
	url : string;
	method ?: "GET" | "POST" | "PUT" | "DELETE";
}

const removeEmptyValue = (obj: any) => {
	console.log("Result:", typeof obj);
	let jsonStr = JSON.stringify(obj);
	if(jsonStr == null){
		return obj;
	}
	let oldObject = JSON.parseObject(JSON.stringify(obj)!);
	if(oldObject == null) {
		return obj;
	}
	//console.log("Old object:", typeof oldObject);
    let newObject = {};
	UTSJSONObject.keys(oldObject).forEach(key => {
		if (oldObject![key] != undefined && oldObject![key] != null) {
			newObject[key] = oldObject![key];
		}
	});
	//console.log("New object:", newObject);
	return newObject;
}

export namespace Ajax {

	type RequestInterceptor = (config : RequestConfig) => RequestConfig | void;
	type ResponseSuccessInterceptor<T = any> = (response : RequestSuccess<T>) => RequestSuccess<T> | void;
	type ResponseFailInterceptor = (error : RequestFail) => any;

	const requestInterceptors : RequestInterceptor[] = [];
	const responseInterceptors : { success : ResponseSuccessInterceptor<any>, fail : ResponseFailInterceptor }[] = [];

	export function addRequestInterceptor(interceptor : RequestInterceptor) {
		console.log("Adding request interceptor:", interceptor);
		requestInterceptors.push(interceptor);
	}

	export function addResponseInterceptor(
		successInterceptor : ResponseSuccessInterceptor<any>,
		failInterceptor ?: ResponseFailInterceptor
	) {
		responseInterceptors.push({
			success: successInterceptor,
			fail: failInterceptor || ((error) => error);
		});
	}

	function request<T = any>(
		options : RequestConfig,
		successCallback ?: (response : T) => void,
		failCallback ?: (error : RequestFail) => void
	) {

		let requestConfig = { ...options } as RequestConfig;
		for (const interceptor of requestInterceptors) {
			//console.log("Request interceptor:", interceptor);
			const result = interceptor(requestConfig);
			if (result) {
				requestConfig = result as RequestConfig;
			}
		}
		requestConfig.data = removeEmptyValue(requestConfig.data);
		return uni.request<T>({
			...requestConfig,
			success: (res : RequestSuccess<T>) => {
				let response = res;
				for (const interceptor of responseInterceptors) {
					if (interceptor.success) {
						const result = interceptor.success(response);
						if (result) {
							response = result;
						}
					}
				}
				successCallback && successCallback(response);
			},
			fail: (err : RequestFail) => {
				let error = { ...err } as RequestFail;
				for (const interceptor of responseInterceptors) {
					if (interceptor.fail) {
						const result = interceptor.fail(error);
						if (result) {
							error = result;
						}
					}
				}
				failCallback && failCallback(error);
			}
		});
	}


	export function get<T = any>(
		url : string,
		data ?: any,
		options ?: CustomRequestConfig,
		successCallback ?: (response : T) => void,
		failCallback ?: (error : RequestFail) => void
	) {
		return request<T>(
			{
				url,
				data,
				method: "GET",
				...options
			},
			successCallback,
			failCallback
		);
	}

	export function post<T = any>(
		url : string,
		data ?: any,
		options ?: CustomRequestConfig,
		successCallback ?: (response : T) => void,
		failCallback ?: (error : RequestFail) => void
	) {
		return request<T>(
			{
				url,
				data,
				method: "POST",
				...options
			},
			successCallback,
			failCallback
		);
	}

	export function put<T = any>(
		url : string,
		data ?: any,
		options ?: CustomRequestConfig,
		successCallback ?: (response : T) => void,
		failCallback ?: (error : RequestFail) => void
	) {
		return request<T>(
			{
				url,
				data,
				method: "PUT",
				...options
			},
			successCallback,
			failCallback
		);
	}

	export function del<T = any>(
		url : string,
		data ?: any,
		options ?: CustomRequestConfig,
		successCallback ?: (response : T) => void,
		failCallback ?: (error : RequestFail) => void
	) {
		return request<T>(
			{
				url,
				data,
				method: "DELETE",
				...options
			},
			successCallback,
			failCallback
		);
	}
}