import { useEffect, useRef, useState, useCallback } from 'react';
import { useAuthStore } from '@/stores/auth';
import { useChatStore } from '../store/chatStore';
import { apiClient } from '@/services/api/client';
import { OutgoingMessage, IncomingMessage } from '../types';
import { v4 as uuidv4 } from 'uuid'; // For message IDs
import type { UseChatReturn } from '@/hooks/types';

/**
 * Hook pour gérer le chat WebSocket
 * FE-TYPE-012: Fully typed hook return
 */
export const useChat = (): UseChatReturn => {
  const { user } = useAuthStore();
  const userId = user?.id;
  // const _username = user?.username;
  const {
    wsToken,
    wsUrl,
    wsStatus,
    setWsStatus,
    addMessage,
    currentConversationId,
    loadMessages,
  } = useChatStore();

  const ws = useRef<WebSocket | null>(null);
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const [messagesToSend, setMessagesToSend] = useState<OutgoingMessage[]>([]); // Queue for messages to send

  const connect = useCallback(() => {
    if (!wsToken || !wsUrl || ws.current?.readyState === WebSocket.OPEN) return;

    setWsStatus('connecting');
    const fullWsUrl = `${wsUrl}?token=${wsToken}`; // Assuming WS server is at root of wsUrl
    ws.current = new WebSocket(fullWsUrl);

    ws.current.onopen = () => {
      setWsStatus('connected');
      // WebSocket connection successful - no logging needed in production
      // Send any queued messages
      setMessagesToSend((prev) => {
        prev.forEach((msg) => ws.current?.send(JSON.stringify(msg)));
        return [];
      });
    };

    ws.current.onmessage = (event) => {
      const data = JSON.parse(event.data);
      if (data.type === 'NewMessage') {
        const message: IncomingMessage = data; // Cast to IncomingMessage
        if (message.conversation_id === currentConversationId) {
          addMessage({
            id: message.message_id,
            conversation_id: message.conversation_id,
            sender_id: message.sender_id,
            sender_username: message.sender_username || 'Unknown', // Need sender_username from backend
            content: message.content,
            created_at: message.created_at,
          });
        }
      }
      // Handle other incoming message types (ActionConfirmed, Error, Pong)
    };

    ws.current.onclose = () => {
      setWsStatus('disconnected');
      // WebSocket disconnected - no logging needed in production
      // Optional: Reconnect logic
    };

    ws.current.onerror = (error) => {
      setWsStatus('error');
      console.error('WebSocket error:', error);
      ws.current?.close();
    };
  }, [wsToken, wsUrl, setWsStatus, addMessage, currentConversationId]);

  const disconnect = useCallback(() => {
    if (ws.current) {
      ws.current.close();
      ws.current = null;
      setWsStatus('disconnected');
    }
  }, [setWsStatus]);

  useEffect(() => {
    if (wsToken && wsUrl && wsStatus === 'disconnected') {
      connect();
    }
    // Clean up on unmount
    return () => {
      disconnect();
    };
  }, [wsToken, wsUrl, wsStatus, connect, disconnect]);

  const sendMessage = useCallback(
    (content: string) => {
      if (
        !ws.current ||
        ws.current.readyState !== WebSocket.OPEN ||
        !currentConversationId ||
        !userId
      ) {
        // WebSocket not ready - message will be queued
        console.warn('WebSocket not open or missing conversation/user ID. Message queued.');
        setMessagesToSend((prev) => [
          ...prev,
          {
            type: 'SendMessage',
            conversation_id: currentConversationId || uuidv4(),
            content,
            parent_message_id: null,
          } as OutgoingMessage,
        ]);
        return;
      }

      const message: OutgoingMessage = {
        type: 'SendMessage',
        conversation_id: currentConversationId,
        content,
        parent_message_id: null,
      };
      ws.current.send(JSON.stringify(message));
    },
    [currentConversationId, userId],
  );

  // TODO: Add fetchHistory function
  const fetchHistory = useCallback(
    async (conversationId: string) => {
      try {
        const response = await apiClient.get(
          `/conversations/${conversationId}/history`,
        );
        loadMessages(conversationId, response.data.messages);
      } catch (error) {
        console.error('Failed to fetch chat history:', error);
      }
    },
    [loadMessages],
  );

  return {
    wsStatus,
    connect,
    disconnect,
    sendMessage,
    fetchHistory,
  };
};
