
import { RagReqOptions, RagReqResponse, RagReqError, RagSessionData, RagMessageData, AgentSessionListOptions } from './interface.uts';

// token/session 持久化 key
const RAG_ACCESS_TOKEN_KEY = 'ragreq_access_token';
const RAG_SESSION_ID_KEY = 'ragreq_session_id';

let _accessToken : string | null = null;
let _sessionId : string | null = null;

export type RagReqConfig {
	baseUrl : string;
	apiKey ?: string;
}

export class RagReq {
	private baseUrl : string;

	constructor(config : RagReqConfig) {
		this.baseUrl = config.baseUrl.replace(/\/$/, '');
		if ((config.apiKey ?? '') !== '') {
			RagReq.setToken(config.apiKey!);
		}
	}

	// 设置 token
	static setToken(token : string) {
		_accessToken = token;
		uni.setStorageSync(RAG_ACCESS_TOKEN_KEY, token);
	}
	static getToken() : string | null {
		if (_accessToken != null) return _accessToken;
		const t = uni.getStorageSync(RAG_ACCESS_TOKEN_KEY) as string | null;
		_accessToken = t;
		return t;
	}
	static clearToken() {
		_accessToken = null;
		uni.removeStorageSync(RAG_ACCESS_TOKEN_KEY);
	}

	// sessionId 管理
	static setSessionId(sessionId : string) {
		_sessionId = sessionId;
		uni.setStorageSync(RAG_SESSION_ID_KEY, sessionId);
	}
	static getSessionId() : string | null {
		if (_sessionId != null) return _sessionId;
		const t = uni.getStorageSync(RAG_SESSION_ID_KEY) as string | null;
		_sessionId = t;
		return t;
	}
	static clearSessionId() {
		_sessionId = null;
		uni.removeStorageSync(RAG_SESSION_ID_KEY);
	}

	// 通用 request
	async request(options : RagReqOptions) : Promise<RagReqResponse<any>> {
		let headers = options.headers ?? ({} as UTSJSONObject);
		const token = RagReq.getToken();
		if ((token ?? '') !== '') {
			headers = Object.assign({}, headers, { Authorization: `Bearer ${token}` }) as UTSJSONObject;
		}
		const url = options.url.startsWith('http') ? options.url : this.baseUrl + options.url;
		return new Promise<RagReqResponse<any>>((resolve, reject) => {
			uni.request({
				url,
				method: options.method ?? 'POST',
				data: options.data,
				header: headers,
				timeout: options.timeout ?? 10000,
			   success: (res) => {
				   let data : UTSJSONObject | Array<UTSJSONObject> | null;
				   if (typeof res.data == 'string') {
					   try { data = JSON.parse(res.data as string) as UTSJSONObject; } catch { data = null; }
				   } else if (Array.isArray(res.data)) {
					   data = res.data as UTSJSONObject[];
				   } else {
					   data = res.data as UTSJSONObject | null;
				   }
				   resolve({
					   status: res.statusCode,
					   data: data ?? {},
					   headers: res.header as UTSJSONObject,
					   error: null
				   } as RagReqResponse<any>);
			   },
			   fail: (err) => {
				   resolve({
					   status: err.errCode,
					   data: null as any,
					   headers: {} as UTSJSONObject,
					   error: err.errMsg ?? 'request fail'
				   } as RagReqResponse<any>);
			   }
			});
		});
	}

	// 发送消息到 RAG
	async sendMessage(message : string, sessionId ?: string) : Promise<RagReqResponse<RagMessageData>> {
		const sid = sessionId ?? RagReq.getSessionId();
		const reqOpt : RagReqOptions = {
			url: '/api/session/chat',
			method: 'POST',
			data: { message, session_id: sid } as UTSJSONObject
		};
		const res = await this.request(reqOpt);
		return res;
	}

	// 获取指定 agent 的会话列表（新接口）
	async getAgentSessionList(
		agentId: string,
		options?: AgentSessionListOptions
	): Promise<RagReqResponse<any>> {
		let url = `/api/v1/agents/${agentId}/sessions`;
		const params: string[] = [];
		if (options!=null) {
			if (options.page !== null) params.push(`page=${options.page}`);
			if (options?.page_size !== null) params.push(`page_size=${options?.page_size}`);
			if (options?.orderby!=null) params.push(`orderby=${encodeURIComponent(options?.orderby??'')}`);
			if (options.desc !== null) params.push(`desc=${options.desc!=null ? 'true' : 'false'}`);
			if (options.id!='') params.push(`id=${encodeURIComponent(options?.id??'')}`);
			if (options.user_id!='') params.push(`user_id=${encodeURIComponent(options?.user_id??'')}`);
			if (options.dsl!=null) params.push(`dsl=${encodeURIComponent(options?.dsl??'')}`);
		}
		if (params.length > 0) {
			url += '?' + params.join('&');
		}
		const headers = {} as UTSJSONObject;
		// Authorization header will be auto-added in request()
		return await this.request({
			url,
			method: 'GET',
			headers
		});
	}

	// 获取历史消息
	async getHistory(sessionId ?: string) : Promise<RagReqResponse<Array<RagMessageData>>> {
		const sid = sessionId ?? RagReq.getSessionId();
		const reqOpt : RagReqOptions = {
			url: `/api/session/history?session_id=${sid}`,
			method: 'GET'
		};
		const res = await this.request(reqOpt);
		return res;
	}

	// 新建会话
	async createSession() : Promise<RagReqResponse<RagSessionData>> {
		const reqOpt : RagReqOptions = {
			url: '/api/session/create',
			method: 'POST',
			data: {} as UTSJSONObject
		};
		const res = await this.request(reqOpt);
		return res;
	}

	// 创建会话（支持 json 或 form-data）
	async createAgentSession(
		agentId : string,
		params ?: UTSJSONObject,
		userId ?: string,
		isFormData : boolean = false
	) : Promise<RagReqResponse<any>> {
	   let url = `/api/v1/agents/${agentId}/sessions`;
	   if ((userId ?? '') !== '') url += `?user_id=${encodeURIComponent(userId!)}`;
		let headers = {} as UTSJSONObject;
		let data : any = params ?? {};
		if (isFormData) {
			headers['Content-Type'] = 'multipart/form-data';
		} else {
			headers['Content-Type'] = 'application/json';
		}
		return await this.request({
			url,
			method: 'POST',
			headers,
			data
		});
	}

	// 与 agent 对话
	async converseWithAgent(
		agentId : string,
		body : UTSJSONObject
	) : Promise<RagReqResponse<UTSJSONObject>> {
		const url = `/api/v1/agents/${agentId}/completions`;
		const headers = { 'Content-Type': 'application/json' } as UTSJSONObject;
		return await this.request({
			url,
			method: 'POST',
			headers,
			data: body
		});
	}
	// 删除 agent 的会话（批量）
	async deleteAgentSessions(
		agentId: string,
		ids: string[]
	): Promise<RagReqResponse<any>> {
		const url = `/api/v1/agents/${agentId}/sessions`;
		const headers = { 'Content-Type': 'application/json' } as UTSJSONObject;
		const data = { ids } as UTSJSONObject;
		return await this.request({
			url,
			method: 'DELETE',
			headers,
			data
		});
	}
}

export default RagReq;