import { YAMLNode, CSVOptions, AnyObject } from './types';

export function parseYAML(content: string): AnyObject {
  const lines = content.split('\n');
  const root: AnyObject = {};
  let currentNode: AnyObject = root;
  let stack: [AnyObject, number][] = [[root, -1]];

  for (const line of lines) {
    if (!line.trim() || line.trim().startsWith('#')) continue;

    const indent = line.search(/\S/);
    const [key, ...valueParts] = line.trim().split(':');
    let value = valueParts.join(':').trim();

    while (stack.length > 1 && stack[stack.length - 1][1] >= indent) {
      stack.pop();
    }
    currentNode = stack[stack.length - 1][0];

    if (value) {
      if (value.startsWith('[') && value.endsWith(']')) {
        currentNode[key] = value.slice(1, -1).split(',').map(v => v.trim());
      } else if (value.toLowerCase() === 'true') {
        currentNode[key] = true;
      } else if (value.toLowerCase() === 'false') {
        currentNode[key] = false;
      } else if (value === 'null') {
        currentNode[key] = null;
      } else if (!isNaN(Number(value))) {
        currentNode[key] = Number(value);
      } else {
        currentNode[key] = value.replace(/^["']|["']$/g, '');
      }
    } else {
      currentNode[key] = {};
      stack.push([currentNode[key] as AnyObject, indent]);
    }
  }

  return root;
}

export function parseCSV(content: string, options: CSVOptions): AnyObject[] {
  const lines = content.split('\n').filter(line => line.trim());
  const delimiter = options.delimiter || ',';
  const result: AnyObject[] = [];

  const headers = options.headers
    ? lines[0].split(delimiter).map(header => header.trim())
    : Array.from({ length: lines[0].split(delimiter).length }, (_, i) => `column${i + 1}`);

  const dataLines = options.headers ? lines.slice(1) : lines;

  for (const line of dataLines) {
    const values = line.split(delimiter).map(value => {
      value = value.trim();
      if (value.startsWith('"') && value.endsWith('"')) {
        return value.slice(1, -1);
      }
      if (value === 'null') {
        return null;
      }
      if (value === '') {
        return value;
      }
      if (!isNaN(Number(value))) {
        return Number(value);
      }
      if (value.toLowerCase() === 'true') {
        return true;
      }
      if (value.toLowerCase() === 'false') {
        return false;
      }
      return value;
    });

    const row: AnyObject = {};
    headers.forEach((header, index) => {
      row[header] = values[index];
    });
    result.push(row);
  }

  return result;
}

export function stringifyYAML(obj: AnyObject, indent = 0): string {
  let result = '';
  const spaces = ' '.repeat(indent);

  for (const [key, value] of Object.entries(obj)) {
    if (value === null || value === undefined) {
      result += `${spaces}${key}:\n`;
    } else if (value === '') {
      result += `${spaces}${key}: ""\n`;
    } else if (Array.isArray(value)) {
      result += `${spaces}${key}: [${value.join(', ')}]\n`;
    } else if (typeof value === 'object') {
      result += `${spaces}${key}:\n${stringifyYAML(value as AnyObject, indent + 2)}`;
    } else if (typeof value === 'string' && value.includes('\n')) {
      result += `${spaces}${key}: |\n${value.split('\n').map(line => `${spaces}  ${line}`).join('\n')}\n`;
    } else {
      result += `${spaces}${key}: ${value}\n`;
    }
  }

  return result;
}

export function stringifyCSV(objects: AnyObject[], options: CSVOptions): string {
  const delimiter = options.delimiter || ',';
  const headers = options.headers
    ? Object.keys(objects[0])
    : Array.from({ length: Object.keys(objects[0]).length }, (_, i) => `column${i + 1}`);

  let result = options.headers ? headers.join(delimiter) + '\n' : '';

  for (const obj of objects) {
    const values = headers.map(header => {
      const value = obj[header];
      if (value === null || value === undefined) {
        return '';
      }
      if (typeof value === 'string' && (value.includes(delimiter) || value.includes('"'))) {
        return `"${value.replace(/"/g, '""')}"`;
      }
      return String(value);
    });
    result += values.join(delimiter) + '\n';
  }

  return result;
} 