import { MeldDirectiveNode } from './remarkMeldDirectives';
import { Text } from 'mdast';

/**
 * Splits a line of text into an array of either:
 *   - raw text nodes
 *   - meldDirective nodes
 */
export function parseMeldDirective(value: string, file: any): Array<MeldDirectiveNode | Text> {
  const result: Array<MeldDirectiveNode | Text> = [];
  let remaining = value;

  // Match any @cmd[...] or @import[...] pattern, even if malformed
  const directiveRegex = /(@(?:cmd|import)\[(?:[^\[\]]|\[(?:[^\[\]]|\[[^\[\]]*\])*\])*\])/g;

  let match: RegExpExecArray | null;
  let lastIndex = 0;

  while ((match = directiveRegex.exec(remaining)) !== null) {
    const start = match.index;
    const end = start + match[0].length;

    // Add any preceding text as a Text node
    if (start > lastIndex) {
      const textChunk = remaining.slice(lastIndex, start);
      result.push({ type: 'text', value: textChunk });
    }

    // Build the directive node
    const rawDirective = match[0];
    try {
      // Check for malformed directives
      if (!rawDirective.endsWith(']')) {
        throw new Error(`Invalid ${rawDirective.startsWith('@cmd') ? 'command' : 'import'} format`);
      }

      const directiveNode = buildMeldDirectiveNode(rawDirective);
      result.push(directiveNode);
    } catch (err: any) {
      // For malformed directives, preserve the original text and add the error
      result.push({ type: 'text', value: rawDirective });
      result.push({ type: 'text', value: ` Error: ${err.message}` });
    }

    lastIndex = end;
  }

  // Add any trailing text
  if (lastIndex < remaining.length) {
    const textChunk = remaining.slice(lastIndex);
    result.push({ type: 'text', value: textChunk });
  }

  return result;
}

/**
 * Helper that parses the `@cmd[...]` or `@import[...]` line and returns a typed node.
 */
export function buildMeldDirectiveNode(raw: string): MeldDirectiveNode {
  // Check for basic format
  if (!raw.startsWith('@cmd[') && !raw.startsWith('@import[')) {
    throw new Error('Invalid directive format');
  }

  // Check for proper closing bracket
  if (!raw.includes(']')) {
    throw new Error('Invalid directive format - missing closing bracket');
  }

  if (raw.startsWith('@cmd')) {
    if (!raw.includes('[') || !raw.includes(']')) {
      throw new Error('Invalid command format');
    }
    const command = raw.slice('@cmd['.length, raw.indexOf(']')).trim();
    if (!command) {
      throw new Error('Invalid command format');
    }

    return {
      type: 'meldDirective',
      meldType: 'cmd',
      raw,
      data: {
        command
      }
    };
  } else {
    // It's an @import directive
    if (!raw.includes('[') || !raw.includes(']')) {
      throw new Error('Invalid import format');
    }
    const importMatch = raw.match(/^@import\[([^\[\]]*(?:\[[^\[\]]*\][^\[\]]*)*)\](?:\s+as\s+(#{1,6})\s*(?:"([^"]*)")?)?$/);
    console.log('Raw input:', raw);
    console.log('Import match:', importMatch);
    if (!importMatch || !importMatch[1].trim()) {
      throw new Error('Invalid import format');
    }

    const [, inside, headingLevelOverride, headingTextOverride] = importMatch;
    console.log('Inside:', inside);
    console.log('Heading level override:', headingLevelOverride);
    console.log('Heading text override:', headingTextOverride);
    
    // Parse import path and any modifiers
    let importPath = inside;
    let heading: string | undefined;
    let importSymbolList: string[] | undefined;
    let importWholeFile = false;

    // Handle whole file import if no # is present
    if (!inside.includes('#')) {
      importWholeFile = true;
    }
    // Handle symbol imports with braces/brackets
    else {
      const [pathPart, rest] = inside.split('#').map(s => s.trim());
      if (!pathPart || !rest) {
        throw new Error('Invalid import format');
      }
      importPath = pathPart;

      // Handle array of symbols: [symbol1, symbol2]
      if (rest.startsWith('[') && rest.endsWith(']')) {
        const symbolsStr = rest.slice(1, -1);
        importSymbolList = symbolsStr.split(',').map(s => s.trim());
      } 
      // Handle single symbol or brace pattern: {type} or {interface}
      else if (rest.startsWith('{') && rest.endsWith('}')) {
        const symbol = rest.slice(1, -1).trim();
        importSymbolList = [symbol];
      }
      // Handle plain specifier based on file type
      else {
        if (importPath.endsWith('.ts') || importPath.endsWith('.js')) {
          // If the rest starts with [ but doesn't end with ], it's malformed
          if (rest.startsWith('[')) {
            throw new Error('Malformed symbol list - missing closing bracket');
          }
          importSymbolList = [rest];
        } else {
          heading = rest;
        }
      }
    }

    return {
      type: 'meldDirective',
      meldType: 'import',
      raw,
      data: {
        importPath,
        heading,
        headingLevelOverride,
        headingTextOverride,
        importSymbolList,
        importWholeFile
      }
    };
  }
} 