import path from 'path';

import { normalizeAgentOutput } from '../agent-protocol.js';
import { neutralizeStrayMarkdown, sanitizeForOutbound } from '../router.js';
import type { OutboundAttachment } from '../types.js';

const LOCAL_MARKDOWN_LINK_RE = /\[[^\]\n]*\]\((\/[^)\n]+)\)/g;

export interface PreparedDiscordOutbound {
  text: string;
  cleanText: string;
  attachments: OutboundAttachment[];
  attachmentSource:
    | 'structured'
    | 'media-tag'
    | 'md-link'
    | 'image-tag'
    | 'mixed'
    | 'none';
  silent: boolean;
}

function sanitizeLocalMarkdownLinks(text: string): string {
  return text.replace(LOCAL_MARKDOWN_LINK_RE, (_full, rawPath: string) => {
    const trimmed = rawPath.trim();
    const basename = path.basename(trimmed.replace(/#.*$/, ''));
    const lineMatch = trimmed.match(/#L(\d+)/);
    return lineMatch ? `\`${basename}:${lineMatch[1]}\`` : `\`${basename}\``;
  });
}

export function prepareDiscordOutbound(
  text: string,
  optionAttachments: OutboundAttachment[] | undefined,
): PreparedDiscordOutbound {
  const normalized = normalizeAgentOutput(text);
  if (normalized.output?.visibility === 'silent') {
    return {
      text: '',
      cleanText: '',
      attachments: [],
      attachmentSource: 'none',
      silent: true,
    };
  }

  const structuredOutput =
    normalized.output?.visibility === 'public' ? normalized.output : null;
  const outboundText = structuredOutput?.text ?? normalized.result ?? text;
  // Redact/strip before escaping so secret patterns (which contain `_`) still
  // match, then escape stray Discord markdown in free-form agent prose so
  // emphasis markers (**bold**, ~~strike~~, …) render literally. Author-
  // controlled structured envelopes are intentional, so their text is left
  // untouched. Escaping runs before sanitizeLocalMarkdownLinks so the inline
  // code it deliberately produces is preserved.
  const safeText = sanitizeForOutbound(outboundText);
  const renderedText = structuredOutput
    ? safeText
    : neutralizeStrayMarkdown(safeText);
  const cleanText = sanitizeLocalMarkdownLinks(renderedText);
  const attachments =
    optionAttachments && optionAttachments.length > 0
      ? optionAttachments
      : (structuredOutput?.attachments ?? []);
  const hasAttachments = attachments.length > 0;
  const attachmentSource =
    optionAttachments && optionAttachments.length > 0
      ? 'structured'
      : normalized.attachmentSource === 'legacy-ejclaw-json'
        ? 'structured'
        : normalized.attachmentSource === 'media-tag'
          ? 'media-tag'
          : normalized.attachmentSource === 'markdown-image'
            ? 'md-link'
            : (normalized.attachmentSource ?? 'none');

  return {
    text: outboundText,
    cleanText,
    attachments,
    attachmentSource: hasAttachments ? attachmentSource : 'none',
    silent: false,
  };
}
