import { useEffect, useRef } from 'react';
import { io, Socket } from 'socket.io-client';
import { ChatMessage, Discussion, TllConfig } from '../types';

interface UseTllSocketOptions {
    discussion: Discussion | null;
    tllConfig: TllConfig | null;
    isTll: boolean;
    setMessages: React.Dispatch<React.SetStateAction<ChatMessage[]>>;
    setLoading: (loading: boolean) => void;
    onNewMessage?: (discussionId: number | string, preview: string, date: string) => void;
}

interface UseTllSocketResult {
    socketRef: React.MutableRefObject<Socket | null>;
    lastSubDiscussionRef: React.MutableRefObject<any>;
}

export function useTllSocket({
    discussion,
    tllConfig,
    isTll,
    setMessages,
    setLoading,
    onNewMessage,
}: UseTllSocketOptions): UseTllSocketResult {
    const socketRef = useRef<Socket | null>(null);
    const lastSubDiscussionRef = useRef<any>(null);

    // Disconnect socket when discussion changes
    useEffect(() => {
        return () => {
            socketRef.current?.disconnect();
            socketRef.current = null;
        };
    }, [discussion?.thread_id]);

    // Connect and receive messages via Socket.io (TLL internal only)
    useEffect(() => {
        if (!isTll || !discussion) return;

        if (!tllConfig?.socket_url || !discussion.tll_discussion_id) {
            setLoading(false);
            return;
        }

        const socket = io(tllConfig.socket_url, { transports: ['websocket'] });
        socketRef.current = socket;
        const ownerId = discussion.tll_owner_id;

        socket.emit('join', {
            connected: discussion.tll_client_id,
            sender: discussion.tll_client_id,
            propertyId: discussion.tll_property_id,
            discussionId: discussion.tll_discussion_id,
        });

        socket.on('chatHistory', (data: any) => {
            const subDiscussions: any[] = data?.chatHistory ?? [];
            if (subDiscussions.length > 0) {
                lastSubDiscussionRef.current = subDiscussions[subDiscussions.length - 1];
            }
            const allMessages: ChatMessage[] = subDiscussions
                .flatMap((sub: any) => sub.chats ?? [])
                .map((m: any, i: number) => ({
                    id: m.id ?? i,
                    message_id: 'tll_msg_' + (m.id ?? i),
                    thread_id: 'tll_' + discussion.tll_discussion_id,
                    body: m.message ?? '',
                    create_date: m.createdAt ?? null,
                    is_incoming: m.sender_id !== ownerId,
                    sender_name: m.sender_name ?? 'Client',
                    sender_type: m.sender_id === ownerId ? 'host' : 'guest',
                }));
            setMessages(allMessages);
            setLoading(false);
        });

        socket.on('chatMessage', ({ createMsg }: any) => {
            if (!createMsg) return;
            setMessages((prev) => [
                ...prev,
                {
                    id: createMsg.id,
                    message_id: 'tll_msg_' + createMsg.id,
                    thread_id: 'tll_' + discussion.tll_discussion_id,
                    body: createMsg.message,
                    create_date: createMsg.createdAt,
                    is_incoming: createMsg.sender_id !== ownerId,
                    sender_name: createMsg.sender_name ?? 'Client',
                    sender_type: createMsg.sender_id === ownerId ? 'host' : 'guest',
                },
            ]);
            onNewMessage?.(discussion.id, createMsg.message ?? '', createMsg.createdAt ?? new Date().toISOString());
        });
    }, [discussion?.thread_id, tllConfig, isTll]);

    return { socketRef, lastSubDiscussionRef };
}
