import { JSONContent } from '@tiptap/core';
import { AvailableContext, ContextVariable } from '../../types/workflow-context';

const VARIABLE_REGEX = /(\{\{[^}]+\}\})/g;
const VARIABLE_PATH_REGEX = /^\{\{(.+)\}\}$/;

function buildVariableMap(context: AvailableContext): Map<string, ContextVariable> {
  const map = new Map<string, ContextVariable>();
  context.groups.forEach((group) => {
    group.variables.forEach((v) => {
      map.set(v.path, v);
    });
  });
  return map;
}

/**
 * Convert a plain string with {{...}} patterns to TipTap JSON content (single-line)
 */
export function deserializeToTipTap(
  value: string,
  availableContext: AvailableContext,
): JSONContent {
  const variableMap = buildVariableMap(availableContext);
  const parts = value.split(VARIABLE_REGEX);
  const content: JSONContent[] = [];

  parts.forEach((part) => {
    if (!part) return;

    const match = part.match(VARIABLE_PATH_REGEX);
    if (match) {
      const path = match[1];
      const variable = variableMap.get(path);
      content.push({
        type: 'variable',
        attrs: {
          path,
          label: variable?.label || path,
          type: variable?.type || 'string',
        },
      });
    } else {
      content.push({
        type: 'text',
        text: part,
      });
    }
  });

  return {
    type: 'doc',
    content: [
      {
        type: 'paragraph',
        content: content.length > 0 ? content : undefined,
      },
    ],
  };
}

/**
 * Convert a plain string with newlines to multi-paragraph TipTap JSON
 */
export function deserializeMultilineToTipTap(
  value: string,
  availableContext: AvailableContext,
): JSONContent {
  const variableMap = buildVariableMap(availableContext);
  const lines = value.split('\n');

  const paragraphs: JSONContent[] = lines.map((line) => {
    const parts = line.split(VARIABLE_REGEX);
    const content: JSONContent[] = [];

    parts.forEach((part) => {
      if (!part) return;

      const match = part.match(VARIABLE_PATH_REGEX);
      if (match) {
        const path = match[1];
        const variable = variableMap.get(path);
        content.push({
          type: 'variable',
          attrs: {
            path,
            label: variable?.label || path,
            type: variable?.type || 'string',
          },
        });
      } else {
        content.push({ type: 'text', text: part });
      }
    });

    return {
      type: 'paragraph',
      content: content.length > 0 ? content : undefined,
    };
  });

  return {
    type: 'doc',
    content: paragraphs,
  };
}

/**
 * Serialize TipTap JSON content back to plain string with {{...}} patterns
 */
export function serializeFromTipTap(doc: JSONContent): string {
  if (!doc.content) return '';

  const lines: string[] = [];

  doc.content.forEach((paragraph) => {
    if (paragraph.type !== 'paragraph') return;

    let line = '';
    if (paragraph.content) {
      paragraph.content.forEach((node) => {
        if (node.type === 'text') {
          line += node.text || '';
        } else if (node.type === 'variable') {
          line += `{{${node.attrs?.path || ''}}}`;
        }
      });
    }
    lines.push(line);
  });

  return lines.join('\n');
}
