/**
 * 문서 본문 markdown 렌더 (Phase 1C + Phase 1B.5 — MarkdownDoc 컴포넌트 전용).
 *
 * mathMarkdown.ts (study 의 문제·해설용) 와 별도 인스턴스를 둬서 study 측 동작에 영향 없음.
 *
 * 차이점:
 *   - GFM heading id (anchor 용 id 자동 부여, prefix=doc-)
 *   - 이미지는 placeholder card 로 렌더. `data-md-image-internal="1"` 인 경우 (href 가
 *     `docimg:img_NNN`) MarkdownDoc 의 selector 가 mount 후 실제 <img> 로 교체.
 *     `data-md-image-internal="0"` (외부 URL) 은 placeholder 유지 — 외부 이미지 자동
 *     fetch 회피 (privacy + dependency).
 *
 * KaTeX / DOMPurify 정책은 mathMarkdown.ts 의 정책과 동일.
 */

import DOMPurify from 'dompurify';
import { Marked } from 'marked';
// @ts-ignore — 타입 정의 누락 시 무시
import markedKatex from 'marked-katex-extension';
// @ts-ignore — 타입 정의 누락 시 무시
import { gfmHeadingId } from 'marked-gfm-heading-id';
import 'katex/dist/katex.min.css';

function escAttr(s: string): string {
  return s.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
function escText(s: string): string {
  return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}

const docMarked = new Marked();
docMarked.use({ mangle: false } as any);
docMarked.use(gfmHeadingId({ prefix: 'doc-' }));
docMarked.use(
  markedKatex({
    throwOnError: false,
    nonStandard: false,
    output: 'html',
  } as any),
);

// 이미지 → placeholder card. raw <img> 를 emit 하면 asset 미서빙 상태(1B.5 전)에선
// 깨진 아이콘이 보임 → 1D pilot 평가가 markdown 품질이 아닌 viewer 미완성 문제로 오염됨.
// 따라서 1C 에선 placeholder 로 렌더하되 원본 href 는 data-md-image-src 에 보존
// (1B.5 에서 ImgAuth selector 로 잡아 실제 <img> 로 교체 예정).
docMarked.use({
  renderer: {
    image(token: any): string {
      const rawHref = (token?.href ?? '') as string;
      const rawAlt = (token?.text ?? '') as string;
      const isInternal = rawHref.startsWith('docimg:');
      const basename = rawHref.split('/').pop() ?? rawHref;
      const labelSrc = rawAlt || basename || '이미지';
      const safeHref = escAttr(rawHref);
      const safeAlt = escAttr(rawAlt);
      const safeLabel = escText(`[이미지: ${labelSrc} — 아직 표시되지 않음]`);
      const internalFlag = isInternal ? '1' : '0';
      return (
        `<figure class="md-image-placeholder" data-md-img="1" data-md-image-src="${safeHref}" data-md-image-internal="${internalFlag}" data-md-image-alt="${safeAlt}">` +
        `<div class="md-image-placeholder-card">` +
        `<span class="md-image-placeholder-icon" aria-hidden="true">🖼️</span>` +
        `<span class="md-image-placeholder-label">${safeLabel}</span>` +
        `</div>` +
        `</figure>`
      );
    },
  },
});

const SANITIZE_OPTS = {
  USE_PROFILES: { html: true },
  // KaTeX (style + aria-hidden), heading anchor (id), 이미지 마킹 (data-md-img,
  // data-md-image-src + data-md-image-internal + data-md-image-alt — 1B.5 ImgAuth
  // selector 용), figure caption (figure/figcaption)
  ADD_ATTR: [
    'style',
    'aria-hidden',
    'id',
    'data-md-img',
    'data-md-image-src',
    'data-md-image-internal',
    'data-md-image-alt',
    'loading',
  ],
  ADD_TAGS: ['figure', 'figcaption'],
  FORBID_TAGS: ['script', 'iframe', 'object', 'embed', 'link', 'meta'],
  FORBID_ATTR: ['onerror', 'onclick', 'onload', 'onmouseover', 'onfocus'],
  ALLOW_UNKNOWN_PROTOCOLS: false,
} as const;

export function renderDocMarkdown(text: string | null | undefined): string {
  if (!text) return '';
  try {
    const html = docMarked.parse(text) as string;
    return DOMPurify.sanitize(html, SANITIZE_OPTS);
  } catch {
    // 마지막 안전망: 모든 태그 제거 후 escape
    return DOMPurify.sanitize(text, { ALLOWED_TAGS: [], ALLOWED_ATTR: [] });
  }
}
