/**
 * Copyright (c) 2024-2026 Тарабанов Александр Викторович
 * All rights reserved.
 * 
 * This software is proprietary and confidential.
 * Unauthorized copying, modification, or distribution is prohibited.
 * 
 * For licensing inquiries: info@hb3-accelerator.com
 * Website: https://hb3-accelerator.com
 * GitHub: https://github.com/VC-HB3-Accelerator
 */

import { ref, computed, watch, onMounted, onUnmounted } from 'vue';
import api from '../api/axios';
import { getFromStorage, setToStorage, removeFromStorage } from '../utils/storage';
import { generateUniqueId } from '../utils/helpers';
import websocketModule from '../services/websocketService';
import { getPublicMessages } from '../services/messagesService';

const { websocketService } = websocketModule;

function initGuestId() {
  let id = getFromStorage('guestId', '');
  if (!id) {
    id = generateUniqueId();
    setToStorage('guestId', id);
  }
  return id;
}

export function useChat(auth) {
  const messages = ref([]);
  const newMessage = ref('');
  const attachments = ref([]); // Теперь это массив File объектов
  const userLanguage = ref('ru');
  const isLoading = ref(false); // Общая загрузка (например, при отправке)
  const hasUserSentMessage = ref(getFromStorage('hasUserSentMessage') === true);

  const messageLoading = ref({
    isLoadingHistory: false, // Загрузка истории
    hasMoreMessages: false,
    offset: 0,
    limit: 30,
    isHistoryLoadingInProgress: false, // Флаг для предотвращения параллельных запросов истории
    isLinkingGuest: false, // Флаг для процесса связывания гостевых сообщений (пока не используется активно)
  });

  const guestId = ref(initGuestId());

  // Сохраняем ссылки на callback функции WebSocket для правильной отписки
  const wsCallbacks = {
    chatMessage: null,
    conversationUpdated: null,
    connected: null,
    disconnected: null,
    error: null
  };

  const shouldLoadHistory = computed(() => {
    return auth.isAuthenticated.value || !!guestId.value;
  });

  // --- Загрузка истории --- 
  const loadMessages = async (options = {}) => {
    const { silent = false, initial = false, authType = null } = options;

    if (messageLoading.value.isHistoryLoadingInProgress) {
      // console.warn('[useChat] Загрузка истории уже идет, пропуск.');
      return;
    }
    messageLoading.value.isHistoryLoadingInProgress = true;

    // Если initial=true, сбрасываем offset и hasMoreMessages
    if (initial) {
        // console.log('[useChat] Начальная загрузка истории...');
        messageLoading.value.offset = 0;
        messageLoading.value.hasMoreMessages = false;
        messages.value = []; // Очищаем текущие сообщения перед начальной загрузкой
    }

    // Не загружаем больше, если уже грузим или больше нет
    if (!initial && (!messageLoading.value.hasMoreMessages || messageLoading.value.isLoadingHistory)) {
      messageLoading.value.isHistoryLoadingInProgress = false;
      return;
    }

    messageLoading.value.isLoadingHistory = true;
    if (!silent && initial) isLoading.value = true; // Показываем общий лоадер только при начальной загрузке

    // console.log(
    //   `[useChat] Загрузка истории сообщений (initial: ${initial}, authType: ${authType}, offset: ${messageLoading.value.offset})...`
    // );

    try {
        // --- Логика ожидания привязки гостя (упрощенная) --- 
        // TODO: Рассмотреть более надежный механизм, если это необходимо
        if (authType) {
            // console.log(`[useChat] Ожидание после ${authType} аутентификации...`);
            await new Promise((resolve) => setTimeout(resolve, 1500)); // Увеличена задержка
            // console.log('[useChat] Ожидание завершено, продолжаем загрузку истории.');
        }
        // --- Конец логики ожидания --- 

        // Определяем, нужно ли запрашивать count
        let totalMessages = -1;
        if (initial || messageLoading.value.offset === 0) {
             try {
                // Получаем количество личных сообщений с ИИ
                const personalCountResponse = await api.get('/chat/history', { params: { count_only: true } });
                const personalCount = personalCountResponse.data.success ? (personalCountResponse.data.total || 0) : 0;
                
                // Получаем количество публичных сообщений
                const publicCountResponse = await api.get('/messages/public', { params: { count_only: true } });
                const publicCount = publicCountResponse.data.success ? (publicCountResponse.data.total || 0) : 0;
                
                totalMessages = personalCount + publicCount;
                // console.log(`[useChat] Всего сообщений в истории: ${totalMessages} (личные: ${personalCount}, публичные: ${publicCount})`);
             } catch(countError) {
                 // console.error('[useChat] Ошибка получения количества сообщений:', countError);
                 // Не прерываем выполнение, попробуем загрузить без total
             }
        }

        let effectiveOffset = messageLoading.value.offset;
        // Если это первая загрузка и мы знаем total, рассчитаем смещение для последних сообщений
        if (initial && totalMessages > 0 && totalMessages > messageLoading.value.limit) {
            effectiveOffset = Math.max(0, totalMessages - messageLoading.value.limit);
            // console.log(`[useChat] Рассчитано начальное смещение: ${effectiveOffset}`);
        }

        // Загружаем личные сообщения с ИИ
        const personalResponse = await api.get('/chat/history', { 
            params: { 
                offset: effectiveOffset, 
                limit: messageLoading.value.limit 
            } 
        });
        
        // Загружаем публичные сообщения от других пользователей
        const publicResponse = await api.get('/messages/public', { 
            params: { 
                offset: 0, 
                limit: 50 
            } 
        });
        
        // Объединяем сообщения
        let allMessages = [];
        if (personalResponse.data.success && personalResponse.data.messages) {
            allMessages = [...allMessages, ...personalResponse.data.messages];
        }
        if (publicResponse.data.success && publicResponse.data.messages) {
            allMessages = [...allMessages, ...publicResponse.data.messages];
        }
        
        // Сортируем по времени создания
        allMessages.sort((a, b) => new Date(a.created_at) - new Date(b.created_at));
        
        const response = {
            data: {
                success: true,
                messages: allMessages,
                total: allMessages.length
            }
        };

        if (response.data.success && response.data.messages) {
            const loadedMessages = response.data.messages;
            const totalFromResponse = response.data.total;
            // console.log(`[useChat] Загружено ${loadedMessages.length} сообщений.`);

            if (loadedMessages.length > 0) {
                // Добавляем к существующим (в начало для истории, в конец для начальной загрузки)
                 if (initial) {
                    messages.value = loadedMessages;
                 } else {
                    messages.value = [...loadedMessages, ...messages.value];
                 }
                
                // Обновляем смещение для следующей загрузки
                // Если загружали последние, offset = total - limit + loaded
                if (initial && totalFromResponse > 0 && effectiveOffset > 0) {
                   messageLoading.value.offset = effectiveOffset + loadedMessages.length;
                } else {
                   messageLoading.value.offset += loadedMessages.length;
                }
                 // console.log(`[useChat] Новое смещение: ${messageLoading.value.offset}`);

                // Проверяем, есть ли еще сообщения для загрузки
                // Используем totalFromResponse из нового API
                if (totalFromResponse >= 0) {
                     messageLoading.value.hasMoreMessages = messageLoading.value.offset < totalFromResponse;
                } else {
                    // Если total не известен, используем hasMore из ответа
                     messageLoading.value.hasMoreMessages = response.data.hasMore || false;
                }
                 // console.log(`[useChat] Есть еще сообщения: ${messageLoading.value.hasMoreMessages}`);
            } else {
                // Если сообщений не пришло, значит, больше нет
                messageLoading.value.hasMoreMessages = false;
            }

            // Очищаем гостевые данные после успешной аутентификации и загрузки
            if (authType) {
                removeFromStorage('guestMessages');
                // removeFromStorage('guestId'); // Удаление guestId теперь только после успешного связывания
                guestId.value = '';
            }

            // Считаем, что пользователь отправлял сообщение, если история не пуста
            if (messages.value.length > 0) {
                hasUserSentMessage.value = true;
                setToStorage('hasUserSentMessage', true);
            }

        } else {
            // console.error('[useChat] API вернул ошибку при загрузке истории:', response.data.error);
             messageLoading.value.hasMoreMessages = false; // Считаем, что больше нет при ошибке
        }
    } catch (error) {
      // console.error('[useChat] Ошибка загрузки истории сообщений:', error);
      messageLoading.value.hasMoreMessages = false; // Считаем, что больше нет при ошибке
    } finally {
      messageLoading.value.isLoadingHistory = false;
      messageLoading.value.isHistoryLoadingInProgress = false;
      if (initial) isLoading.value = false;
    }
  };

  // --- Отправка сообщения --- 
  const handleSendMessage = async (payload) => {
    // --- НАЧАЛО ДОБАВЛЕННЫХ ЛОГОВ ---
    // console.log('[useChat] handleSendMessage called. Payload:', payload);
    // console.log('[useChat] Current auth state:', {
    //     isAuthenticated: auth.isAuthenticated.value,
    //     userId: auth.userId.value,
    //     authType: auth.authType.value,
    // });
    // --- КОНЕЦ ДОБАВЛЕННЫХ ЛОГОВ ---

    const { message: text, attachments: files } = payload; // files - массив File объектов
    const userMessageContent = text.trim();

    // Проверка на пустое сообщение (если нет ни текста, ни файлов)
    if (!userMessageContent && (!files || files.length === 0)) {
        // console.warn('[useChat] Попытка отправить пустое сообщение.');
        return;
    }

    isLoading.value = true;
    const tempId = generateUniqueId();
    const isGuestMessage = !auth.isAuthenticated.value;

    // Создаем локальное сообщение для отображения
    const userMessage = {
        id: tempId,
        content: userMessageContent || `[${files.length} вложений]`, // Отображение для UI
        sender_type: 'user',
        role: 'user',
        isLocal: true,
        isGuest: isGuestMessage,
        timestamp: new Date().toISOString(),
        // Генерируем инфо для отображения в Message.vue (без File объектов)
        attachments: files ? files.map(f => ({ 
            originalname: f.name,
            size: f.size,
            mimetype: f.type,
            // url: URL.createObjectURL(f) // Можно создать временный URL для превью, если Message.vue его использует
        })) : [],
        hasError: false
    };
    messages.value.push(userMessage);

    // Очистка ввода происходит в ChatInterface
    // newMessage.value = '';
    // attachments.value = [];

    try {
        const formData = new FormData();
        formData.append('message', userMessageContent);
        formData.append('language', userLanguage.value);

        if (files && files.length > 0) {
            files.forEach((file) => {
                formData.append('attachments', file, file.name);
            });
        }

        let apiUrl = '/chat/message';
        if (isGuestMessage) {
            if (!guestId.value) {
                guestId.value = initGuestId();
                setToStorage('guestId', guestId.value);
            }
            formData.append('guestId', guestId.value);
            apiUrl = '/chat/guest-message';
        }

        const response = await api.post(apiUrl, formData, {
            headers: {
                // Content-Type устанавливается браузером для FormData
            }
        });

        const userMsgIndex = messages.value.findIndex((m) => m.id === tempId);

        if (response.data.success) {
             // console.log('[useChat] Сообщение успешно отправлено:', response.data);
             // Обновляем локальное сообщение данными с сервера
             if (userMsgIndex !== -1) {
                const serverUserMessage = response.data.userMessage || { id: response.data.messageId };
                messages.value[userMsgIndex].id = serverUserMessage.id || tempId; // Используем серверный ID
                messages.value[userMsgIndex].isLocal = false;
                messages.value[userMsgIndex].timestamp = serverUserMessage.created_at || new Date().toISOString();
                // Опционально: обновить content/attachments с сервера, если они отличаются
             }

            // Добавляем ответ ИИ, если есть
            // Системное сообщение о согласиях уже включено в ответ ИИ
            if (response.data.aiResponse) {
                messages.value.push({
                    id: `ai_${Date.now()}`,
                    content: response.data.aiResponse.response || response.data.aiResponse,
                    sender_type: 'assistant',
                    role: 'assistant',
                    timestamp: new Date().toISOString(),
                    isLocal: false,
                    // Добавляем информацию о согласиях, если есть
                    consentRequired: response.data.consentRequired || false,
                    missingConsents: response.data.missingConsents || [],
                    consentDocuments: response.data.consentDocuments || [],
                    autoConsentOnReply: response.data.autoConsentOnReply || false
                });
            }

            // Добавляем системное сообщение для гостя (только если нет согласия, чтобы не дублировать)
            if (isGuestMessage && response.data.systemMessage && !response.data.consentRequired) {
                messages.value.push({
                    id: `system-${Date.now()}`,
                    content: response.data.systemMessage,
                    sender_type: 'system',
                    role: 'system',
                    timestamp: new Date().toISOString(),
                    isSystem: true,
                    telegramBotUrl: response.data.telegramBotUrl,
                    supportEmail: response.data.supportEmail
                });
            }

            // Сохраняем гостевое сообщение (если нужно)
            if (isGuestMessage) {
                try {
                    const storedMessages = getFromStorage('guestMessages', []);
                    // Добавляем сообщение пользователя (с серверным ID)
                    storedMessages.push({
                        id: messages.value[userMsgIndex].id,
                        content: userMessageContent,
                        sender_type: 'user',
                        role: 'user',
                        isGuest: true,
                        timestamp: messages.value[userMsgIndex].timestamp,
                        attachmentsInfo: messages.value[userMsgIndex].attachments // Сохраняем инфо о файлах
                    });
                    setToStorage('guestMessages', storedMessages);
                } catch (storageError) {
                    // console.error('[useChat] Ошибка сохранения гостевого сообщения в localStorage:', storageError);
                }
            }

            hasUserSentMessage.value = true;
            setToStorage('hasUserSentMessage', true);

        } else {
            throw new Error(response.data.error || 'Ошибка отправки сообщения от API');
        }

    } catch (error) {
        // console.error('[useChat] Ошибка отправки сообщения:', error);
        const userMsgIndex = messages.value.findIndex((m) => m.id === tempId);
        if (userMsgIndex !== -1) {
            messages.value[userMsgIndex].hasError = true;
            messages.value[userMsgIndex].isLocal = false; // Убираем статус "отправка"
        }
        // Добавляем системное сообщение об ошибке
        messages.value.push({
            id: `error-${Date.now()}`,
            content: 'Произошла ошибка при отправке сообщения. Пожалуйста, попробуйте еще раз.',
            sender_type: 'system',
            role: 'system',
            timestamp: new Date().toISOString(),
        });
    } finally {
        isLoading.value = false;
    }
  };

  // --- Управление гостевыми сообщениями --- 
  const loadGuestMessagesFromStorage = () => {
      if (!auth.isAuthenticated.value && guestId.value) {
          try {
              const storedMessages = getFromStorage('guestMessages');
              if (storedMessages && Array.isArray(storedMessages) && storedMessages.length > 0) {
                  // console.log(`[useChat] Найдено ${storedMessages.length} сохраненных гостевых сообщений`);
                  // Добавляем только если текущий список пуст (чтобы не дублировать при HMR)
                  if(messages.value.length === 0) {
                     messages.value = storedMessages.map(m => ({ ...m, isGuest: true })); // Помечаем как гостевые
                     hasUserSentMessage.value = true;
                  }
              }
          } catch (e) {
              // console.error('[useChat] Ошибка загрузки гостевых сообщений из localStorage:', e);
              removeFromStorage('guestMessages'); // Очистить при ошибке парсинга
          }
      }
  };

  // --- Связывание гостевых сообщений после аутентификации ---
  const linkGuestMessagesAfterAuth = async () => {
    if (!guestId.value) return;
    try {
      const response = await api.post('/chat/process-guest', { guestId: guestId.value });
      if (response.data.success && response.data.conversationId) {
        // Можно сразу загрузить историю по этому диалогу, если нужно
        await loadMessages({ initial: true });
        // Удаляем guestId только после успешного связывания
        removeFromStorage('guestId');
        guestId.value = '';
      }
    } catch (error) {
      // console.error('[useChat] Ошибка связывания гостевых сообщений:', error);
      }
  };

  // --- Watchers --- 
  // Сортировка сообщений при изменении
  watch(messages, (newMessages) => {
    // Сортируем только если массив изменился
    if (newMessages.length > 1) {
       messages.value.sort((a, b) => {
         const dateA = new Date(a.timestamp || a.created_at || 0);
         const dateB = new Date(b.timestamp || b.created_at || 0);
         return dateA - dateB;
       });
    }
  }, { deep: false }); // deep: false т.к. нас интересует только добавление/удаление элементов

 // Сброс чата при выходе пользователя
 watch(() => auth.isAuthenticated.value, (isAuth, wasAuth) => {
     if (!isAuth && wasAuth) { // Если пользователь разлогинился
         // console.log('[useChat] Пользователь вышел, сброс состояния чата.');
         messages.value = [];
         messageLoading.value.offset = 0;
         messageLoading.value.hasMoreMessages = false;
         hasUserSentMessage.value = false;
         newMessage.value = '';
         attachments.value = [];
         // Отключаем WebSocket
         cleanupWebSocket();
         // Гостевые данные очищаются при успешной аутентификации в loadMessages
         // или если пользователь сам очистит localStorage
     } else if (isAuth && !wasAuth) { // Если пользователь вошел
         // console.log('[useChat] Пользователь вошел, подключаем WebSocket.');
         // Отложенное подключение, чтобы дождаться загрузки данных пользователя
         setTimeout(() => setupChatWebSocket(), 100);
     }
 });

 // Отслеживаем загрузку данных пользователя для подключения WebSocket
 watch(() => auth.user?.value, (newUser, oldUser) => {
     if (newUser && newUser.id && auth.isAuthenticated.value) {
         // console.log('[useChat] Данные пользователя загружены, подключаем WebSocket:', newUser.id);
         setupChatWebSocket();
     }
 }, { immediate: false });

  // --- WebSocket для real-time сообщений ---
  function setupChatWebSocket() {
    // Подключаемся к WebSocket только если пользователь аутентифицирован
    if (auth.isAuthenticated.value && auth.user && auth.user.value && auth.user.value.id) {
      // console.log('[useChat] Подключение к WebSocket для пользователя:', auth.user.value.id);
      websocketService.connect(auth.user.value.id);
      
      // Создаем и сохраняем callback функции
      wsCallbacks.chatMessage = (message) => {
        // console.log('[useChat] Получено новое сообщение через WebSocket:', message);
        // Проверяем, что сообщение не дублируется
        const existingMessage = messages.value.find(m => m.id === message.id);
        if (!existingMessage) {
          messages.value.push(message);
        }
      };
      
      wsCallbacks.conversationUpdated = (conversationId) => {
        // console.log('[useChat] Обновление диалога через WebSocket:', conversationId);
        // Можно добавить логику обновления списка диалогов
      };
      
      wsCallbacks.connected = () => {
        // console.log('[useChat] WebSocket подключен');
      };
      
      wsCallbacks.disconnected = () => {
        // console.log('[useChat] WebSocket отключен');
      };
      
      wsCallbacks.error = (error) => {
        // console.error('[useChat] WebSocket ошибка:', error);
      };
      
      // Подписываемся на события
      websocketService.on('chat-message', wsCallbacks.chatMessage);
      websocketService.on('conversation-updated', wsCallbacks.conversationUpdated);
      websocketService.on('connected', wsCallbacks.connected);
      websocketService.on('disconnected', wsCallbacks.disconnected);
      websocketService.on('error', wsCallbacks.error);
    } else {
      // console.log('[useChat] WebSocket не подключен: пользователь не аутентифицирован или данные не загружены');
    }
  }
  
  function cleanupWebSocket() {
    // Отписываемся от всех событий, передавая те же callback функции
    if (websocketService) {
      if (wsCallbacks.chatMessage) {
        websocketService.off('chat-message', wsCallbacks.chatMessage);
      }
      if (wsCallbacks.conversationUpdated) {
        websocketService.off('conversation-updated', wsCallbacks.conversationUpdated);
      }
      if (wsCallbacks.connected) {
        websocketService.off('connected', wsCallbacks.connected);
      }
      if (wsCallbacks.disconnected) {
        websocketService.off('disconnected', wsCallbacks.disconnected);
      }
      if (wsCallbacks.error) {
        websocketService.off('error', wsCallbacks.error);
      }
      websocketService.disconnect();
      
      // Очищаем ссылки на callback функции
      Object.keys(wsCallbacks).forEach(key => {
        wsCallbacks[key] = null;
      });
    }
  }

  // --- Инициализация --- 
  onMounted(() => {
    if (!auth.isAuthenticated.value && guestId.value) {
      loadGuestMessagesFromStorage();
    } else if (auth.isAuthenticated.value) {
      loadMessages({ initial: true });
    }
    
    // Подключаем WebSocket если пользователь уже аутентифицирован
    setupChatWebSocket();
    
    // Логика обновления данных централизована в useAuth.js
  });
  
  onUnmounted(() => {
    cleanupWebSocket();
  });

    // Подписываемся на централизованные события очистки и обновления данных
    window.addEventListener('clear-application-data', () => {
      console.log('[useChat] Clearing chat data');
      // Очищаем данные при выходе из системы
      messages.value = [];
    });
    
    window.addEventListener('refresh-application-data', () => {
      console.log('[useChat] Refreshing chat data');
      loadMessages({ initial: true }); // Обновляем данные при входе в систему
    });

  return {
    messages,
    newMessage,     // v-model
    attachments,    // v-model
    isLoading,
    messageLoading, // Содержит isLoadingHistory и hasMoreMessages
    userLanguage,
    hasUserSentMessage,
    loadMessages,
    handleSendMessage,
    loadGuestMessagesFromStorage, // Экспортируем на всякий случай
    linkGuestMessagesAfterAuth,   // Экспортируем для вызова после авторизации
  };
} 