import { defineStore } from 'pinia';
import { ref, computed, watch } from 'vue'; // Import watch
import axios from 'boot/axios';

export const useChatStore = defineStore('chat', () => 
{
  const isVisible = ref(false);
  const currentThreadId = ref(null);
  const messages = ref([]); // Array of { sender: 'user' | 'bot', content: string, createdAt?: Date, loading?: boolean }
  const isLoading = ref(false);
  const error = ref(null);
  const pollingIntervalId = ref(null); // To store the interval ID

  // --- Getters ---
  const chatMessages = computed(() => messages.value);
  const isChatVisible = computed(() => isVisible.value);
  const activeThreadId = computed(() => currentThreadId.value);

  // --- Actions ---

  // New action to create a thread if it doesn't exist
  async function createThreadIfNotExists() 
  {
    if (currentThreadId.value) return; // Already have a thread

    isLoading.value = true;
    error.value = null;
    try 
    {
      // Call the endpoint without content to just create the thread
      const response = await axios.post('/api/chat/threads', {});
      currentThreadId.value = response.data.threadId;
      messages.value = []; // Start with an empty message list for the new thread
      console.log('Created new chat thread:', currentThreadId.value);
      // Start polling now that we have a thread ID
      startPolling();
    }
    catch (err) 
    {
      console.error('Error creating chat thread:', err);
      error.value = 'Failed to start chat.';
      // Don't set isVisible to false, let the user see the error
    }
    finally 
    {
      isLoading.value = false;
    }
  }

  function toggleChat() 
  {
    isVisible.value = !isVisible.value;

    if (isVisible.value) 
    {
      if (!currentThreadId.value) 
      {
        // If opening and no thread exists, create one
        createThreadIfNotExists();
      }
      else 
      {
        // If opening and thread exists, fetch messages if empty and start polling
        if (messages.value.length === 0) 
        {
          fetchMessages();
        }
        startPolling();
      }
    }
    else 
    {
      // If closing, stop polling
      stopPolling();
    }
  }

  async function fetchMessages() 
  {
    if (!currentThreadId.value) 
    {
      console.log('No active thread to fetch messages for.');
      // Don't try to fetch if no thread ID yet. createThreadIfNotExists handles the initial state.
      return;
    }
    // Avoid setting isLoading if polling, maybe use a different flag? For now, keep it simple.
    // isLoading.value = true; // Might cause flickering during polling
    error.value = null; // Clear previous errors on fetch attempt
    try 
    {
      const response = await axios.get(`/api/chat/threads/${currentThreadId.value}/messages`);
      const newMessages = response.data.map(msg => ({
        sender: msg.sender,
        content: msg.content,
        createdAt: new Date(msg.createdAt),
        loading: msg.content === 'Loading...'
      })).sort((a, b) => a.createdAt - b.createdAt);

      // Only update if messages have actually changed to prevent unnecessary re-renders
      if (JSON.stringify(messages.value) !== JSON.stringify(newMessages)) 
      {
        messages.value = newMessages;
      }

    }
    catch (err) 
    {
      console.error('Error fetching messages:', err);
      error.value = 'Failed to load messages.';
      // Don't clear messages on polling error, keep the last known state
      // messages.value = [];
      stopPolling(); // Stop polling if there's an error fetching
    }
    finally 
    {
      // isLoading.value = false;
    }
  }

  // Function to start polling
  function startPolling() 
  {
    if (pollingIntervalId.value) return; // Already polling
    if (!currentThreadId.value) return; // No thread to poll for

    console.log('Starting chat polling for thread:', currentThreadId.value);
    pollingIntervalId.value = setInterval(fetchMessages, 5000); // Poll every 5 seconds
  }

  // Function to stop polling
  function stopPolling() 
  {
    if (pollingIntervalId.value) 
    {
      console.log('Stopping chat polling.');
      clearInterval(pollingIntervalId.value);
      pollingIntervalId.value = null;
    }
  }


  async function sendMessage(content) 
  {
    if (!content.trim()) return;
    if (!currentThreadId.value) 
    {
      error.value = 'Cannot send message: No active chat thread.';
      console.error('Attempted to send message without a thread ID.');
      return; // Should not happen if UI waits for thread creation
    }

    const userMessage = {
      sender: 'user',
      content: content.trim(),
      createdAt: new Date(),
    };
    messages.value.push(userMessage);

    const loadingMessage = { sender: 'bot', content: '...', loading: true, createdAt: new Date(Date.now() + 1) }; // Ensure unique key/time
    messages.value.push(loadingMessage);

    // Stop polling temporarily while sending a message to avoid conflicts
    stopPolling();

    isLoading.value = true; // Indicate activity
    error.value = null;

    try 
    {
      const payload = { content: userMessage.content };
      // Always post to the existing thread once it's created
      const response = await axios.post(`/api/chat/threads/${currentThreadId.value}/messages`, payload);

      // Remove loading indicator
      messages.value = messages.value.filter(m => !m.loading);

      // The POST might return the new message, but we'll rely on the next fetchMessages call
      // triggered by startPolling to get the latest state including any potential bot response.

      // Immediately fetch messages after sending to get the updated list
      await fetchMessages();

    }
    catch (err) 
    {
      console.error('Error sending message:', err);
      error.value = 'Failed to send message.';
      // Remove loading indicator on error
      messages.value = messages.value.filter(m => !m.loading);
      // Optionally add an error message to the chat
      // Ensure the object is correctly formatted
      messages.value.push({ sender: 'bot', content: "Sorry, I couldn't send that message.", createdAt: new Date() });
    }
    finally 
    {
      isLoading.value = false;
      // Restart polling after sending attempt is complete
      startPolling();
    }
  }

  // Call this when the user logs out or the app closes if you want to clear state
  function resetChat() 
  {
    stopPolling(); // Ensure polling stops on reset
    isVisible.value = false;
    currentThreadId.value = null;
    messages.value = [];
    isLoading.value = false;
    error.value = null;
  }

  // Watch for visibility changes to manage polling (alternative to putting logic in toggleChat)
  // watch(isVisible, (newValue) => {
  //   if (newValue && currentThreadId.value) {
  //     startPolling();
  //   } else {
  //     stopPolling();
  //   }
  // });

  // Watch for thread ID changes (e.g., after creation)
  // watch(currentThreadId, (newId) => {
  //   if (newId && isVisible.value) {
  //       messages.value = []; // Clear old messages if any
  //       fetchMessages(); // Fetch messages for the new thread
  //       startPolling(); // Start polling for the new thread
  //   } else {
  //       stopPolling(); // Stop polling if thread ID becomes null
  //   }
  // });


  return {
    // State refs
    isVisible,
    currentThreadId,
    messages,
    isLoading,
    error,

    // Computed getters
    chatMessages,
    isChatVisible,
    activeThreadId,

    // Actions
    toggleChat,
    sendMessage,
    fetchMessages, // Expose if needed externally
    resetChat,
    // Expose polling control if needed externally, though typically managed internally
    // startPolling,
    // stopPolling,
  };
});
