/**
 * extractPlaceholders.ts
 * 
 * Extracts placeholders from a markdown file.
 * Placeholders can be:
 * - @cmd[command] - Execute a command
 * - @import[file.md#heading] - Import a section from a markdown file
 * - @import[file.ts:symbol] - Import a symbol from a code file
 * - @import[file.ts:symbol1,symbol2] - Import multiple symbols from a code file
 * - @import[file.md#heading as h2] - Import with heading level override
 * - @import[file.md#heading as h2 "New Title"] - Import with heading level and text override
 */

const CMD_REGEX = /@cmd\[(.*?)\]/g;
const IMPORT_REGEX = /@import\[(?<importSpec>[^\]]*)\](?:\s+as\s+(?<asSpec>[^@\n]+))?/g;
const AS_SPEC_REGEX = /^(?<level>#{1,6}|h[1-6])(?:\s+(?<text>[^"\n]+))?$/;

export interface Placeholder {
  type: 'cmd' | 'import';
  raw: string;
  lineNumber: number;
  command?: string;
  importPath?: string;
  heading?: string;
  importSymbol?: string;
  importSymbolList?: string[];
  headingLevelOverride?: string;
  headingTextOverride?: string;
}

export function extractPlaceholders(content: string): Placeholder[] {
  const placeholders: Placeholder[] = [];
  const lines = content.split('\n');

  lines.forEach((line, index) => {
    const lineNumber = index + 1;
    let lastIndex = 0;

    // Handle all placeholders in order
    const allMatches: { type: 'cmd' | 'import', match: RegExpExecArray }[] = [];
    
    // Find all cmd matches
    CMD_REGEX.lastIndex = 0;
    let cmdMatch: RegExpExecArray | null;
    while ((cmdMatch = CMD_REGEX.exec(line)) !== null) {
      allMatches.push({ type: 'cmd', match: cmdMatch });
    }

    // Find all import matches
    IMPORT_REGEX.lastIndex = 0;
    let importMatch: RegExpExecArray | null;
    while ((importMatch = IMPORT_REGEX.exec(line)) !== null) {
      allMatches.push({ type: 'import', match: importMatch });
    }

    // Sort matches by index
    allMatches.sort((a, b) => a.match.index - b.match.index);

    // Process matches in order
    for (const { type, match } of allMatches) {
      if (type === 'cmd') {
        placeholders.push({
          type: 'cmd',
          raw: match[0],
          command: match[1],
          lineNumber
        });
      } else {
        const rawDirective = match[0];
        const importSpec = match.groups?.importSpec.trim() ?? '';
        const asSpec = match.groups?.asSpec?.trim() ?? '';

        // Parse the as spec to get heading level and text
        let headingLevelOverride: string | undefined;
        let headingTextOverride: string | undefined;
        if (asSpec) {
          console.log('asSpec:', asSpec);
          const asMatch = AS_SPEC_REGEX.exec(asSpec);
          console.log('asMatch:', asMatch);
          if (asMatch?.groups) {
            console.log('asMatch.groups:', asMatch.groups);
            headingLevelOverride = asMatch.groups.level;
            headingTextOverride = asMatch.groups.text;
          }
        }

        // Handle empty import placeholders
        if (!importSpec.trim()) {
          placeholders.push({
            type: 'import',
            raw: rawDirective,
            lineNumber
          });
          continue;
        }

        // Parse the import spec
        let filePath: string;
        let specifier: string | undefined;

        if (importSpec.includes('#')) {
          // Split on the first # only
          const firstHash = importSpec.indexOf('#');
          filePath = importSpec.slice(0, firstHash).trim();
          specifier = importSpec.slice(firstHash + 1).trim();
          console.log('importSpec:', importSpec);
          console.log('filePath:', filePath);
          console.log('specifier:', specifier);
        } else if (importSpec.includes('::')) {
          // Split on the first :: only
          const firstColon = importSpec.indexOf('::');
          filePath = importSpec.slice(0, firstColon).trim();
          specifier = importSpec.slice(firstColon + 2).trim();
          console.log('importSpec:', importSpec);
          console.log('filePath:', filePath);
          console.log('specifier:', specifier);
        } else {
          filePath = importSpec;
        }

        if (!specifier) {
          placeholders.push({
            type: 'import',
            raw: rawDirective,
            lineNumber,
            importPath: filePath
          });
          continue;
        }

        // Check if it's a markdown file or code file
        const isMarkdown = filePath.endsWith('.md');
        if (isMarkdown) {
          // Markdown heading import
          placeholders.push({
            type: 'import',
            raw: rawDirective,
            lineNumber,
            importPath: filePath,
            heading: specifier,
            headingLevelOverride: headingLevelOverride,
            headingTextOverride: headingTextOverride
          });
        } else {
          // Code symbol import
          // Check if it's a list of symbols in brackets
          console.log('specifier:', specifier);
          // Remove the closing bracket if it exists
          if (specifier.endsWith(']')) {
            specifier = specifier.slice(0, -1).trim();
          }
          const symbolMatch = specifier.match(/^\s*\[([^\]]+)\]?\s*$/);
          console.log('symbolMatch:', symbolMatch);
          if (symbolMatch) {
            const symbols = symbolMatch[1].split(',').map(s => s.trim());
            console.log('symbols:', symbols);
            placeholders.push({
              type: 'import',
              raw: rawDirective,
              lineNumber,
              importPath: filePath,
              importSymbolList: symbols
            });
          } else {
            // Single symbol (either myFunction or {interface})
            placeholders.push({
              type: 'import',
              raw: rawDirective,
              lineNumber,
              importPath: filePath,
              importSymbol: specifier.trim()
            });
          }
        }
      }
    }
  });

  return placeholders;
} 