/**
 * Unified mention serialization and parsing utilities.
 * Shared across room chat, issues, and PR comments.
 */

export type MentionType =
  | 'user'
  | 'channel'
  | 'ai'
  | 'repo'
  | 'command'
  | 'special_here'
  | 'special_channel';

export const MENTION_TYPES: MentionType[] = [
  'user',
  'channel',
  'ai',
  'repo',
  'command',
  'special_here',
  'special_channel',
];

export interface MentionSpan {
  type: MentionType;
  id: string;
  label: string;
}

export interface ExtractedMentions {
  safeContent: string;
  mentions: MentionSpan[];
}

/**
 * Parse @[type:id:label] tokens from message content.
 * Returns the safe content (with mentions replaced by placeholders) and the parsed mention list.
 *
 * Placeholders use zero-width spaces to prevent markdown from interpreting the text.
 */
const PLACEHOLDER_PREFIX = '​MENTION_';
const PLACEHOLDER_SUFFIX = '​';

const MENTION_RE = /@\[([a-z_]+):([^:\]]+):([^\]]+)\]/g;
const PLACEHOLDER_RE = /​MENTION_(\d+)​/g;

export function extractMentions(content: string): ExtractedMentions {
  const mentions: MentionSpan[] = [];
  const safeContent = content.replace(MENTION_RE, (_match, type, id, label) => {
    const idx = mentions.length;
    mentions.push({ type: type as MentionType, id, label });
    return `${PLACEHOLDER_PREFIX}${idx}${PLACEHOLDER_SUFFIX}`;
  });
  return { safeContent, mentions };
}

export function restoreMentions(
  text: string,
  mentions: MentionSpan[],
): string {
  return text.replace(PLACEHOLDER_RE, (match, idxStr) => {
    const idx = parseInt(idxStr, 10);
    const m = mentions[idx];
    return m ? `@[${m.type}:${m.id}:${m.label}]` : match;
  });
}

/** Build a mention token string for serialization. */
export function serializeMention(type: MentionType, id: string, label: string): string {
  return `@[${type}:${id}:${label}]`;
}

/** Build a mention token from a user mention. */
export function serializeUserMention(userId: string, displayName: string): string {
  return serializeMention('user', userId, displayName);
}

/** Build a mention token from a channel mention. */
export function serializeChannelMention(channelId: string, channelName: string): string {
  return serializeMention('channel', channelId, channelName);
}

/** Build a mention token from an AI mention. */
export function serializeAiMention(aiId: string, aiName: string): string {
  return serializeMention('ai', aiId, aiName);
}

/** Build a mention token from a repo mention. */
export function serializeRepoMention(repoName: string, label?: string): string {
  return serializeMention('repo', repoName, label ?? repoName);
}

/** Build a mention token from a command mention. */
export function serializeCommandMention(commandId: string, commandName: string): string {
  return serializeMention('command', commandId, commandName);
}

/** Build a mention token for @here. */
export function serializeHereMention(): string {
  return '@[special_here:here:here]';
}

/** Build a mention token for @channel. */
export function serializeChannelBroadcastMention(): string {
  return '@[special_channel:channel:channel]';
}
