import { applyTextareaChange } from './markdownIndent';

type ChangeHandler = (value: string) => void;

/** 在选区两侧包裹 Markdown 标记 */
export function wrapMarkdownSelection(
  textarea: HTMLTextAreaElement,
  value: string,
  prefix: string,
  suffix: string,
  placeholder: string,
  onChange: ChangeHandler,
) {
  const { selectionStart, selectionEnd } = textarea;
  const selected = value.slice(selectionStart, selectionEnd);
  const text = selected || placeholder;
  const insert = prefix + text + suffix;
  const next = value.slice(0, selectionStart) + insert + value.slice(selectionEnd);
  const newStart = selectionStart + prefix.length;
  const newEnd = newStart + text.length;
  applyTextareaChange(textarea, next, newStart, newEnd, onChange);
}

/** 为当前行或选区行添加前缀（如引用） */
export function prefixMarkdownLines(
  textarea: HTMLTextAreaElement,
  value: string,
  prefix: string,
  onChange: ChangeHandler,
) {
  const { selectionStart, selectionEnd } = textarea;
  const lineStart = value.lastIndexOf('\n', selectionStart - 1) + 1;
  const nextNewline = value.indexOf('\n', selectionEnd);
  const lineEnd = nextNewline === -1 ? value.length : nextNewline;
  const block = value.slice(lineStart, lineEnd);
  const lines = block.split('\n').map(line => `${prefix}${line}`);
  const next = value.slice(0, lineStart) + lines.join('\n') + value.slice(lineEnd);
  applyTextareaChange(
    textarea,
    next,
    selectionStart + prefix.length,
    selectionEnd + prefix.length * lines.length,
    onChange,
  );
}

/** 切换当前行标题级别（源码模式） */
export function cycleMarkdownHeading(
  textarea: HTMLTextAreaElement,
  value: string,
  onChange: ChangeHandler,
) {
  const { selectionStart } = textarea;
  const lineStart = value.lastIndexOf('\n', selectionStart - 1) + 1;
  const lineEnd = value.indexOf('\n', selectionStart);
  const end = lineEnd === -1 ? value.length : lineEnd;
  const line = value.slice(lineStart, end);
  const match = line.match(/^(#{2,6})\s+(.*)$/);
  let nextLine: string;
  if (!match) {
    nextLine = `## ${line}`;
  } else {
    const level = match[1].length;
    const body = match[2];
    nextLine = level >= 6 ? body : `${'#'.repeat(level + 1)} ${body}`;
  }
  const next = value.slice(0, lineStart) + nextLine + value.slice(end);
  const offset = nextLine.length - line.length;
  applyTextareaChange(
    textarea,
    next,
    selectionStart + Math.max(0, offset),
    selectionStart + Math.max(0, offset),
    onChange,
  );
}

/** 插入登录可见区块模板 */
export function insertMarkdownMembersOnly(
  textarea: HTMLTextAreaElement,
  value: string,
  onChange: ChangeHandler,
) {
  const { selectionStart, selectionEnd } = textarea;
  const snippet = '\n\n<members-only data-gate="login">\n\n\n</members-only>\n\n';
  const next = value.slice(0, selectionStart) + snippet + value.slice(selectionEnd);
  const cursor = selectionStart + '\n\n<members-only data-gate="login">\n\n'.length;
  applyTextareaChange(textarea, next, cursor, cursor, onChange);
}

/** 插入回复可见区块模板 */
export function insertMarkdownReplyOnly(
  textarea: HTMLTextAreaElement,
  value: string,
  onChange: ChangeHandler,
) {
  const { selectionStart, selectionEnd } = textarea;
  const snippet = '\n\n<reply-only data-gate="reply">\n\n\n</reply-only>\n\n';
  const next = value.slice(0, selectionStart) + snippet + value.slice(selectionEnd);
  const cursor = selectionStart + '\n\n<reply-only data-gate="reply">\n\n'.length;
  applyTextareaChange(textarea, next, cursor, cursor, onChange);
}

/** 在光标处插入链接 Markdown */
export function insertMarkdownLink(
  textarea: HTMLTextAreaElement,
  value: string,
  url: string,
  onChange: ChangeHandler,
) {
  const { selectionStart, selectionEnd } = textarea;
  const selected = value.slice(selectionStart, selectionEnd) || '链接文字';
  const insert = `[${selected}](${url})`;
  const next = value.slice(0, selectionStart) + insert + value.slice(selectionEnd);
  applyTextareaChange(
    textarea,
    next,
    selectionStart + insert.length,
    selectionStart + insert.length,
    onChange,
  );
}
