'use client';

import { useState, useEffect, useCallback, useRef } from 'react';
import { useSignalRContext } from '@/contexts/signalrProvider';
import type { ChatMessage } from '@/types/chat';

type SystemMessage = {
	id: number;
	content: string;
	receivedAt: string;
};

type ChatParticipant = {
	memberName: string;
	isGuest: boolean;
};

let systemMsgId = 0;

export default function useChat(channelSID?: string) {
	const { chatConnection, chatConnected } = useSignalRContext();
	const [messages, setMessages] = useState<ChatMessage[]>([]);
	const [systemMessages, setSystemMessages] = useState<SystemMessage[]>([]);
	const [participantCount, setParticipantCount] = useState(0);
	const [participants, setParticipants] = useState<ChatParticipant[]>([]);
	const prevConnectionRef = useRef<typeof chatConnection>(null);
	const prevChannelRef = useRef<string|null>(null);

	useEffect(() => {
		if (!chatConnection || !chatConnected) {
			return;
		}

		// 동일 connection + 동일 channel 이면 중복 등록 방지
		if (prevConnectionRef.current === chatConnection && prevChannelRef.current === channelSID) {
			return;
		}

		prevConnectionRef.current = chatConnection;
		prevChannelRef.current = channelSID ?? null;

		chatConnection.on('ReceiveHistory', (history: ChatMessage[]) => {
			setMessages(history);
		});

		chatConnection.on('ReceiveMessage', (message: ChatMessage) => {
			setMessages((prev) => [...prev, message]);
		});

		chatConnection.on('ReceiveSystemMessage', (content: string) => {
			setSystemMessages((prev) => [
				...prev,
				{ id: ++systemMsgId, content, receivedAt: new Date().toISOString() }
			]);
		});

		chatConnection.on('ReceiveParticipantCount', (count: number) => {
			setParticipantCount(count);
		});

		chatConnection.on('ReceiveParticipants', (list: ChatParticipant[]) => {
			setParticipants(list);
		});

		// 채널 참가 (channelSID 필수)
		if (channelSID) {
			chatConnection.invoke('JoinChannel', channelSID).catch((err) => {
				console.error('채팅 채널 참가 실패:', err);
			});
		}

		return () => {
			chatConnection.off('ReceiveHistory');
			chatConnection.off('ReceiveMessage');
			chatConnection.off('ReceiveSystemMessage');
			chatConnection.off('ReceiveParticipantCount');
			chatConnection.off('ReceiveParticipants');

			// 채널 퇴장
			if (channelSID && chatConnection.state === 'Connected') {
				chatConnection.invoke('LeaveChannel').catch(() => {});
			}

			prevConnectionRef.current = null;
			prevChannelRef.current = null;
		};
	}, [chatConnection, chatConnected, channelSID]);

	const sendMessage = useCallback(async (content: string) => {
		if (!chatConnection || !chatConnected) {
			return;
		}
		const trimmed = content.trim();
		if (!trimmed || trimmed.length > 500) {
			return;
		}

		try {
			await chatConnection.invoke('SendMessage', trimmed);
		} catch (error) {
			console.error('메시지 전송 실패:', error);
		}
	}, [chatConnection, chatConnected]);

	const clearMessages = useCallback(() => {
		setMessages([]);
		setSystemMessages([]);
	}, []);

	const refreshChat = useCallback(async () => {
		if (!chatConnection || !chatConnected) {
			return;
		}
		setMessages([]);
		setSystemMessages([]);
		try {
			await chatConnection.invoke('RequestHistory');
			await chatConnection.invoke('RequestParticipantCount');
		} catch {
			// ignore
		}
	}, [chatConnection, chatConnected]);

	const requestParticipants = useCallback(async () => {
		if (!chatConnection || !chatConnected) {
			return;
		}
		try {
			await chatConnection.invoke('RequestParticipants');
		} catch {
			// ignore
		}
	}, [chatConnection, chatConnected]);

	return {
		messages,
		systemMessages,
		participantCount,
		participants,
		sendMessage,
		clearMessages,
		refreshChat,
		requestParticipants,
		chatConnected
	};
}
