import { v4 as uuidv4 } from 'uuid';
import { dataStore } from '../data-store/index.js';
import { createModuleLogger } from '../../utils/logger.js';
import type { Message, ConversationHistory } from '../../types/conversation.js';

const log = createModuleLogger('conversation-history');

const DEFAULT_HOURS_BACK = 72;

function createEmptyHistory(characterId: string, userId: number): ConversationHistory {
  return {
    characterId,
    telegramUserId: userId,
    userInfo: { interests: [], notes: [] },
    messages: [],
    lastActivity: new Date().toISOString(),
    totalMessages: 0,
    totalStarsSpent: 0,
  };
}

export class ConversationManager {
  async addMessage(
      characterId: string,
      userId: number,
      role: 'user' | 'assistant',
      content: string,
      metadata?: Message['metadata'],
      photoInfo?: { messageType?: Message['messageType']; imagePath?: string; imageUrl?: string },
    ): Promise<ConversationHistory> {
      let history = await dataStore.getConversationHistory(characterId, userId);
      if (!history) {
        history = createEmptyHistory(characterId, userId);
      }

      const message: Message = {
        id: uuidv4(),
        role,
        content,
        timestamp: new Date().toISOString(),
        ...(metadata ? { metadata } : {}),
        ...(photoInfo?.messageType ? { messageType: photoInfo.messageType } : {}),
        ...(photoInfo?.imagePath ? { imagePath: photoInfo.imagePath } : {}),
        ...(photoInfo?.imageUrl ? { imageUrl: photoInfo.imageUrl } : {}),
      };

      history.messages.push(message);
      history.totalMessages = history.messages.length;
      history.lastActivity = message.timestamp;

      await dataStore.saveConversationHistory(history);
      log.info({ characterId, userId, role, messageId: message.id, messageType: photoInfo?.messageType }, 'Message added');
      return history;
    }


  async getHistory(characterId: string, userId: number): Promise<ConversationHistory | null> {
    return dataStore.getConversationHistory(characterId, userId);
  }

  async getRecentMessages(characterId: string, userId: number, hoursBack: number = DEFAULT_HOURS_BACK): Promise<Message[]> {
    const history = await dataStore.getConversationHistory(characterId, userId);
    if (!history) return [];

    const cutoff = new Date(Date.now() - hoursBack * 60 * 60 * 1000).toISOString();
    return history.messages.filter((m) => m.timestamp >= cutoff);
  }

  async updateUserInfo(
    characterId: string,
    userId: number,
    info: Partial<ConversationHistory['userInfo']>,
  ): Promise<void> {
    let history = await dataStore.getConversationHistory(characterId, userId);
    if (!history) {
      history = createEmptyHistory(characterId, userId);
    }

    if (info.name !== undefined) history.userInfo.name = info.name;
    if (info.interests) {
      const existing = new Set(history.userInfo.interests ?? []);
      for (const i of info.interests) existing.add(i);
      history.userInfo.interests = [...existing];
    }
    if (info.notes) {
      const existing = new Set(history.userInfo.notes ?? []);
      for (const n of info.notes) existing.add(n);
      history.userInfo.notes = [...existing];
    }

    await dataStore.saveConversationHistory(history);
    log.info({ characterId, userId }, 'User info updated');
  }

  async deleteHistory(characterId: string, userId: number): Promise<boolean> {
    const deleted = await dataStore.deleteConversation(characterId, userId);
    if (deleted) {
      log.info({ characterId, userId }, 'Conversation deleted');
    }
    return deleted;
  }
}

export const conversationManager = new ConversationManager();
