/* ============================================================================
 * 서명전에 — TDS Post 컴포넌트
 *  · 포스트 형식 줄글 (공지·이벤트·약관) 전용 컨테이너 묶음.
 *  · 8 서브:
 *      Post.H1 / Post.H2 / Post.H3 / Post.H4   — 시멘틱 h1~h4 + 기본 typography
 *      Post.Paragraph                          — 시멘틱 p (본문)
 *      Post.Ol / Post.Ul                       — 시멘틱 ol/ul (중첩 가능)
 *      Post.Li                                 — 시멘틱 li (Ol/Ul 안에서만)
 *      Post.Hr                                 — 시멘틱 hr (구분선)
 *
 *  · 공통 props:
 *      typography     "t1"~"t7" | "st1"~"st13"
 *                      — 미지정 시 헤딩은 자기 기본값, 본문/리스트는 부모 상속
 *      paddingBottom  number | string
 *                      — 자기 아래 여백. number 면 `${n}px`, string 은 그대로.
 *
 *  · Hr 만 typography 없음 — paddingBottom 만.
 *
 *  · 디자인 원칙:
 *      - margin 은 CSS 에서 0 으로 초기화 — 위아래 간격 = paddingBottom 으로만 조립.
 *      - 헤딩은 굵게 + 살짝 음수 letter-spacing.
 *      - 리스트는 decimal/disc 기본, 중첩되어도 동일.
 *      - 본문 p 는 white-space: pre-wrap — `<br />` 또는 `\n` 모두 줄바꿈으로 인정.
 * ========================================================================== */

// ----- typography → utility class 매핑 (Paragraph 와 동일 규칙) -----
function __postTypoClass(typo) {
  if (!typo || typeof typo !== "string") return "";
  let m = typo.match(/^t(\d+)$/i);
  if (m) {
    const n = parseInt(m[1], 10);
    if (n >= 1 && n <= 7) return `ty-${n}`;
  }
  m = typo.match(/^st(\d+)$/i);
  if (m) {
    const n = parseInt(m[1], 10);
    if (n >= 1 && n <= 13) return `sub-ty-${n}`;
  }
  if (window.console && console.warn) {
    console.warn(
      `[Post] \`typography\` 는 t1~t7 또는 st1~st13 만 가능해요. 받은 값: ${typo}`
    );
  }
  return "";
}

// ----- paddingBottom 정규화 -----
function __postPb(pb) {
  if (pb === undefined || pb === null || pb === "") return undefined;
  if (typeof pb === "number" && Number.isFinite(pb)) return `${pb}px`;
  return String(pb);
}

// ----- 공통 헤딩 팩토리 -----
function __makeHeading(Tag, defaultTypo, displayName) {
  function Heading({
    typography,
    paddingBottom,
    className = "",
    style,
    id,
    children,
    ...rest
  }) {
    const typo = typography || defaultTypo;
    const cls = [
      "tds-post__h",
      `tds-post__${Tag}`,
      __postTypoClass(typo),
      className,
    ].filter(Boolean).join(" ");

    const pb = __postPb(paddingBottom);
    const mergedStyle = pb !== undefined
      ? Object.assign({ paddingBottom: pb }, style || {})
      : style;

    return React.createElement(
      Tag,
      Object.assign({ id: id, className: cls, style: mergedStyle }, rest),
      children
    );
  }
  Heading.displayName = displayName;
  return Heading;
}

// =============================================================================
// Root Post — 보통 서브만 쓰는데, 포스트 영역을 명시적으로 감싸고 싶을 때 사용
// =============================================================================
function Post({ className = "", style, id, children, ...rest }) {
  const cls = ["tds-post", className].filter(Boolean).join(" ");
  return (
    <div id={id} className={cls} style={style} {...rest}>
      {children}
    </div>
  );
}

// =============================================================================
// Post.H1 / H2 / H3 / H4
// =============================================================================
const PostH1 = __makeHeading("h1", "t2", "PostH1");
const PostH2 = __makeHeading("h2", "t3", "PostH2");
const PostH3 = __makeHeading("h3", "st8", "PostH3");
const PostH4 = __makeHeading("h4", "t5", "PostH4");

