'use client';

import { useState, useEffect, useRef, useCallback } from 'react';
import { useSession } from 'next-auth/react';
import { useRouter } from 'next/navigation';
import Image from 'next/image';
import { CommonHeader } from '@/components/layout/CommonHeader';
import { Footer } from '@/components/layout/Footer';
import { supportChatService } from '@/services/support-chat.service';
import { socketService } from '@/services/socket.service';
import type { SupportChat, SupportMessage } from '@/services/support-chat.service';

export default function SupportChatPage() {
  const { data: session, status } = useSession();
  const router = useRouter();

  const [chat, setChat] = useState<SupportChat | null>(null);
  const [messages, setMessages] = useState<SupportMessage[]>([]);
  const [input, setInput] = useState('');
  const [isLoading, setIsLoading] = useState(true);
  const [isSending, setIsSending] = useState(false);
  const [hasMore, setHasMore] = useState(false);
  const [currentPage, setCurrentPage] = useState(1);
  const [isLoadingMore, setIsLoadingMore] = useState(false);
  const [isTyping, setIsTyping] = useState(false);
  const [error, setError] = useState('');

  const messagesEndRef = useRef<HTMLDivElement>(null);
  const messagesContainerRef = useRef<HTMLDivElement>(null);
  const typingTimeoutRef = useRef<NodeJS.Timeout | null>(null);
  const currentUserId = (session?.user as any)?.id;

  // Redirect to login if not authenticated
  useEffect(() => {
    if (status === 'loading') return;
    if (!session) {
      const tokensExist = typeof window !== 'undefined' && !!localStorage.getItem('accessToken');
      if (!tokensExist) {
        router.replace('/login');
      }
    }
  }, [session, status, router]);

  // Initialize chat
  useEffect(() => {
    if (!session) return;

    const initChat = async () => {
      try {
        const supportChat = await supportChatService.getOrCreateChat();
        setChat(supportChat);

        // Load messages
        const { messages: loadedMessages, pagination } = await supportChatService.getMessages(supportChat.id);
        setMessages(loadedMessages);
        setHasMore(pagination.page < pagination.pages);

        // Mark as read
        await supportChatService.markAsRead(supportChat.id);
      } catch (err) {
        console.error('Failed to initialize support chat:', err);
        setError('Failed to load support chat. Please try again.');
      } finally {
        setIsLoading(false);
      }
    };

    initChat();
  }, [session]);

  // Socket connection and event listeners
  useEffect(() => {
    if (!chat) return;

    const token = typeof window !== 'undefined' ? localStorage.getItem('accessToken') : null;
    if (!token) return;

    // Connect socket if not connected
    const connectSocket = async () => {
      if (!socketService.isConnected()) {
        try {
          await socketService.connect(token);
        } catch (err) {
          console.error('Socket connection failed:', err);
        }
      }

      // Join support chat room
      if (socketService.isConnected()) {
        const socket = (socketService as any).socket;
        if (socket) {
          socket.emit('support_join', { chatId: chat.id });
        }
      }
    };

    connectSocket();

    // Listen for new support messages
    const handleNewMessage = (message: SupportMessage) => {
      if (message.chatId === chat.id) {
        setMessages(prev => {
          if (prev.some(m => m.id === message.id)) return prev;
          return [...prev, message];
        });
        // Mark as read since we're viewing
        supportChatService.markAsRead(chat.id).catch(() => {});
      }
    };

    const handleTypingStart = (data: { chatId: string; userId: string }) => {
      if (data.chatId === chat.id && data.userId !== currentUserId) {
        setIsTyping(true);
      }
    };

    const handleTypingStop = (data: { chatId: string; userId: string }) => {
      if (data.chatId === chat.id && data.userId !== currentUserId) {
        setIsTyping(false);
      }
    };

    // Register socket event handlers
    const socket = (socketService as any).socket;
    if (socket) {
      socket.on('support_new_message', handleNewMessage);
      socket.on('support_typing_start', handleTypingStart);
      socket.on('support_typing_stop', handleTypingStop);
    }

    return () => {
      if (socket) {
        socket.off('support_new_message', handleNewMessage);
        socket.off('support_typing_start', handleTypingStart);
        socket.off('support_typing_stop', handleTypingStop);
        socket.emit('support_leave', { chatId: chat.id });
      }
    };
  }, [chat, currentUserId]);

  // Auto-scroll to bottom on new messages (scroll container, not page)
  useEffect(() => {
    const container = messagesContainerRef.current;
    if (container) {
      container.scrollTop = container.scrollHeight;
    }
  }, [messages]);

  // Send message
  const handleSend = async () => {
    if (!input.trim() || !chat || isSending) return;

    const content = input.trim();
    setInput('');
    setIsSending(true);

    // Stop typing indicator
    const socket = (socketService as any).socket;
    if (socket) {
      socket.emit('support_typing_stop', { chatId: chat.id });
    }

    try {
      // Try socket first
      if (socket?.connected) {
        const result = await new Promise<{ success: boolean; message?: SupportMessage; error?: string }>((resolve) => {
          const timeout = setTimeout(() => resolve({ success: false, error: 'timeout' }), 10000);
          socket.emit('support_send_message', { chatId: chat.id, content }, (response: any) => {
            clearTimeout(timeout);
            resolve(response);
          });
        });

        if (result.success && result.message) {
          setMessages(prev => {
            if (prev.some(m => m.id === result.message!.id)) return prev;
            return [...prev, result.message!];
          });
        } else {
          // Fallback to REST
          const message = await supportChatService.sendMessage(chat.id, content);
          setMessages(prev => [...prev, message]);
        }
      } else {
        // REST fallback
        const message = await supportChatService.sendMessage(chat.id, content);
        setMessages(prev => [...prev, message]);
      }
    } catch (err) {
      console.error('Failed to send message:', err);
      setInput(content); // Restore message
    } finally {
      setIsSending(false);
    }
  };

  // Handle typing indicator
  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setInput(e.target.value);

    if (!chat) return;
    const socket = (socketService as any).socket;
    if (!socket?.connected) return;

    socket.emit('support_typing_start', { chatId: chat.id });

    if (typingTimeoutRef.current) clearTimeout(typingTimeoutRef.current);
    typingTimeoutRef.current = setTimeout(() => {
      socket.emit('support_typing_stop', { chatId: chat.id });
    }, 3000);
  };

  // Load older messages
  const loadMore = useCallback(async () => {
    if (!chat || !hasMore || isLoadingMore) return;

    setIsLoadingMore(true);
    try {
      const nextPage = currentPage + 1;
      const { messages: olderMessages, pagination } = await supportChatService.getMessages(chat.id, nextPage);
      setMessages(prev => [...olderMessages, ...prev]);
      setCurrentPage(nextPage);
      setHasMore(pagination.page < pagination.pages);
    } catch (err) {
      console.error('Failed to load more messages:', err);
    } finally {
      setIsLoadingMore(false);
    }
  }, [chat, hasMore, isLoadingMore, currentPage]);

  // Format time
  const formatTime = (dateStr: string) => {
    const date = new Date(dateStr);
    return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
  };

  const formatDate = (dateStr: string) => {
    const date = new Date(dateStr);
    const today = new Date();
    const yesterday = new Date(today);
    yesterday.setDate(yesterday.getDate() - 1);

    if (date.toDateString() === today.toDateString()) return 'Today';
    if (date.toDateString() === yesterday.toDateString()) return 'Yesterday';
    return date.toLocaleDateString([], { month: 'short', day: 'numeric', year: 'numeric' });
  };

  // Group messages by date
  const groupedMessages = messages.reduce<{ date: string; messages: SupportMessage[] }[]>((groups, msg) => {
    const dateStr = formatDate(msg.createdAt);
    const lastGroup = groups[groups.length - 1];
    if (lastGroup && lastGroup.date === dateStr) {
      lastGroup.messages.push(msg);
    } else {
      groups.push({ date: dateStr, messages: [msg] });
    }
    return groups;
  }, []);

  if (status === 'loading' || (isLoading && session)) {
    return (
      <div className="min-h-screen bg-white flex items-center justify-center">
        <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-[#00293d]"></div>
      </div>
    );
  }

  if (!session) return null;

  return (
    <div className="min-h-screen bg-white flex flex-col">
      {/* Header */}
      <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6 w-full">
        <CommonHeader />
      </div>

      {/* Chat Area */}
      <main className="flex-1 max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 pb-8 w-full flex flex-col">
        {/* Chat Header */}
        <div className="border border-[#00293d]/10 rounded-t-[15px] px-6 py-4 flex items-center gap-3 bg-[#e58625]">
          <Image
            src="/assets/icons/chat-icon.svg"
            alt=""
            width={24}
            height={24}
            className="brightness-0 invert"
          />
          <div>
            <h1 className="font-fractul font-bold text-[18px] text-white">
              Support Chat
            </h1>
            <p className="font-serif text-[13px] text-white/70">
              {chat?.status === 'CLOSED' ? 'This chat has been closed' : 'We typically reply within a few minutes'}
            </p>
          </div>
        </div>

        {error ? (
          <div className="flex-1 border-x border-[#00293d]/10 flex items-center justify-center">
            <div className="text-center">
              <p className="font-serif text-[16px] text-red-500 mb-4">{error}</p>
              <button
                onClick={() => window.location.reload()}
                className="font-fractul text-[14px] text-[#e58625] hover:underline"
              >
                Try Again
              </button>
            </div>
          </div>
        ) : (
          <>
            {/* Messages Area */}
            <div
              ref={messagesContainerRef}
              className="flex-1 border-x border-[#00293d]/10 overflow-y-auto px-6 py-4 min-h-[400px] max-h-[500px] bg-[#f9f9f9]"
            >
              {/* Load More */}
              {hasMore && (
                <div className="text-center mb-4">
                  <button
                    onClick={loadMore}
                    disabled={isLoadingMore}
                    className="font-serif text-[13px] text-[#5ba4a4] hover:underline disabled:opacity-50"
                  >
                    {isLoadingMore ? 'Loading...' : 'Load older messages'}
                  </button>
                </div>
              )}

              {messages.length === 0 ? (
                <div className="flex items-center justify-center h-full">
                  <div className="text-center">
                    <Image
                      src="/assets/icons/chat-icon.svg"
                      alt=""
                      width={48}
                      height={48}
                      className="mx-auto mb-4 opacity-30"
                    />
                    <p className="font-fractul font-semibold text-[16px] text-[#00293d]/60 mb-2">
                      Welcome to Support Chat
                    </p>
                    <p className="font-serif text-[14px] text-[#00293d]/40">
                      Send a message to start chatting with our support team
                    </p>
                  </div>
                </div>
              ) : (
                groupedMessages.map((group) => (
                  <div key={group.date}>
                    {/* Date Separator */}
                    <div className="flex items-center gap-3 my-4">
                      <div className="flex-1 h-px bg-[#00293d]/10"></div>
                      <span className="font-serif text-[12px] text-[#00293d]/40">{group.date}</span>
                      <div className="flex-1 h-px bg-[#00293d]/10"></div>
                    </div>

                    {group.messages.map((msg) => {
                      const isOwn = msg.senderId === currentUserId;
                      return (
                        <div
                          key={msg.id}
                          className={`flex mb-3 ${isOwn ? 'justify-end' : 'justify-start'}`}
                        >
                          <div
                            className={`max-w-[75%] rounded-[15px] px-4 py-3 ${
                              isOwn
                                ? 'bg-[#e58625] text-white rounded-br-[4px]'
                                : 'bg-white text-[#00293d] border border-[#00293d]/10 rounded-bl-[4px]'
                            }`}
                          >
                            {!isOwn && (
                              <p className="font-fractul font-semibold text-[12px] text-[#e58625] mb-1">
                                Support Team
                              </p>
                            )}
                            <p className="font-serif text-[14px] leading-relaxed whitespace-pre-wrap break-words">
                              {msg.content}
                            </p>
                            <p
                              className={`font-serif text-[11px] mt-1 ${
                                isOwn ? 'text-white/50' : 'text-[#00293d]/40'
                              }`}
                            >
                              {formatTime(msg.createdAt)}
                            </p>
                          </div>
                        </div>
                      );
                    })}
                  </div>
                ))
              )}

              {/* Typing Indicator */}
              {isTyping && (
                <div className="flex justify-start mb-3">
                  <div className="bg-white border border-[#00293d]/10 rounded-[15px] rounded-bl-[4px] px-4 py-3">
                    <div className="flex gap-1">
                      <span className="w-2 h-2 bg-[#00293d]/30 rounded-full animate-bounce" style={{ animationDelay: '0ms' }}></span>
                      <span className="w-2 h-2 bg-[#00293d]/30 rounded-full animate-bounce" style={{ animationDelay: '150ms' }}></span>
                      <span className="w-2 h-2 bg-[#00293d]/30 rounded-full animate-bounce" style={{ animationDelay: '300ms' }}></span>
                    </div>
                  </div>
                </div>
              )}

              <div ref={messagesEndRef} />
            </div>

            {/* Input Area */}
            <div className="border border-[#00293d]/10 rounded-b-[15px] px-4 py-3 bg-white">
              {chat?.status === 'CLOSED' ? (
                <div className="text-center py-2">
                  <p className="font-serif text-[14px] text-[#00293d]/50">
                    This chat has been closed. Start a new chat from the FAQ page.
                  </p>
                </div>
              ) : (
                <div className="flex items-center gap-3">
                  <input
                    type="text"
                    value={input}
                    onChange={handleInputChange}
                    onKeyDown={(e) => {
                      if (e.key === 'Enter' && !e.shiftKey) {
                        e.preventDefault();
                        handleSend();
                      }
                    }}
                    placeholder="Type your message..."
                    className="flex-1 font-serif text-[14px] text-[#00293d] bg-[#f5f5f5] rounded-[10px] px-4 py-3 outline-none focus:ring-2 focus:ring-[#5ba4a4]/30 placeholder:text-[#00293d]/40"
                    disabled={isSending}
                  />
                  <button
                    onClick={handleSend}
                    disabled={!input.trim() || isSending}
                    className="w-[44px] h-[44px] flex items-center justify-center bg-[#e58625] rounded-[10px] hover:bg-[#d47a1f] transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
                  >
                    {isSending ? (
                      <div className="w-5 h-5 border-2 border-white/30 border-t-white rounded-full animate-spin"></div>
                    ) : (
                      <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
                        <path d="M22 2L11 13" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
                        <path d="M22 2L15 22L11 13L2 9L22 2Z" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
                      </svg>
                    )}
                  </button>
                </div>
              )}
            </div>
          </>
        )}
      </main>

      {/* Footer */}
      <Footer />
    </div>
  );
}
