/**
 * Unified Session Registry
 * Wraps per-provider session maps into a single interface for session management.
 */

import { getActiveClaudeSDKSessions, abortClaudeSDKSession, isClaudeSDKSessionActive } from '../claude-sdk.js';
import { getActiveCursorSessions, abortCursorSession, isCursorSessionActive } from '../cursor-cli.js';
import { getActiveCodexSessions, abortCodexSession, isCodexSessionActive } from '../openai-codex.js';

/**
 * Get all active sessions across all providers for a user.
 * Note: current provider maps are global (not per-user), so we return all.
 * When relay-based sessions are added, userId will be used to filter.
 * @returns {Array<{ sessionId, provider, startTime, status, isProcessing }>}
 */
export function getAllActiveSessions() {
  const sessions = [];

  // Claude SDK sessions — returns array of session IDs
  const claudeIds = getActiveClaudeSDKSessions();
  for (const id of claudeIds) {
    sessions.push({
      sessionId: id,
      provider: 'claude',
      status: isClaudeSDKSessionActive(id) ? 'active' : 'idle',
    });
  }

  // Cursor sessions — returns array of session IDs
  const cursorIds = getActiveCursorSessions();
  for (const id of cursorIds) {
    sessions.push({
      sessionId: id,
      provider: 'cursor',
      status: isCursorSessionActive(id) ? 'active' : 'idle',
    });
  }

  // Codex sessions — returns array of { id, status, startedAt }
  const codexSessions = getActiveCodexSessions();
  for (const s of codexSessions) {
    sessions.push({
      sessionId: s.id,
      provider: 'codex',
      status: s.status === 'running' ? 'active' : s.status,
      startedAt: s.startedAt,
    });
  }

  return sessions;
}

/**
 * Check if a session is active across any provider.
 * @param {string} sessionId
 * @returns {{ active: boolean, provider: string|null }}
 */
export function checkSessionStatus(sessionId) {
  if (isClaudeSDKSessionActive(sessionId)) return { active: true, provider: 'claude' };
  if (isCursorSessionActive(sessionId)) return { active: true, provider: 'cursor' };
  if (isCodexSessionActive(sessionId)) return { active: true, provider: 'codex' };
  return { active: false, provider: null };
}

/**
 * Abort a session by ID, auto-detecting or using specified provider.
 * @param {string} sessionId
 * @param {string} [provider] - Optional: 'claude', 'cursor', 'codex'
 * @returns {Promise<{ aborted: boolean, provider: string|null }>}
 */
export async function abortSession(sessionId, provider) {
  // If provider specified, abort directly
  if (provider) {
    const result = await abortByProvider(sessionId, provider);
    return { aborted: result, provider: result ? provider : null };
  }

  // Auto-detect provider
  if (isClaudeSDKSessionActive(sessionId)) {
    const result = await abortClaudeSDKSession(sessionId);
    return { aborted: result, provider: 'claude' };
  }
  if (isCursorSessionActive(sessionId)) {
    const result = abortCursorSession(sessionId);
    return { aborted: result, provider: 'cursor' };
  }
  if (isCodexSessionActive(sessionId)) {
    const result = abortCodexSession(sessionId);
    return { aborted: result, provider: 'codex' };
  }

  return { aborted: false, provider: null };
}

/**
 * Abort all active sessions.
 * @returns {Promise<Array<{ sessionId, provider, aborted }>>}
 */
export async function abortAllSessions() {
  const all = getAllActiveSessions();
  const results = [];

  for (const s of all) {
    const { aborted } = await abortSession(s.sessionId, s.provider);
    results.push({ sessionId: s.sessionId, provider: s.provider, aborted });
  }

  return results;
}

/**
 * Get session stats summary.
 * @returns {{ total, byProvider: { claude, cursor, codex }, active }}
 */
export function getSessionStats() {
  const sessions = getAllActiveSessions();
  const byProvider = { claude: 0, cursor: 0, codex: 0 };

  for (const s of sessions) {
    byProvider[s.provider] = (byProvider[s.provider] || 0) + 1;
  }

  return {
    total: sessions.length,
    active: sessions.filter(s => s.status === 'active').length,
    byProvider,
  };
}

// -- Internal --

async function abortByProvider(sessionId, provider) {
  switch (provider) {
    case 'claude': return abortClaudeSDKSession(sessionId);
    case 'cursor': return abortCursorSession(sessionId);
    case 'codex': return abortCodexSession(sessionId);
    default: return false;
  }
}
