'use strict';

const MESSAGE_ROLES = new Set(['user', 'assistant']);
const RECENT_TURN_LIMIT = 6;

function _text(value) {
  return String(value ?? '').replace(/\s+/g, ' ').trim();
}

function _messageText(message) {
  return _text(message?.text ?? message?.content ?? message?.message ?? '');
}

function _timestampMs(value) {
  if (typeof value === 'number' && Number.isFinite(value)) return value;
  const parsed = Date.parse(String(value || ''));
  return Number.isFinite(parsed) ? parsed : 0;
}

function _timestampIso(value) {
  const ms = _timestampMs(value);
  return ms ? new Date(ms).toISOString() : '';
}

function _cleanUserPrompt(text) {
  const cleaned = _text(text)
    .replace(/<image\b[\s\S]*?<\/image>\s*/gi, '')
    .replace(/\[input_image\]\s*/g, '')
    .trim();
  if (!cleaned) return '';
  if (/^this session is being continued from a previous conversation/i.test(cleaned)) return '';
  return cleaned;
}

function _isAckOnlyPrompt(text) {
  const normalized = _text(text).toLowerCase();
  return /^(ok|okay|yes|yep|go ahead|continue|thanks|thank you|done|sounds good|looks good)$/i.test(normalized);
}

function _isContentRichPrompt(text) {
  const cleaned = _cleanUserPrompt(text);
  if (!cleaned || _isAckOnlyPrompt(cleaned)) return false;
  if (cleaned.length >= 24) return true;
  if (/[$/@#]|https?:\/\/|\b(fix|debug|review|implement|test|commit|merge|explain|why|how|what|where|find|update|design|use)\b/i.test(cleaned)) return true;
  return false;
}

function _promptPayload(entry, source, freshness) {
  if (!entry?.text) return null;
  return {
    text: entry.text,
    source,
    freshness,
    confidence: _isContentRichPrompt(entry.text) ? 'medium' : 'low',
    timestamp: entry.timestamp,
    updatedAt: entry.timestamp,
    isContentRich: _isContentRichPrompt(entry.text),
  };
}

function _summaryActivityMs(summary) {
  if (!summary || typeof summary !== 'object') return 0;
  const values = [
    summary.lastActivity,
    summary.progress?.updatedAt,
    summary.currentTask?.updatedAt,
    summary.currentTask?.timestamp,
    summary.currentTask?.promptTimestamp,
    summary.intent?.updatedAt,
    summary.latestPrompt?.updatedAt,
    summary.latestPrompt?.timestamp,
    summary.displayPrompt?.updatedAt,
    summary.displayPrompt?.timestamp,
    summary.aiSummary?.updatedAt,
  ];
  return values.reduce((latest, value) => Math.max(latest, _timestampMs(value)), 0);
}

function _summaryPromptMs(summary) {
  if (!summary || typeof summary !== 'object') return 0;
  return Math.max(
    _timestampMs(summary.latestPrompt?.timestamp || summary.latestPrompt?.updatedAt),
    _timestampMs(summary.displayPrompt?.timestamp || summary.displayPrompt?.updatedAt),
    _timestampMs(summary.currentTask?.promptTimestamp || summary.currentTask?.timestamp),
    _timestampMs(summary.intent?.timestamp || summary.intent?.updatedAt)
  );
}

function _summaryProgressMs(summary) {
  if (!summary || typeof summary !== 'object') return 0;
  return Math.max(
    _timestampMs(summary.progress?.updatedAt),
    _timestampMs(summary.lastActivity)
  );
}

function _hasPrompt(summary) {
  return !!_text(summary?.latestPrompt?.text || summary?.displayPrompt?.text || summary?.lastPrompt || summary?.currentTask?.text);
}

function _hasProgress(summary) {
  return !!_text(summary?.progress?.summary || summary?.progress?.text || summary?.progress || summary?.summary);
}

function summarizeMessagesForTimeline(messages, options = {}) {
  const source = options.source || 'conversation-timeline';
  const freshness = options.freshness || 'durable';
  const sessionId = String(options.sessionId || '').trim();
  const ctmSessionId = String(options.ctmSessionId || sessionId || '').trim();
  const agentSessionId = String(options.agentSessionId || '').trim() || null;
  const turns = [];

  for (const message of Array.isArray(messages) ? messages : []) {
    const role = String(message?.role || '').trim();
    if (!MESSAGE_ROLES.has(role)) continue;
    const text = role === 'user' ? _cleanUserPrompt(_messageText(message)) : _messageText(message);
    if (!text) continue;
    const timestamp = _timestampMs(message?.timestamp || message?.created_at || message?.createdAt || message?.time);
    const turn = {
      role,
      text,
      timestamp,
      source: message?.source || source,
    };
    turns.push(turn);
  }

  turns.sort((a, b) => {
    if (a.timestamp && b.timestamp && a.timestamp !== b.timestamp) return a.timestamp - b.timestamp;
    if (a.timestamp && !b.timestamp) return -1;
    if (!a.timestamp && b.timestamp) return 1;
    return 0;
  });
  const userEntries = turns.filter(turn => turn.role === 'user');
  const assistantEntries = turns.filter(turn => turn.role === 'assistant');

  const latestUser = userEntries[userEntries.length - 1] || null;
  const displayUser = [...userEntries].reverse().find(entry => _isContentRichPrompt(entry.text)) || latestUser;
  const taskUser = latestUser && _isContentRichPrompt(latestUser.text) ? latestUser : displayUser;
  const latestAssistantAfterTask = [...assistantEntries]
    .reverse()
    .find(entry => !taskUser?.timestamp || !entry.timestamp || entry.timestamp >= taskUser.timestamp)
    || assistantEntries[assistantEntries.length - 1]
    || null;
  const latestActivity = turns.reduce((latest, turn) => Math.max(latest, turn.timestamp || 0), 0);
  const latestPrompt = _promptPayload(latestUser, source, freshness);
  const displayPrompt = _promptPayload(displayUser, source, freshness);
  const currentTask = _promptPayload(taskUser, source, freshness) || {
    text: null,
    source,
    freshness: 'missing',
    confidence: 'low',
    timestamp: 0,
    updatedAt: 0,
    promptTimestamp: 0,
  };
  if (currentTask?.text) {
    currentTask.prompt = currentTask.text;
    currentTask.fullPrompt = currentTask.text;
    currentTask.promptTimestamp = currentTask.timestamp || 0;
  }

  const progress = latestAssistantAfterTask ? {
    phase: '',
    summary: latestAssistantAfterTask.text,
    bullets: [latestAssistantAfterTask.text],
    next: null,
    source,
    updatedAt: latestAssistantAfterTask.timestamp || latestActivity || 0,
  } : {
    phase: '',
    summary: null,
    bullets: [],
    next: null,
    source: 'none',
    updatedAt: 0,
  };

  return {
    sessionId: agentSessionId || sessionId,
    ctmSessionId,
    agentSessionId,
    summary: null,
    summarySource: null,
    lastPrompt: latestPrompt?.text || '',
    displayPrompt: displayPrompt?.text || '',
    latestPrompt,
    currentTask,
    intent: currentTask?.text ? {
      text: currentTask.text,
      source: currentTask.source,
      freshness: currentTask.freshness,
      confidence: currentTask.confidence,
      prompt: currentTask.text,
      fullPrompt: currentTask.text,
      timestamp: currentTask.timestamp || 0,
      updatedAt: currentTask.updatedAt || 0,
    } : null,
    progress,
    recentTurns: turns.slice(-RECENT_TURN_LIMIT).map(turn => ({
      role: turn.role,
      text: turn.text,
      timestamp: turn.timestamp ? _timestampIso(turn.timestamp) : '',
      source: turn.source,
    })),
    turnCount: turns.length,
    lastActivity: latestActivity,
    timelineSource: source,
    timelineFreshness: freshness,
  };
}

function mergeTimelineSummaries(primary, timeline) {
  if (!primary) return timeline || null;
  if (!timeline) return primary || null;

  const merged = { ...primary };
  const primaryPromptMs = _summaryPromptMs(primary);
  const timelinePromptMs = _summaryPromptMs(timeline);
  const timelinePromptWins = timelinePromptMs && (!primaryPromptMs || timelinePromptMs >= primaryPromptMs || !_hasPrompt(primary));
  const primaryAiFresh = primary?.aiSummary?.status === 'fresh'
    && _timestampMs(primary.aiSummary.updatedAt) >= timelinePromptMs;

  if (timelinePromptWins) {
    merged.lastPrompt = timeline.lastPrompt || merged.lastPrompt;
    merged.displayPrompt = timeline.displayPrompt || merged.displayPrompt;
    merged.latestPrompt = timeline.latestPrompt || merged.latestPrompt;
    if (!primaryAiFresh) {
      merged.currentTask = timeline.currentTask || merged.currentTask;
      merged.intent = timeline.intent || merged.intent;
    }
  }

  const primaryProgressMs = _summaryProgressMs(primary);
  const timelineProgressMs = _summaryProgressMs(timeline);
  if (timelineProgressMs && (!primaryProgressMs || timelineProgressMs >= primaryProgressMs || !_hasProgress(primary))) {
    merged.progress = timeline.progress || merged.progress;
  }

  if ((!Array.isArray(primary.recentTurns) || primary.recentTurns.length === 0) && Array.isArray(timeline.recentTurns)) {
    merged.recentTurns = timeline.recentTurns;
  }
  const latestActivity = Math.max(_summaryActivityMs(primary), _summaryActivityMs(timeline));
  if (latestActivity) merged.lastActivity = latestActivity;
  merged.timelineSource = timeline.timelineSource || merged.timelineSource;
  merged.timelineFreshness = timeline.timelineFreshness || merged.timelineFreshness;
  return merged;
}

module.exports = {
  summarizeMessagesForTimeline,
  mergeTimelineSummaries,
  _private: {
    _cleanUserPrompt,
    _isContentRichPrompt,
    _summaryActivityMs,
    _summaryPromptMs,
    _summaryProgressMs,
  },
};
