'use client';
import SendSvg from '@/assets/icons/svg/send.svg';
import SunSvg from '@/assets/icons/svg/sun.svg';
import VideoSvg from '@/assets/icons/svg/video.svg';
import React, { Dispatch, SetStateAction, useCallback, useEffect, useRef, useState } from 'react';
import {
    Keyboard,
    ScrollView,
    StyleSheet,
    TextInput,
    TouchableOpacity,
    View
} from 'react-native';

import { Message } from '@/types/ask';
import { useTranslation } from 'react-i18next';
import { ThemedText } from '../ThemedText';
import { createNewConversation } from './utils';
import { WsMessage } from '@/lib/websocket-util';
import { webSocketManager } from '@/lib/websocket-util';

interface Props {
    setIsHello: Dispatch<SetStateAction<boolean>>,
    conversationId: string | null,
    setUserMessages: Dispatch<SetStateAction<Message[]>>;
    setConversationId: (conversationId: string) => void,
    selectedImages: string[];
    setSelectedImages: Dispatch<SetStateAction<string[]>>;
}
const RENDER_INTERVAL = 50; // 渲染间隔，单位毫秒

export default function SendMessage(props: Props) {
    const { setIsHello, conversationId, setUserMessages, setConversationId, selectedImages, setSelectedImages } = props;

    const { t } = useTranslation()

    // 用户询问
    const [inputValue, setInputValue] = useState('');

    // 添加一个ref来跟踪键盘状态
        const isKeyboardVisible = useRef(false);
    const chunkQueue = useRef<string[]>([]);
    const renderInterval = useRef<ReturnType<typeof setInterval> | null>(null);

    useEffect(() => {
                                const handleChatStream = (message: WsMessage) => {
            if (message.type !== 'ChatStream' || !message.chunk) return;

            chunkQueue.current.push(message.chunk);

            if (!renderInterval.current) {
                renderInterval.current = setInterval(() => {
                    if (chunkQueue.current.length > 0) {
                        const textToRender = chunkQueue.current.join('');
                        chunkQueue.current = [];

                        setUserMessages(prevMessages => {
                            if (prevMessages.length === 0) return prevMessages;

                            const lastMessage = prevMessages[prevMessages.length - 1];
                            if (lastMessage.role !== 'assistant') return prevMessages;

                            const updatedContent = (lastMessage.content === 'keepSearchIng' ? '' : lastMessage.content) + textToRender;

                            const updatedLastMessage = { ...lastMessage, content: updatedContent };

                            return [...prevMessages.slice(0, -1), updatedLastMessage];
                        });
                    } else {
                        if (renderInterval.current) {
                            clearInterval(renderInterval.current);
                            renderInterval.current = null;
                        }
                    }
                }, RENDER_INTERVAL);
            }
        };

                        const handleChatStreamEnd = (message: WsMessage) => {
            if (message.type !== 'ChatStreamEnd') return;

            // Stop the timer and process any remaining chunks
            if (renderInterval.current) {
                clearInterval(renderInterval.current);
                renderInterval.current = null;
            }

            const remainingText = chunkQueue.current.join('');
            chunkQueue.current = [];

            setUserMessages(prevMessages => {
                if (prevMessages.length === 0) return prevMessages;

                const lastMessage = prevMessages[prevMessages.length - 1];
                if (lastMessage.role !== 'assistant') return prevMessages;

                // Apply remaining chunks from the queue
                const contentWithQueue = (lastMessage.content === 'keepSearchIng' ? '' : lastMessage.content) + remainingText;

                // Create the final updated message object
                const updatedLastMessage = {
                    ...lastMessage,
                    // Use the final message from ChatStreamEnd if available, otherwise use the content with queued text
                    content: message.message ? message.message.content : contentWithQueue,
                    timestamp: message.message ? message.message.timestamp : lastMessage.timestamp,
                };

                return [...prevMessages.slice(0, -1), updatedLastMessage];
            });
        };

        const handleChatResponse = (message: WsMessage) => {
            if (message.type === 'ChatResponse' && message.message) {
                setUserMessages(prev => {
                    const newMessages = prev.filter(item => item.content !== 'keepSearchIng');
                    return [...newMessages, {
                        ...(message.message as Message),
                        role: 'assistant',
                    }];
                });
            }
        }

        const typedHandleChatStream = handleChatStream as (message: WsMessage) => void;
        const typedHandleChatStreamEnd = handleChatStreamEnd as (message: WsMessage) => void;
        const typedHandleChatResponse = handleChatResponse as (message: WsMessage) => void;

        webSocketManager.subscribe('ChatStream', typedHandleChatStream);
        webSocketManager.subscribe('ChatStreamEnd', typedHandleChatStreamEnd);
        webSocketManager.subscribe('ChatResponse', typedHandleChatResponse);

                return () => {
            webSocketManager.unsubscribe('ChatStream', typedHandleChatStream);
            webSocketManager.unsubscribe('ChatStreamEnd', typedHandleChatStreamEnd);
            webSocketManager.unsubscribe('ChatResponse', typedHandleChatResponse);
            if (renderInterval.current) {
                clearInterval(renderInterval.current);
            }
        };
    }, [setUserMessages]);

    useEffect(() => {
        // 使用keyboardWillShow而不是keyboardDidShow，这样可以在键盘完全显示前更新UI
        const showSubscription = Keyboard.addListener('keyboardWillShow', () => {
            isKeyboardVisible.current = true;
            if (!conversationId) {
                // 确保在下一个事件循环中更新状态，避免可能的渲染问题
                requestAnimationFrame(() => {
                    setIsHello(false);
                    setUserMessages([
                        {
                            id: Math.random().toString(36).substring(2, 9),
                            content: t("ask:ask.introduction1"),
                            role: 'assistant',
                            timestamp: new Date().toISOString()
                        }
                    ])
                });
            }
        });

        const hideSubscription = Keyboard.addListener('keyboardWillHide', () => {
            isKeyboardVisible.current = false;
        });

        return () => {
            showSubscription.remove();
            hideSubscription.remove();
        };
    }, [conversationId, setIsHello, setUserMessages, t]);


    // 发送询问
    const handleSubmit = useCallback(async () => {
        const text = inputValue.trim();
        // 用户输入信息之后进行后续操作
        if (text) {
            // 将用户输入信息添加到消息列表中
            setUserMessages(pre => ([...pre, {
                id: Math.random().toString(36).substring(2, 9),
                content: text,
                role: 'user',
                timestamp: new Date().toISOString()
            },
            {
                id: Math.random().toString(36).substring(2, 9),
                content: "keepSearchIng",
                role: 'assistant',
                timestamp: new Date().toISOString()
            }
            ]));
            let currentSessionId = conversationId;
            // 如果没有对话ID，先创建一个新对话
            if (!currentSessionId) {
                currentSessionId = await createNewConversation(text);
                setConversationId(currentSessionId);
            }

            // 通过 WebSocket 发送消息
            if (currentSessionId) {
                webSocketManager.send({
                    type: 'Chat',
                    session_id: currentSessionId,
                    message: text,
                    image_material_ids: selectedImages.length > 0 ? selectedImages : undefined,
                });
                setSelectedImages([]);
            } else {
                console.error("无法获取 session_id，消息发送失败。");
                // 可以在这里处理错误，例如显示一个提示
                setUserMessages(prev => prev.filter(item => item.content !== 'keepSearchIng'));
            }
            // 将输入框清空
            setInputValue('');
            // 只有在键盘可见时才关闭键盘
            if (isKeyboardVisible.current) {
                Keyboard.dismiss();
            }
        }
    }, [inputValue, conversationId, selectedImages, createNewConversation, setConversationId, setSelectedImages, setUserMessages]);

    const handleQuitly = (type: string) => {
        setIsHello(false)
        setUserMessages(pre => ([
            ...pre,
            {
                id: Math.random().toString(36).substring(2, 9),
                content: type === "search"
                    ? t("ask:ask.introduction2")
                    : t("ask:ask.introduction3"),
                role: 'assistant',
                timestamp: new Date().toISOString()
            }
        ]))
    };

    return (
        <View style={styles.container}>
            <View className="relative w-full">
                <ScrollView horizontal={true}>
                    <TouchableOpacity style={[styles.button, { borderColor: '#FFB645' }]} onPress={() => handleQuitly('search')}>
                        <SunSvg width={18} height={18} />
                        <ThemedText>{t("ask:ask.search")}</ThemedText>
                    </TouchableOpacity><TouchableOpacity style={[styles.button, { borderColor: '#E2793F' }]} onPress={() => handleQuitly('video')}>
                        <VideoSvg width={18} height={18} />
                        <ThemedText>{t("ask:ask.video")}</ThemedText>
                    </TouchableOpacity>
                </ScrollView>
                <TextInput
                    style={styles.input}
                    placeholder="Ask MeMo Anything..."
                    placeholderTextColor="#999"
                    value={inputValue}
                    onChangeText={(text: string) => {
                        setInputValue(text);
                    }}
                    onSubmitEditing={handleSubmit}
                    // 调起的键盘类型
                    returnKeyType="send"
                />
                <TouchableOpacity
                    style={[styles.voiceButton, { bottom: -10 }]}
                    onPress={handleSubmit}
                    className="absolute right-2"
                >
                    <View>
                        <SendSvg color={'white'} width={24} height={24} />
                    </View>
                </TouchableOpacity>
            </View>
        </View>
    );
}

const styles = StyleSheet.create({
    button: {
        paddingHorizontal: 8,
        paddingVertical: 4,
        margin: 5,
        borderRadius: 25,
        alignItems: 'center',
        borderWidth: 2,
        display: 'flex',
        flexDirection: 'row',
        gap: 5
    },
    container: {
        justifyContent: 'center',
        backgroundColor: '#transparent',
    },
    input: {
        borderColor: '#FF9500',
        borderWidth: 1,
        borderRadius: 25,
        paddingHorizontal: 20,
        paddingVertical: 13,
        fontSize: 16,
        width: '100%', // 确保输入框宽度撑满
        paddingRight: 50
    },
    voiceButton: {
        padding: 8,
        borderRadius: 20,
        backgroundColor: '#FF9500',
        justifyContent: 'center',
        alignItems: 'center',
        position: 'absolute',
        transform: [{ translateY: -12 }],
    },
});