import { MENTION_PARSING_REGEX } from '@/utils/constants';

export function parseMentions(
  srcContent: string,
  mentionsUsedMap?: Map<string, string>
) {
  const userMentions: Array<{
    handle: string;
    start: number;
    end: number;
    display_name: string;
  }> = [];
  MENTION_PARSING_REGEX.lastIndex = 0;
  const mentionRegex = MENTION_PARSING_REGEX;
  let match: RegExpExecArray | null;
  let srcContentIndex = 0;
  let content = '';
  while ((match = mentionRegex.exec(srcContent))) {
    // Add the text content before this mention
    content += srcContent.substring(srcContentIndex, match.index);
    srcContentIndex = match.index + match[0].length;
    // If we match a mention, swap for the display name...
    const handle = match[0].substring(1);
    if (mentionsUsedMap?.has(handle)) {
      // Fall back to @handle if display name is blank
      const display_name = mentionsUsedMap.get(handle)! || `@${handle}`;
      const start = content.length;
      const end = start + display_name.length;
      content += display_name;
      userMentions.push({ handle, start, end, display_name });
    } else {
      // Use the text as-is if there is no mention
      content += match[0];
    }
  }
  // Add the rest of the string
  content += srcContent.substring(srcContentIndex);
  return {
    content,
    userMentions,
  };
}

/**
 * Reconstructs the original text with @handles from transformed content with display names
 * This is the inverse operation of parseCaptionMentions
 *
 * @param transformedContent - Text where @handles have been replaced with display names
 * @param userMentions - Array of user mention data with positions and handles
 * @returns Object with original content (@handles) and mentionsUsedMap
 */
export function reconstructContent(
  transformedContent: string,
  userMentions: Array<{
    start: number;
    end: number;
    handle: string;
    display_name?: string | null;
  }>
) {
  const mentionsUsedMap = new Map<string, string>();
  // Sort mentions by start position in reverse order to avoid position shifts
  const sortedMentions = [...userMentions].sort((a, b) => b.start - a.start);

  let originalContent = transformedContent;

  // Process each mention in reverse order (from end to start)
  // This ensures we don't affect the positions of earlier mentions
  sortedMentions.forEach((mention) => {
    const { start, end, handle, display_name } = mention;

    if (display_name) {
      mentionsUsedMap.set(handle, display_name);
    }

    // Replace the display name with @handle in the original content
    const beforeMention = originalContent.substring(0, start);
    const afterMention = originalContent.substring(end);
    originalContent = beforeMention + `@${handle}` + afterMention;
  });

  return {
    content: originalContent,
    mentionsUsedMap,
  };
}
