import { promises as fs } from 'fs';
import path from 'path';
import os from 'os';

class SessionManager {
  constructor() {
    // Store sessions in memory with conversation history
    this.sessions = new Map();
    this.maxSessions = 100;
    this.sessionsDir = path.join(os.homedir(), '.gemini', 'sessions');
    this.ready = this.init();
  }

  async init() {
    await this.initSessionsDir();
    await this.loadSessions();
  }

  async initSessionsDir() {
    try {
      await fs.mkdir(this.sessionsDir, { recursive: true });
    } catch (error) {
      // console.error('Error creating sessions directory:', error);
    }
  }

  // Create a new session
  createSession(sessionId, projectPath) {
    const session = {
      id: sessionId,
      projectPath: projectPath,
      messages: [],
      createdAt: new Date(),
      lastActivity: new Date()
    };

    // Evict oldest session from memory if we exceed limit
    if (this.sessions.size >= this.maxSessions) {
      const oldestKey = this.sessions.keys().next().value;
      if (oldestKey) this.sessions.delete(oldestKey);
    }

    this.sessions.set(sessionId, session);
    this.saveSession(sessionId);

    return session;
  }

  // Add a message to session
  addMessage(sessionId, role, content) {
    let session = this.sessions.get(sessionId);

    if (!session) {
      // Create session if it doesn't exist
      session = this.createSession(sessionId, '');
    }

    const message = {
      role: role, // 'user' or 'assistant'
      content: content,
      timestamp: new Date()
    };

    session.messages.push(message);
    session.lastActivity = new Date();

    this.saveSession(sessionId);

    return session;
  }

  // Get session by ID
  getSession(sessionId) {
    return this.sessions.get(sessionId);
  }

  // Get all sessions for a project
  getProjectSessions(projectPath) {
    const sessions = [];

    for (const [id, session] of this.sessions) {
      if (session.projectPath === projectPath) {
        sessions.push({
          id: session.id,
          summary: this.getSessionSummary(session),
          messageCount: session.messages.length,
          lastActivity: session.lastActivity
        });
      }
    }

    return sessions.sort((a, b) =>
      new Date(b.lastActivity) - new Date(a.lastActivity)
    );
  }

  // Get session summary
  getSessionSummary(session) {
    if (session.messages.length === 0) {
      return 'New Session';
    }

    // Find first user message
    const firstUserMessage = session.messages.find(m => m.role === 'user');
    if (firstUserMessage) {
      const content = firstUserMessage.content;
      return content.length > 50 ? content.substring(0, 50) + '...' : content;
    }

    return 'New Session';
  }

  // Build conversation context for Gemini
  buildConversationContext(sessionId, maxMessages = 10) {
    const session = this.sessions.get(sessionId);

    if (!session || session.messages.length === 0) {
      return '';
    }

    // Get last N messages for context
    const recentMessages = session.messages.slice(-maxMessages);

    let context = 'Here is the conversation history:\n\n';

    for (const msg of recentMessages) {
      if (msg.role === 'user') {
        context += `User: ${msg.content}\n`;
      } else {
        context += `Assistant: ${msg.content}\n`;
      }
    }

    context += '\nBased on the conversation history above, please answer the following:\n';

    return context;
  }

  // Prevent path traversal
  _safeFilePath(sessionId) {
    const safeId = String(sessionId).replace(/[/\\]|\.\./g, '');
    return path.join(this.sessionsDir, `${safeId}.json`);
  }

  // Save session to disk
  async saveSession(sessionId) {
    const session = this.sessions.get(sessionId);
    if (!session) return;

    try {
      const filePath = this._safeFilePath(sessionId);
      await fs.writeFile(filePath, JSON.stringify(session, null, 2));
    } catch (error) {
      // console.error('Error saving session:', error);
    }
  }

  // Load sessions from disk
  async loadSessions() {
    try {
      const files = await fs.readdir(this.sessionsDir);

      for (const file of files) {
        if (file.endsWith('.json')) {
          try {
            const filePath = path.join(this.sessionsDir, file);
            const data = await fs.readFile(filePath, 'utf8');
            const session = JSON.parse(data);

            // Convert dates
            session.createdAt = new Date(session.createdAt);
            session.lastActivity = new Date(session.lastActivity);
            session.messages.forEach(msg => {
              msg.timestamp = new Date(msg.timestamp);
            });

            this.sessions.set(session.id, session);
          } catch (error) {
            // console.error(`Error loading session ${file}:`, error);
          }
        }
      }

      // Enforce eviction after loading to prevent massive memory usage
      while (this.sessions.size > this.maxSessions) {
        const oldestKey = this.sessions.keys().next().value;
        if (oldestKey) this.sessions.delete(oldestKey);
      }
    } catch (error) {
      // console.error('Error loading sessions:', error);
    }
  }

  // Delete a session
  async deleteSession(sessionId) {
    this.sessions.delete(sessionId);

    try {
      const filePath = this._safeFilePath(sessionId);
      await fs.unlink(filePath);
    } catch (error) {
      // console.error('Error deleting session file:', error);
    }
  }

  // Get session messages for display
  getSessionMessages(sessionId) {
    const session = this.sessions.get(sessionId);
    if (!session) return [];

    return session.messages.map(msg => ({
      type: 'message',
      message: {
        role: msg.role,
        content: msg.content
      },
      timestamp: msg.timestamp.toISOString()
    }));
  }
}

// Singleton instance
const sessionManager = new SessionManager();

export const ready = sessionManager.ready;
export default sessionManager;