import { request, uploadFile } from '../base'
import type { ResultDomain } from '../../types'
import type {
    TbChat,
    TbChatMessage,
    CreateChatParam,
    ChatPrepareData,
    StopChatParam,
    CommentMessageParam,
    ChatListParam,
    ChatMessageListParam,
    SSECallbacks,
    SSETask,
    SSEMessageData,
    DifyFileInfo
} from '../../types/ai/aiChat'

/* eslint-disable @typescript-eslint/no-explicit-any */
declare const uni: {
    getStorageSync: (key: string) => any
    request: (options: any) => any
}

// API 基础配置
const BASE_URL = 'http://localhost:8180'

/**
 * @description    AI对话相关接口（直接调用ai模块）
 * @filename    aiChat.ts
 * @author    cascade
 * @copyright xyzh
 * @since 2025-12-23
 */
export const aiChatAPI = {
    baseUrl: '/urban-lifeline/ai/chat',

    // ====================== AI对话管理 ======================

    /**
     * 创建对话
     * @param param agentId、userId、title 必传
     */
    createChat(param: CreateChatParam): Promise<ResultDomain<TbChat>> {
        return request<TbChat>({ url: `${this.baseUrl}/conversation`, method: 'POST', data: param })
    },

    /**
     * 更新对话
     * @param chat agentId、userId、title、userType 必传
     */
    updateChat(chat: TbChat): Promise<ResultDomain<TbChat>> {
        return request<TbChat>({ url: `${this.baseUrl}/conversation`, method: 'PUT', data: chat })
    },

    /**
     * 查询对话列表
     * @param param agentId 必传
     */
    getChatList(param: ChatListParam): Promise<ResultDomain<TbChat[]>> {
        return request<TbChat[]>({ url: `${this.baseUrl}/conversations`, method: 'GET', data: param })
    },

    /**
     * 获取对话消息列表
     * @param param agentId、chatId、userId 必传
     */
    getChatMessageList(param: ChatMessageListParam): Promise<ResultDomain<TbChatMessage[]>> {
        return request<TbChatMessage[]>({ url: `${this.baseUrl}/messages`, method: 'POST', data: param })
    },

    /**
     * 准备流式对话会话
     * @param param agentId、chatId、query、userId 必传
     */
    prepareChatMessageSession(param: ChatPrepareData): Promise<ResultDomain<string>> {
        return request<string>({ url: `${this.baseUrl}/stream/prepare`, method: 'POST', data: param })
    },

    /**
     * 流式对话（SSE）- 返回EventSource URL
     */
    getStreamUrl(sessionId: string): string {
        return `${this.baseUrl}/stream?sessionId=${sessionId}`
    },

    /**
     * 建立SSE流式对话连接
     * @param sessionId 会话ID（必传）
     * @param callbacks 回调函数
     * @returns SSETask 可用于中止请求
     */
    streamChat(sessionId: string, callbacks: SSECallbacks): SSETask {
        const url = `${BASE_URL}${this.baseUrl}/stream?sessionId=${sessionId}`
        const token = uni.getStorageSync('token') || ''

        const requestTask = uni.request({
            url: url,
            method: 'GET',
            header: {
                'Accept': 'text/event-stream',
                'Authorization': token ? `Bearer ${token}` : ''
            },
            enableChunked: true,
            success: (res: any) => {
                console.log('SSE请求完成:', res)
                // 处理非200状态码
                if (res.statusCode !== 200) {
                    console.error('SSE请求状态码异常:', res.statusCode)
                    let errorMsg = '抱歉，服务暂时不可用，请稍后重试。'
                    if (res.statusCode === 401) {
                        errorMsg = '登录已过期，请重新登录。'
                    } else if (res.statusCode === 403) {
                        errorMsg = '无权限访问，请联系管理员。'
                    } else if (res.statusCode === 404) {
                        errorMsg = '会话不存在或已过期，请重新发起对话。'
                    } else if (res.statusCode >= 500) {
                        errorMsg = '服务器异常，请稍后重试。'
                    }
                    callbacks.onError?.(errorMsg)
                }
                callbacks.onComplete?.()
            },
            fail: (err: any) => {
                console.error('SSE请求失败:', err)
                callbacks.onError?.('网络连接失败，请稍后重试。')
                callbacks.onComplete?.()
            }
        })

        // 监听分块数据
        requestTask.onChunkReceived((res: any) => {
            try {
                const decoder = new TextDecoder('utf-8')
                const text = decoder.decode(new Uint8Array(res.data))

                const lines = text.split('\n')
                for (const line of lines) {
                    if (line.startsWith('data:')) {
                        const dataStr = line.substring(5).trim()
                        if (dataStr && dataStr !== '[DONE]') {
                            try {
                                const data: SSEMessageData = JSON.parse(dataStr)
                                const event = data.event

                                if (event === 'message' || event === 'agent_message') {
                                    callbacks.onMessage?.(data)
                                } else if (event === 'message_end') {
                                    callbacks.onEnd?.(data.task_id || '')
                                } else if (event === 'error' || data.message) {
                                    // 解析错误消息，提取友好提示
                                    let errorMsg = data.message || '发生错误，请稍后重试。'
                                    // 处理嵌套的 JSON 错误信息
                                    if (errorMsg.includes('invalid_param')) {
                                        errorMsg = '请求参数错误，请稍后重试。'
                                    } else if (errorMsg.includes('rate_limit')) {
                                        errorMsg = '请求过于频繁，请稍后再试。'
                                    } else if (errorMsg.includes('quota_exceeded')) {
                                        errorMsg = 'AI 服务额度已用完，请联系管理员。'
                                    }
                                    callbacks.onError?.(errorMsg)
                                }
                            } catch (e) {
                                console.log('解析SSE数据失败:', dataStr)
                            }
                        }
                    }
                }
            } catch (e) {
                console.error('处理分块数据失败:', e)
            }
        })

        return {
            abort: () => {
                requestTask.abort()
            }
        }
    },

    /**
     * 停止对话
     * @param param taskId、agentId、userId 必传
     */
    stopChat(param: StopChatParam): Promise<ResultDomain<boolean>> {
        return request<boolean>({ url: `${this.baseUrl}/stop`, method: 'POST', data: param })
    },

    /**
     * 评价对话消息
     * @param param agentId、chatId、messageId、comment、userId 必传
     */
    commentChatMessage(param: CommentMessageParam): Promise<ResultDomain<boolean>> {
        return request<boolean>({ url: `${this.baseUrl}/comment`, method: 'POST', data: param })
    },

    // ====================== 文件上传 ======================

    /**
     * 上传文件用于对话（图文多模态）
     * @param filePath 文件临时路径
     * @param agentId 智能体ID
     */
    uploadFileForChat(filePath: string, agentId: string): Promise<ResultDomain<DifyFileInfo>> {
        return uploadFile<DifyFileInfo>({
            url: `${this.baseUrl}/file/upload`,
            filePath: filePath,
            name: 'file',
            formData: { agentId: agentId }
        })
    }
}
