import type { ChatMessage } from '@genesislcap/foundation-ai';

/** Max words kept from the first user turn when deriving a session title. */
export const COST_SESSION_TITLE_MAX_WORDS = 10;

/** Hard cap on derived title length (ellipsis included). */
export const COST_SESSION_TITLE_MAX_CHARS = 60;

const ELLIPSIS = '…';

/** Plain text from a chat message `content` field. */
export function getChatMessageText(content: ChatMessage['content']): string {
  return typeof content === 'string' ? content.trim() : '';
}

/**
 * Trim a raw user phrase to a display-friendly session title: first sentence,
 * then word cap, then character cap.
 */
export function truncateCostSessionTitle(text: string): string {
  const normalized = text.replace(/\s+/g, ' ').trim();
  if (!normalized) return '';

  const firstSentence = normalized.split(/\n|[.!?](?:\s|$)/u)[0]?.trim() || normalized;

  const words = firstSentence.split(/\s+/).filter(Boolean);
  let title = words.slice(0, COST_SESSION_TITLE_MAX_WORDS).join(' ');
  if (words.length > COST_SESSION_TITLE_MAX_WORDS) {
    title = `${title}${ELLIPSIS}`;
  }

  if (title.length > COST_SESSION_TITLE_MAX_CHARS) {
    const sliceEnd = COST_SESSION_TITLE_MAX_CHARS - ELLIPSIS.length;
    title = `${title.slice(0, Math.max(0, sliceEnd)).trimEnd()}${ELLIPSIS}`;
  }

  return title;
}

/** First non-empty user message in the thread, shortened for cost history. */
export function deriveCostSessionTitleFromMessages(
  messages: readonly ChatMessage[],
): string | undefined {
  for (const message of messages) {
    if (message.role !== 'user') continue;
    const title = truncateCostSessionTitle(message.content);
    if (title) return title;
  }
  return undefined;
}

export interface ResolveCostSessionTitleInput {
  explicit?: string;
  /** Host-provided label (e.g. Create `projectName`). */
  appTitle?: string;
  messages: readonly ChatMessage[];
  headerTitle?: string;
  fallback?: string;
}

/** Resolve the label stored on a finalized cost session record. */
export function resolveCostSessionTitle(input: ResolveCostSessionTitleInput): string {
  const explicit = input.explicit?.trim();
  if (explicit) return explicit;

  const appTitle = input.appTitle?.trim();
  if (appTitle) return appTitle;

  const fromMessages = deriveCostSessionTitleFromMessages(input.messages);
  if (fromMessages) return fromMessages;

  const header = input.headerTitle?.trim();
  if (header) return header;

  return input.fallback?.trim() || 'Untitled session';
}
