import React, { useState, useEffect, useRef } from 'react';
import { CheckCircle, XCircle, Send, Clock, User, X, RefreshCw } from 'lucide-react';
import chatService, { type Chat, type ChatMessage } from '../../features/notifications/services/chatService';
import { toast } from 'react-toastify';
import Loading from '../../shared/components/Loading';
import EmptyState from '../../shared/components/EmptyState';
import { formatDate } from '../../shared/utils/format';
import useAuthStore from '../../store/useAuthStore';
import { useChatNotifications } from '../../features/notifications/contexts/ChatNotificationContext';
import { logger } from '../../shared/utils/logger';

const ChatManagementPage: React.FC = () => {
  const [chats, setChats] = useState<Chat[]>([]);
  const [selectedChat, setSelectedChat] = useState<Chat | null>(null);
  const [messages, setMessages] = useState<ChatMessage[]>([]);
  const [newMessage, setNewMessage] = useState('');
  const [loading, setLoading] = useState(false);
  const [loadingMessages, setLoadingMessages] = useState(false);
  const [ws, setWs] = useState<WebSocket | null>(null);
  const [notificationWs, setNotificationWs] = useState<WebSocket | null>(null);
  const messagesEndRef = useRef<HTMLDivElement>(null);
  const authStore = useAuthStore();
  // Tokens are in httpOnly cookies, not accessible from JavaScript
  // WebSocket authentication will use cookie-based auth
  const { refreshCount } = useChatNotifications();

  const scrollToBottom = () => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  };

  useEffect(() => {
    scrollToBottom();
  }, [messages]);

  useEffect(() => {
    fetchChats();
    connectNotificationWebSocket();
    if (refreshCount) {
      refreshCount();
    }

    return () => {
      if (ws) ws.close();
      if (notificationWs) notificationWs.close();
    };
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    if (selectedChat) {
      fetchMessages(selectedChat.id);
      connectChatWebSocket(selectedChat.id);
    }

    return () => {
      if (ws) {
        ws.close();
        setWs(null);
      }
    };
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [selectedChat]);

  const connectNotificationWebSocket = () => {
    // Check if user is authenticated (tokens are in httpOnly cookies)
    if (!authStore.isAuthenticated) return;

    const baseUrl = import.meta.env.VITE_API_URL || 'http://localhost:8000';
    const normalizedBase = baseUrl.replace(/\/$/, '');
    const wsProtocol = normalizedBase.startsWith('https') ? 'wss' : 'ws';
    const wsBase = normalizedBase.replace(/^https?/, wsProtocol);
    // Use cookie-based authentication - cookies are sent automatically with WebSocket
    // Backend should validate using cookies instead of query parameter
    const wsUrl = `${wsBase}/api/chat/ws/staff/notifications`;
    
    const websocket = new WebSocket(wsUrl);
    
    websocket.onopen = () => {
      logger.debug('Notification WebSocket connected');
    };
    
    websocket.onmessage = (event) => {
      const data = JSON.parse(event.data);
      
      if (data.type === 'new_chat') {
        toast.info(`New chat from ${data.data.visitor_name}`, {
          onClick: () => {
            fetchChats().then(() => {
              const newChat = chats.find(c => c.id === data.data.id);
              if (newChat) setSelectedChat(newChat);
            });
          }
        });
        fetchChats();
      } else if (data.type === 'new_message_notification') {
        const chatData = data.data.chat;
        const messageData = data.data.message;
        toast.info(`New message from ${chatData.visitor_name}: ${messageData.message.substring(0, 50)}${messageData.message.length > 50 ? '...' : ''}`, {
          onClick: () => {
            fetchChats().then(() => {
              const chat = chats.find(c => c.id === chatData.id);
              if (chat) {
                setSelectedChat(chat);
                fetchMessages(chat.id);
              }
            });
          },
          autoClose: 10000
        });
        fetchChats();
      }
    };
    
    websocket.onerror = (error) => {
      logger.error('Notification WebSocket error', error);
    };
    
    websocket.onclose = () => {
      logger.debug('Notification WebSocket disconnected');
      setTimeout(() => {
        connectNotificationWebSocket();
      }, 5000);
    };
    
    setNotificationWs(websocket);
  };

  const connectChatWebSocket = (chatId: number) => {
    // Check if user is authenticated (tokens are in httpOnly cookies)
    if (!authStore.isAuthenticated) return;

    if (ws) {
      ws.close();
    }

    const baseUrl = import.meta.env.VITE_API_URL || 'http://localhost:8000';
    const normalizedBase = baseUrl.replace(/\/$/, '');
    const wsProtocol = normalizedBase.startsWith('https') ? 'wss' : 'ws';
    const wsBase = normalizedBase.replace(/^https?/, wsProtocol);
    // Use cookie-based authentication - cookies are sent automatically with WebSocket
    // Backend should validate using cookies instead of query parameter
    const wsUrl = `${wsBase}/api/chat/ws/${chatId}?user_type=staff`;
    
    const websocket = new WebSocket(wsUrl);
    
    websocket.onopen = () => {
      logger.debug('Chat WebSocket connected for chat', { chatId });
    };
    
    websocket.onmessage = (event) => {
      try {
        const data = JSON.parse(event.data);
        
        if (data.type === 'new_message') {
          setMessages(prev => {
            
            const exists = prev.find(m => m.id === data.data.id);
            if (exists) return prev;
            return [...prev, data.data];
          });
        } else if (data.type === 'chat_accepted') {
          
          if (selectedChat && selectedChat.id === chatId) {
            setSelectedChat({ ...selectedChat, status: 'active' });
          }
          fetchChats();
        } else if (data.type === 'chat_closed') {
          toast.info('Chat has been closed');
          if (selectedChat) {
            setSelectedChat({ ...selectedChat, status: 'closed' });
          }
          fetchChats();
        }
      } catch (error) {
        logger.error('Error parsing WebSocket message', error);
      }
    };
    
    websocket.onerror = (error) => {
      logger.error('Chat WebSocket error', error);
    };
    
    websocket.onclose = (event) => {
      logger.debug('Chat WebSocket disconnected', { code: event.code, reason: event.reason });
      
      if (event.code !== 1000 && selectedChat && selectedChat.id === chatId) {
        logger.debug('Attempting to reconnect chat WebSocket...');
        setTimeout(() => {
          if (selectedChat && selectedChat.id === chatId) {
            connectChatWebSocket(chatId);
          }
        }, 3000);
      }
    };
    
    setWs(websocket);
  };

  
  useEffect(() => {
    if (!selectedChat) return;

    const pollInterval = setInterval(async () => {
      try {
        const response = await chatService.getMessages(selectedChat.id);
        if (response.success) {
          setMessages(response.data);
        }
      } catch (error) {
        logger.error('Error polling messages', error);
      }
    }, 3000); 

    return () => clearInterval(pollInterval);
  }, [selectedChat]);

  const fetchChats = async () => {
    try {
      setLoading(true);
      const response = await chatService.listChats();
      if (response.success) {
        setChats(response.data);
      } else {
        // Clear data if response is not successful
        setChats([]);
      }
    } catch (error: unknown) {
      // Clear data when API connection fails
      setChats([]);
      toast.error(getUserFriendlyError(error) || 'Failed to load chats');
    } finally {
      setLoading(false);
    }
  };

  const fetchMessages = async (chatId: number) => {
    try {
      setLoadingMessages(true);
      const response = await chatService.getMessages(chatId);
      if (response.success) {
        setMessages(response.data);
      } else {
        // Clear data if response is not successful
        setMessages([]);
      }
    } catch (error: unknown) {
      // Clear data when API connection fails
      setMessages([]);
      toast.error(getUserFriendlyError(error) || 'Failed to load messages');
    } finally {
      setLoadingMessages(false);
    }
  };

  const handleAcceptChat = async (chatId: number) => {
    try {
      const response = await chatService.acceptChat(chatId);
      if (response.success) {
        toast.success('Chat accepted');
        fetchChats();
        if (selectedChat?.id === chatId) {
          setSelectedChat(response.data);
        }
      }
    } catch (error: unknown) {
      toast.error(getUserFriendlyError(error) || 'Failed to accept chat');
    }
  };

  const handleSendMessage = async () => {
    if (!newMessage.trim() || !selectedChat) return;
    
    const messageText = newMessage.trim();
    setNewMessage('');
    
    
    const tempMessage: ChatMessage = {
      id: Date.now(),
      chat_id: selectedChat.id,
      sender_type: 'staff',
      sender_name: 'You',
      message: messageText,
      is_read: false,
      created_at: new Date().toISOString()
    };
    setMessages(prev => [...prev, tempMessage]);
    
    try {
      if (ws && ws.readyState === WebSocket.OPEN) {
        
        ws.send(JSON.stringify({
          type: 'message',
          message: messageText
        }));
      } else {
        
        await chatService.sendMessage(selectedChat.id, messageText);
        
        const messagesResponse = await chatService.getMessages(selectedChat.id);
        setMessages(messagesResponse.data);
      }
    } catch (error: unknown) {
      toast.error('Failed to send message');
      
      setMessages(prev => prev.filter(m => m.id !== tempMessage.id));
    }
  };

  const handleCloseChat = async (chatId: number) => {
    try {
      const response = await chatService.closeChat(chatId);
      if (response.success) {
        toast.success('Chat closed');
        fetchChats();
        if (selectedChat?.id === chatId) {
          setSelectedChat({ ...selectedChat, status: 'closed' });
        }
      }
    } catch (error: unknown) {
      toast.error(getUserFriendlyError(error) || 'Failed to close chat');
    }
  };

  const handleKeyPress = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      handleSendMessage();
    }
  };

  const getStatusBadge = (status: string) => {
    switch (status) {
      case 'pending':
        return (
          <span className="px-3 py-1.5 text-xs font-semibold rounded-full bg-gradient-to-r from-amber-50 to-yellow-50 text-amber-800 border border-amber-200/60 shadow-sm">
            <Clock className="w-3 h-3 inline mr-1.5" />
            Pending
          </span>
        );
      case 'active':
        return (
          <span className="px-3 py-1.5 text-xs font-semibold rounded-full bg-gradient-to-r from-emerald-50 to-green-50 text-emerald-800 border border-emerald-200/60 shadow-sm">
            <CheckCircle className="w-3 h-3 inline mr-1.5" />
            Active
          </span>
        );
      case 'closed':
        return (
          <span className="px-3 py-1.5 text-xs font-semibold rounded-full bg-gradient-to-r from-slate-50 to-gray-50 text-slate-700 border border-slate-200/60 shadow-sm">
            <XCircle className="w-3 h-3 inline mr-1.5" />
            Closed
          </span>
        );
      default:
        return null;
    }
  };

  if (loading && chats.length === 0) {
    return <Loading fullScreen text="Loading chats..." />;
  }

  return (
    <div className="space-y-6 bg-gradient-to-br from-slate-50 via-white to-slate-50 min-h-screen -m-6 p-8">
      <div className="flex items-center justify-between">
        <div>
          <div className="flex items-center gap-3 mb-2">
            <div className="h-1 w-16 bg-gradient-to-r from-[var(--luxury-gold)] to-[var(--luxury-gold-dark)] rounded-full"></div>
            <h1 className="text-3xl font-serif font-bold bg-gradient-to-r from-slate-900 via-slate-800 to-slate-900 bg-clip-text text-transparent tracking-tight">
              Chat Management
            </h1>
          </div>
          <p className="text-slate-600 mt-2 font-light">Manage customer support chats with elegance</p>
        </div>
        <button
          onClick={fetchChats}
          className="px-6 py-2.5 bg-gradient-to-r from-[var(--luxury-gold)] to-[var(--luxury-gold-dark)] text-slate-900 rounded-lg font-semibold hover:from-[var(--luxury-gold-dark)] hover:to-[var(--luxury-gold)] transition-all duration-300 shadow-lg shadow-[var(--luxury-gold)]/30 hover:shadow-xl hover:shadow-[var(--luxury-gold)]/40 flex items-center gap-2"
        >
          <RefreshCw className="w-4 h-4" />
          Refresh
        </button>
      </div>

      <div className="grid grid-cols-1 lg:grid-cols-3 gap-6 h-[calc(100vh-200px)]">
        {}
        <div className="luxury-glass rounded-xl shadow-2xl border border-[var(--luxury-gold)]/20 overflow-hidden flex flex-col">
          <div className="p-4 border-b border-[var(--luxury-gold)]/20 bg-gradient-to-r from-[var(--luxury-gold)]/10 via-[var(--luxury-gold-dark)]/10 to-[var(--luxury-gold)]/10 relative">
            <div className="absolute top-0 left-0 right-0 h-0.5 bg-gradient-to-r from-transparent via-[var(--luxury-gold)] to-transparent"></div>
            <h2 className="font-serif font-semibold text-slate-900 tracking-wide">Chats ({chats.length})</h2>
          </div>
          <div className="flex-1 overflow-y-auto">
            {chats.length === 0 ? (
              <EmptyState
                title="No chats"
                description="No chat requests at the moment"
              />
            ) : (
              <div className="divide-y divide-gray-200">
                {chats.map((chat) => (
                  <div
                    key={chat.id}
                    onClick={() => setSelectedChat(chat)}
                    className={`p-4 cursor-pointer hover:bg-gradient-to-r hover:from-[var(--luxury-gold)]/5 hover:to-[var(--luxury-gold-dark)]/5 transition-all duration-300 ${
                      selectedChat?.id === chat.id 
                        ? 'bg-gradient-to-r from-[var(--luxury-gold)]/10 to-[var(--luxury-gold-dark)]/10 border-l-4 border-[var(--luxury-gold)] shadow-sm' 
                        : 'border-l-4 border-transparent'
                    }`}
                  >
                    <div className="flex items-start justify-between mb-2">
                      <div className="flex items-center gap-2">
                        <User className="w-4 h-4 text-gray-500" />
                        <span className="font-semibold text-slate-900">
                          {chat.visitor_name || 'Guest'}
                        </span>
                      </div>
                      {getStatusBadge(chat.status)}
                    </div>
                    {chat.visitor_email && (
                      <p className="text-sm text-gray-600 mb-2">{chat.visitor_email}</p>
                    )}
                    <p className="text-xs text-gray-500">
                      {formatDate(chat.created_at)}
                    </p>
                    {chat.status === 'pending' && (
                      <button
                        onClick={(e) => {
                          e.stopPropagation();
                          handleAcceptChat(chat.id);
                        }}
                        className="mt-2 w-full px-3 py-1.5 bg-gradient-to-r from-[var(--luxury-gold)] to-[var(--luxury-gold-dark)] text-slate-900 text-sm font-semibold rounded-lg hover:from-[var(--luxury-gold-dark)] hover:to-[var(--luxury-gold)] transition-all duration-300 shadow-md shadow-[var(--luxury-gold)]/30 hover:shadow-lg"
                      >
                        Accept Chat
                      </button>
                    )}
                  </div>
                ))}
              </div>
            )}
          </div>
        </div>

        {}
        <div className="lg:col-span-2 luxury-glass rounded-xl shadow-2xl border border-[var(--luxury-gold)]/20 overflow-hidden flex flex-col">
          {selectedChat ? (
            <>
              <div className="p-4 border-b border-[var(--luxury-gold)]/20 bg-gradient-to-r from-[var(--luxury-gold)]/10 via-[var(--luxury-gold-dark)]/10 to-[var(--luxury-gold)]/10 flex items-center justify-between relative">
                <div className="absolute top-0 left-0 right-0 h-0.5 bg-gradient-to-r from-transparent via-[var(--luxury-gold)] to-transparent"></div>
                <div>
                  <h2 className="font-serif font-semibold text-slate-900 tracking-wide">
                    {selectedChat.visitor_name || 'Guest'}
                  </h2>
                  {selectedChat.visitor_email && (
                    <p className="text-sm text-slate-600 font-light">{selectedChat.visitor_email}</p>
                  )}
                  {selectedChat.staff_name && (
                    <p className="text-xs text-[var(--luxury-gold)] mt-1 font-medium">
                      Accepted by: {selectedChat.staff_name}
                    </p>
                  )}
                </div>
                <div className="flex items-center gap-2">
                  {getStatusBadge(selectedChat.status)}
                  {selectedChat.status !== 'closed' && (
                    <button
                      onClick={() => handleCloseChat(selectedChat.id)}
                      className="p-2 text-gray-600 hover:text-red-600 transition-colors"
                      title="Close chat"
                    >
                      <X className="w-5 h-5" />
                    </button>
                  )}
                </div>
              </div>

              <div className="flex-1 overflow-y-auto p-4 space-y-4 bg-gradient-to-b from-slate-50/50 to-white">
                {loadingMessages ? (
                  <Loading text="Loading messages..." />
                ) : messages.length === 0 ? (
                  <EmptyState
                    title="No messages"
                    description="Start the conversation"
                  />
                ) : (
                  messages.map((message) => (
                    <div
                      key={message.id}
                      className={`flex ${
                        message.sender_type === 'staff' ? 'justify-end' : 'justify-start'
                      }`}
                    >
                      <div
                        className={`max-w-[80%] rounded-xl p-4 shadow-lg ${
                          message.sender_type === 'staff'
                            ? 'bg-gradient-to-br from-[var(--luxury-gold)] to-[var(--luxury-gold-dark)] text-slate-900 border border-[var(--luxury-gold)]/30'
                            : 'bg-white text-slate-800 border border-slate-200/60 shadow-sm'
                        }`}
                      >
                        {message.sender_type === 'visitor' && (
                          <div className="text-xs font-semibold mb-1.5 text-[var(--luxury-gold)] tracking-wide">
                            {message.sender_name || 'Visitor'}
                          </div>
                        )}
                        <p className="text-sm whitespace-pre-wrap break-words leading-relaxed">
                          {message.message}
                        </p>
                        <p
                          className={`text-xs mt-2 ${
                            message.sender_type === 'staff'
                              ? 'text-slate-700/70'
                              : 'text-slate-500'
                          }`}
                        >
                          {new Date(message.created_at).toLocaleTimeString([], {
                            hour: '2-digit',
                            minute: '2-digit',
                          })}
                        </p>
                      </div>
                    </div>
                  ))
                )}
                <div ref={messagesEndRef} />
              </div>

              {selectedChat.status !== 'closed' && (
                <div className="p-4 border-t border-[var(--luxury-gold)]/20 bg-white/90 backdrop-blur-sm">
                  <div className="flex gap-3">
                    <input
                      type="text"
                      value={newMessage}
                      onChange={(e) => setNewMessage(e.target.value)}
                      onKeyPress={handleKeyPress}
                      placeholder="Type your message..."
                      className="flex-1 px-4 py-3 border-2 border-slate-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-[var(--luxury-gold)]/30 focus:border-[var(--luxury-gold)] transition-all duration-200 font-light"
                      disabled={selectedChat.status === 'pending'}
                    />
                    <button
                      onClick={handleSendMessage}
                      disabled={!newMessage.trim() || selectedChat.status === 'pending'}
                      className="bg-gradient-to-r from-[var(--luxury-gold)] to-[var(--luxury-gold-dark)] text-slate-900 px-5 py-3 rounded-xl hover:from-[var(--luxury-gold-dark)] hover:to-[var(--luxury-gold)] disabled:bg-gray-300 disabled:text-gray-500 disabled:cursor-not-allowed transition-all duration-300 flex items-center gap-2 font-semibold shadow-lg shadow-[var(--luxury-gold)]/30 hover:shadow-xl disabled:shadow-none"
                    >
                      <Send className="w-4 h-4" />
                    </button>
                  </div>
                  {selectedChat.status === 'pending' && (
                    <p className="text-xs text-slate-500 mt-2 font-light">
                      Accept the chat to start messaging
                    </p>
                  )}
                </div>
              )}
            </>
          ) : (
            <div className="flex-1 flex items-center justify-center">
              <EmptyState
                title="No chat selected"
                description="Select a chat from the list to view messages"
              />
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

export default ChatManagementPage;