// =============================================================================
// Post.Paragraph — <p> 본문
// =============================================================================
function PostParagraph({
  typography,
  paddingBottom,
  className = "",
  style,
  id,
  children,
  ...rest
}) {
  const cls = [
    "tds-post__paragraph",
    __postTypoClass(typography),
    className,
  ].filter(Boolean).join(" ");

  const pb = __postPb(paddingBottom);
  const mergedStyle = pb !== undefined
    ? Object.assign({ paddingBottom: pb }, style || {})
    : style;

  return (
    <p id={id} className={cls} style={mergedStyle} {...rest}>
      {children}
    </p>
  );
}

// =============================================================================
// Post.Ol — 시멘틱 <ol> (중첩 가능)
// =============================================================================
function PostOl({
  typography,
  paddingBottom,
  className = "",
  style,
  id,
  children,
  ...rest
}) {
  const cls = [
    "tds-post__ol",
    __postTypoClass(typography),
    className,
  ].filter(Boolean).join(" ");

  const pb = __postPb(paddingBottom);
  const mergedStyle = pb !== undefined
    ? Object.assign({ paddingBottom: pb }, style || {})
    : style;

  return (
    <ol id={id} className={cls} style={mergedStyle} {...rest}>
      {children}
    </ol>
  );
}

// =============================================================================
// Post.Ul — 시멘틱 <ul> (중첩 가능)
// =============================================================================
function PostUl({
  typography,
  paddingBottom,
  className = "",
  style,
  id,
  children,
  ...rest
}) {
  const cls = [
    "tds-post__ul",
    __postTypoClass(typography),
    className,
  ].filter(Boolean).join(" ");

  const pb = __postPb(paddingBottom);
  const mergedStyle = pb !== undefined
    ? Object.assign({ paddingBottom: pb }, style || {})
    : style;

  return (
    <ul id={id} className={cls} style={mergedStyle} {...rest}>
      {children}
    </ul>
  );
}

// =============================================================================
// Post.Li — 시멘틱 <li>
//  · Ol/Ul 안에서만 사용해야 마커가 제대로 보여요 (브라우저 기본 동작).
// =============================================================================
function PostLi({
  typography,
  paddingBottom,
  className = "",
  style,
  id,
  children,
  ...rest
}) {
  const cls = [
    "tds-post__li",
    __postTypoClass(typography),
    className,
  ].filter(Boolean).join(" ");

  const pb = __postPb(paddingBottom);
  const mergedStyle = pb !== undefined
    ? Object.assign({ paddingBottom: pb }, style || {})
    : style;

  return (
    <li id={id} className={cls} style={mergedStyle} {...rest}>
      {children}
    </li>
  );
}

// =============================================================================
// Post.Hr — 시멘틱 <hr>
//  · paddingBottom 만 받음. typography 없음.
// =============================================================================
function PostHr({
  paddingBottom,
  className = "",
  style,
  id,
  ...rest
}) {
  const cls = ["tds-post__hr", className].filter(Boolean).join(" ");

  const pb = __postPb(paddingBottom);
  const mergedStyle = pb !== undefined
    ? Object.assign({ paddingBottom: pb }, style || {})
    : style;

  return <hr id={id} className={cls} style={mergedStyle} {...rest} />;
}

// ----- Subcomponent 부착 -----
Post.H1 = PostH1;
Post.H2 = PostH2;
Post.H3 = PostH3;
Post.H4 = PostH4;
Post.Paragraph = PostParagraph;
Post.Ol = PostOl;
Post.Ul = PostUl;
Post.Li = PostLi;
Post.Hr = PostHr;

window.Post = Post;
window.PostH1 = PostH1;
window.PostH2 = PostH2;
window.PostH3 = PostH3;
window.PostH4 = PostH4;
window.PostParagraph = PostParagraph;
window.PostOl = PostOl;
window.PostUl = PostUl;
window.PostLi = PostLi;
window.PostHr = PostHr;

Object.assign(window, {
  Post,
  PostH1,
  PostH2,
  PostH3,
  PostH4,
  PostParagraph,
  PostOl,
  PostUl,
  PostLi,
  PostHr,
});
