/**
 * markdownImporter.ts
 * 
 * Extracts a section of a markdown file from a given heading to the next heading.
 * Ignores headings within fenced code blocks.
 */

import { readFileSync } from 'fs';

export interface MarkdownImportOptions {
  filePath: string;
  heading?: string;
  headingLevelOverride?: string;
  headingTextOverride?: string;
}

export interface MarkdownImportResult {
  content: string;
  headingFound: boolean;
  duplicateHeadings: boolean;
}

export function importMarkdownSection(options: MarkdownImportOptions): MarkdownImportResult {
  const { filePath, heading, headingLevelOverride, headingTextOverride } = options;

  try {
    const content = readFileSync(filePath, 'utf-8');
    
    // If no heading is provided, return the entire file
    if (!heading) {
      return {
        content,
        headingFound: true,
        duplicateHeadings: false
      };
    }

    const lines = content.split('\n');
    const result: MarkdownImportResult = {
      content: '',
      headingFound: false,
      duplicateHeadings: false
    };

    // Track heading locations
    const headingLocations: number[] = [];
    let inCodeBlock = false;

    // Find all matching headings (ignoring those in code blocks)
    for (let i = 0; i < lines.length; i++) {
      const line = lines[i].trim();

      // Track code blocks
      if (line.startsWith('```')) {
        inCodeBlock = !inCodeBlock;
        continue;
      }

      // Skip lines in code blocks
      if (inCodeBlock) continue;

      // Look for headings
      if (line.startsWith('#')) {
        const match = line.match(/^#+\s+(.*)$/);
        if (match && match[1].trim() === heading) {
          headingLocations.push(i);
        }
      }
    }

    // Handle results
    if (headingLocations.length === 0) {
      return result;
    }

    if (headingLocations.length > 1) {
      result.headingFound = true;
      result.duplicateHeadings = true;
      return result;
    }

    result.headingFound = true;

    // Extract content from the heading until the next heading or end of file
    const startLine = headingLocations[0];
    let endLine = lines.length;

    // Find the next heading at the same or higher level
    const currentLevel = lines[startLine].match(/^(#+)/)?.[0].length || 1;
    inCodeBlock = false;

    for (let i = startLine + 1; i < lines.length; i++) {
      const line = lines[i].trim();

      // Track code blocks
      if (line.startsWith('```')) {
        inCodeBlock = !inCodeBlock;
        continue;
      }

      // Skip lines in code blocks
      if (inCodeBlock) continue;

      // Look for next heading at same or higher level
      if (line.startsWith('#')) {
        const nextLevel = line.match(/^(#+)/)?.[0].length || 1;
        // Stop at the next heading of the same or higher level
        if (nextLevel <= currentLevel) {
          endLine = i;
          break;
        }
      }
    }

    // Extract the content and apply heading level and text overrides if specified
    let extractedContent = lines.slice(startLine, endLine).join('\n');
    if (headingLevelOverride || headingTextOverride) {
      // Get the original heading line
      const headingLine = lines[startLine];
      // Get the original heading level markers
      const originalLevel = headingLine.match(/^#+/)?.[0] || '#';
      // Get the new heading text (either override or original)
      const newText = headingTextOverride || heading;
      // Get the new level markers (either override or original)
      const newLevel = headingLevelOverride || originalLevel;
      // Replace the first heading line
      extractedContent = extractedContent.replace(headingLine, `${newLevel} ${newText}`);
    }
    result.content = extractedContent;
    return result;

  } catch (error) {
    if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
      throw new Error('File not found');
    }
    throw error;
  }
} 