import { readFileSync } from 'fs';
import { dirname } from 'path';
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkStringify, { Options } from 'remark-stringify';
import { remarkMeldDirectives } from './plugins/remarkMeldDirectives';
import { remarkProcessMeldNodes } from './plugins/remarkProcessMeldNodes';
import { remarkMeldDirectiveHandler } from './plugins/remarkMeldDirectiveHandler';

export interface MeldOptions {
  inputPath: string;
  workspacePath: string;
  outputFile?: string;
  dryRun?: boolean;
  debug?: boolean;
}

export interface MeldResult {
  content: string;
  errors: string[];
}

export async function processMeldFile(options: MeldOptions): Promise<MeldResult> {
  const { inputPath, workspacePath, debug } = options;

  try {
    const content = readFileSync(inputPath, 'utf-8');
    
    // Process the file through our remark pipeline
    const file = await unified()
      .use(remarkParse)
      .use(() => (tree) => {
        if (debug) console.log('After parse:', JSON.stringify(tree, null, 2));
        return tree;
      })
      .use(remarkMeldDirectives)
      .use(() => (tree) => {
        if (debug) console.log('After meldDirectives:', JSON.stringify(tree, null, 2));
        return tree;
      })
      .use(remarkProcessMeldNodes, { currentFileDir: dirname(inputPath), debug })
      .use(() => (tree) => {
        if (debug) console.log('After processMeldNodes:', JSON.stringify(tree, null, 2));
        return tree;
      })
      .use(remarkMeldDirectiveHandler)
      .use(() => (tree) => {
        if (debug) console.log('After meldDirectiveHandler:', JSON.stringify(tree, null, 2));
        return tree;
      })
      .use(remarkStringify, {
        // Disable escaping and other markdown processing
        entities: false,
        bullet: '-',
        fence: '`',
        fences: true,
        incrementListMarker: true,
        rule: '-',
        ruleRepetition: 3,
        ruleSpaces: false,
        setext: false,
        quote: '"',
        strong: '*',
        emphasis: '_'
      } as Options)
      .process(content);

    const meldErrors = (file.data as any).meldErrors || [];

    // Clean up any double newlines and trailing whitespace
    let processedContent = String(file);
    processedContent = processedContent.split('\n').map(line => line.trimRight()).join('\n');
    processedContent = processedContent.replace(/\n{3,}/g, '\n\n');
    processedContent = processedContent.replace(/\n+$/, '\n');

    return {
      content: processedContent,
      errors: meldErrors
    };

  } catch (error) {
    if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
      return {
        content: '',
        errors: ['Input file not found']
      };
    }
    return {
      content: '',
      errors: [`Error processing file: ${(error as Error).message}`]
    };
  }
}

export class Meld {
  private options: MeldOptions;

  constructor(options: MeldOptions) {
    this.options = options;
  }

  async process(): Promise<MeldResult> {
    return processMeldFile(this.options);
  }
} 