import React, { useState, useEffect, useCallback } from 'react';
import { Chat, Message, ChatState } from './types';
import { createChat, getChats, getMessages, sendMessage, deleteChat } from './services/api';
import ChatSidebar from './components/ChatSidebar';
import ChatWindow from './components/ChatWindow';
import DocumentsModal from './components/DocumentsModal';

const App: React.FC = () => {
  const [state, setState] = useState<ChatState>({
    chats: [],
    activeChat: null,
    messages: [],
    isLoading: false,
    isSending: false,
    error: null,
  });

  const [isDocsModalOpen, setIsDocsModalOpen] = useState(false);

  // Listen for custom event to open docs modal
  useEffect(() => {
    const handleOpenModal = () => setIsDocsModalOpen(true);
    window.addEventListener('open-documents-modal', handleOpenModal);
    return () => window.removeEventListener('open-documents-modal', handleOpenModal);
  }, []);

  // Load chats on mount
  useEffect(() => {
    loadChats();
  }, []);

  // Load all chats from API
  const loadChats = async () => {
    try {
      setState(prev => ({ ...prev, isLoading: true, error: null }));
      const chats = await getChats();
      setState(prev => ({ ...prev, chats, isLoading: false }));
    } catch (err) {
      setState(prev => ({
        ...prev,
        isLoading: false,
        error: err instanceof Error ? err.message : 'Failed to load chats',
      }));
    }
  };

  // Load messages for a chat
  const loadMessages = async (chatId: string) => {
    try {
      setState(prev => ({ ...prev, isLoading: true, error: null }));
      const messages = await getMessages(chatId);
      setState(prev => ({ ...prev, messages, isLoading: false }));
    } catch (err) {
      setState(prev => ({
        ...prev,
        isLoading: false,
        error: err instanceof Error ? err.message : 'Failed to load messages',
      }));
    }
  };

  // Handle selecting a chat
  const handleSelectChat = useCallback(async (chat: Chat) => {
    setState(prev => ({ ...prev, activeChat: chat, messages: [] }));
    await loadMessages(chat.id);
  }, []);

  // Handle creating a new chat
  const handleNewChat = useCallback(async () => {
    try {
      setState(prev => ({ ...prev, isLoading: true, error: null }));
      const chat = await createChat();
      setState(prev => ({
        ...prev,
        chats: [chat, ...prev.chats],
        activeChat: chat,
        messages: [],
        isLoading: false,
      }));
    } catch (err) {
      setState(prev => ({
        ...prev,
        isLoading: false,
        error: err instanceof Error ? err.message : 'Failed to create chat',
      }));
    }
  }, []);

  // Handle deleting a chat
  const handleDeleteChat = useCallback(async (chatId: string) => {
    try {
      await deleteChat(chatId);
      setState(prev => {
        const newChats = prev.chats.filter(c => c.id !== chatId);
        const newActiveChat = prev.activeChat?.id === chatId ? null : prev.activeChat;
        const newMessages = prev.activeChat?.id === chatId ? [] : prev.messages;
        return {
          ...prev,
          chats: newChats,
          activeChat: newActiveChat,
          messages: newMessages,
        };
      });
    } catch (err) {
      setState(prev => ({
        ...prev,
        error: err instanceof Error ? err.message : 'Failed to delete chat',
      }));
    }
  }, []);

  // Handle sending a message
  const handleSendMessage = useCallback(async (content: string) => {
    if (!state.activeChat) return;

    const chatId = state.activeChat.id;

    // Optimistically add user message
    const tempUserMsg: Message = {
      id: `temp-${Date.now()}`,
      chat_id: chatId,
      role: 'user',
      content,
      timestamp: new Date().toISOString(),
    };

    setState(prev => ({
      ...prev,
      messages: [...prev.messages, tempUserMsg],
      isSending: true,
      error: null,
    }));

    try {
      const response = await sendMessage(chatId, content);

      setState(prev => {
        // Replace temp message with real messages
        const messagesWithoutTemp = prev.messages.filter(m => m.id !== tempUserMsg.id);
        const newMessages = [
          ...messagesWithoutTemp,
          response.user_message,
          response.assistant_message,
        ];

        // Update chat title if it changed (first message)
        const updatedChats = prev.chats.map(chat => {
          if (chat.id === chatId && chat.title === 'New Chat') {
            const newTitle = content.length > 50 ? content.slice(0, 50) + '...' : content;
            return { ...chat, title: newTitle };
          }
          return chat;
        });

        // Update active chat title too
        const updatedActiveChat = prev.activeChat && prev.activeChat.title === 'New Chat'
          ? { ...prev.activeChat, title: content.length > 50 ? content.slice(0, 50) + '...' : content }
          : prev.activeChat;

        return {
          ...prev,
          messages: newMessages,
          chats: updatedChats,
          activeChat: updatedActiveChat,
          isSending: false,
        };
      });
    } catch (err) {
      setState(prev => ({
        ...prev,
        messages: prev.messages.filter(m => m.id !== tempUserMsg.id),
        isSending: false,
        error: err instanceof Error ? err.message : 'Failed to send message',
      }));
    }
  }, [state.activeChat]);

  return (
    <div className="h-screen flex bg-gray-100 overflow-hidden">
      {/* Sidebar */}
      <ChatSidebar
        chats={state.chats}
        activeChat={state.activeChat}
        onSelectChat={handleSelectChat}
        onNewChat={handleNewChat}
        onDeleteChat={handleDeleteChat}
        isLoading={state.isLoading}
      />

      {/* Main Chat Area */}
      <ChatWindow
        activeChat={state.activeChat}
        messages={state.messages}
        onSendMessage={handleSendMessage}
        isSending={state.isSending}
        isLoading={state.isLoading}
      />

      {/* Error Toast */}
      {state.error && (
        <div className="fixed bottom-4 right-4 max-w-md bg-red-500 text-white px-6 py-4 rounded-xl shadow-2xl flex items-center gap-3 animate-in slide-in-from-bottom-4 duration-300">
          <svg className="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
          </svg>
          <span className="text-sm font-medium">{state.error}</span>
          <button
            onClick={() => setState(prev => ({ ...prev, error: null }))}
            className="ml-2 hover:bg-red-600 p-1 rounded transition-colors"
          >
            <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
            </svg>
          </button>
        </div>
      )}

      {/* Documents Management Modal */}
      <DocumentsModal
        isOpen={isDocsModalOpen}
        onClose={() => setIsDocsModalOpen(false)}
      />
    </div>
  );
};

export default App;
