/**
 * Generates summary and chapters for prompt content.
 *
 * Uses regex-based extraction by default (first sentence + markdown headings).
 * An optional LLM generator can be injected for higher-quality summaries.
 */

const MAX_SUMMARY_WORDS = 20;
const HEADING_RE = /^#{1,6}\s+(.+)$/gm;

export interface LlmSummaryGenerator {
  generate(content: string): Promise<{ summary: string; chapters: string[] }>;
}

export class PromptSummaryService {
  constructor(private readonly llmGenerator: LlmSummaryGenerator | null = null) {}

  async generateSummary(content: string): Promise<{ summary: string; chapters: string[] }> {
    if (this.llmGenerator) {
      try {
        return await this.llmGenerator.generate(content);
      } catch {
        // Fall back to regex on LLM failure
      }
    }
    return this.generateWithRegex(content);
  }

  generateWithRegex(content: string): { summary: string; chapters: string[] } {
    return {
      summary: extractFirstSentence(content, MAX_SUMMARY_WORDS),
      chapters: extractHeadings(content),
    };
  }
}

/**
 * Extract the first sentence, truncated to maxWords.
 * Strips markdown formatting.
 */
export function extractFirstSentence(content: string, maxWords: number): string {
  if (!content.trim()) return '';

  // Skip leading headings and blank lines to find first content line
  const lines = content.split('\n');
  let firstContent = '';
  for (const line of lines) {
    const trimmed = line.trim();
    if (!trimmed) continue;
    if (trimmed.startsWith('#')) continue;
    firstContent = trimmed;
    break;
  }

  if (!firstContent) {
    // All lines are headings or empty — use first heading text
    for (const line of lines) {
      const trimmed = line.trim();
      if (trimmed.startsWith('#')) {
        firstContent = trimmed.replace(/^#+\s*/, '');
        break;
      }
    }
  }

  if (!firstContent) return '';

  // Strip basic markdown formatting
  firstContent = firstContent
    .replace(/\*\*(.+?)\*\*/g, '$1')
    .replace(/\*(.+?)\*/g, '$1')
    .replace(/`(.+?)`/g, '$1')
    .replace(/\[(.+?)\]\(.+?\)/g, '$1');

  // Split on sentence boundaries
  const sentenceEnd = firstContent.search(/[.!?]\s|[.!?]$/);
  const sentence = sentenceEnd >= 0 ? firstContent.slice(0, sentenceEnd + 1) : firstContent;

  // Truncate to maxWords
  const words = sentence.split(/\s+/);
  if (words.length <= maxWords) return sentence;
  return words.slice(0, maxWords).join(' ') + '...';
}

/**
 * Extract markdown headings as chapter titles.
 */
export function extractHeadings(content: string): string[] {
  const headings: string[] = [];
  let match: RegExpExecArray | null;
  while ((match = HEADING_RE.exec(content)) !== null) {
    const heading = match[1]!.trim();
    if (heading) headings.push(heading);
  }
  return headings;
}
