/* ============================================================================
 * 서명전에 — TDS Top 컴포넌트
 *  · 페이지 최상단 영역 — 헤더/타이틀 블록을 일관되게 짜는 빌더.
 *    여러 슬롯(upper / 중앙 [subtitleTop+title+subtitleBottom] / right / lower)을
 *    조합해서 서비스 곳곳의 진입 헤더(예: HistoryAccount 첫 줄, Result 결과 헤더,
 *    Help/FAQ 카테고리 헤더, Onboarding 안내 헤더)를 한 줄로 짤 수 있어요.
 *
 *  · 구조:
 *      ┌──────────────────────────────────────────────┐
 *      │ upperGap (기본 24px)                         │
 *      ├──────────────────────────────────────────────┤
 *      │ upper   (Asset/Lottie 등)                    │
 *      │                                              │
 *      │ ┌──────────────────────┬───────────────────┐ │
 *      │ │ subtitleTop          │  right            │ │
 *      │ │ title                │  (Asset/Button)   │ │
 *      │ │ subtitleBottom       │                   │ │
 *      │ └──────────────────────┴───────────────────┘ │
 *      │                                              │
 *      │ lower   (LowerButton / LowerCTA)             │
 *      ├──────────────────────────────────────────────┤
 *      │ lowerGap (기본 24px)                         │
 *      └──────────────────────────────────────────────┘
 *
 *  · 서브 (총 14):
 *      Top.TitleParagraph      — h1 텍스트 (role="heading" aria-level="1" 자동)
 *      Top.TitleTextButton     — 타이틀이 텍스트 버튼처럼 동작 (TextButton 위임)
 *      Top.TitleSelector       — 타이틀이 셀렉터 (chev-down, aria-haspopup="listbox")
 *      Top.SubtitleParagraph   — h2 부제목 (role="heading" aria-level="2" 자동)
 *      Top.SubtitleTextButton  — 부제목이 텍스트 버튼처럼 동작
 *      Top.SubtitleSelector    — 부제목이 셀렉터 (chev-down, aria-haspopup="listbox")
 *      Top.SubtitleBadges      — 부제목 자리에 뱃지 묶음 (Badge 위임)
 *      Top.UpperAssetContent   — upper 슬롯 Asset 래퍼 (정렬 + 여백 규칙)
 *      Top.RightAssetContent   — right 슬롯 Asset 래퍼
 *      Top.RightButton         — right 슬롯 버튼 (Button 위임, size 기본 medium)
 *      Top.RightArrow          — right 슬롯 chev-right 아이콘 단독
 *      Top.LowerButton         — lower 작은 버튼 1개 (Button 위임, size 기본 small)
 *      Top.LowerCTA            — lower 두 버튼 (type="2-button"; left/right 버튼 슬롯)
 *      Top.LowerCTAButton      — LowerCTA 안에 들어가는 버튼 (Button 위임, size 기본 large)
 *
 *  · 여백 규칙:
 *      - upperGap / lowerGap 은 number (px) — `${n}px` 인라인.
 *      - subtitleTop ↔ title : 6px 마진. title ↔ subtitleBottom : 6px 마진.
 *      - upper 슬롯과 본문 사이 16px (UpperAssetContent 가 자체 margin-bottom).
 *      - right 슬롯은 본문 텍스트 column 의 우측. 기본 vertical center,
 *        rightVerticalAlign="end" 면 아래쪽 정렬(긴 본문에 작게 맞춤).
 *      - lower 슬롯과 본문 사이 16px.
 *
 *  · 접근성:
 *      - TitleParagraph 는 자동으로 role="heading" + aria-level="1".
 *      - SubtitleParagraph 는 자동으로 role="heading" + aria-level="2".
 *      - TitleSelector / SubtitleSelector 는 자동으로 aria-haspopup="listbox".
 *      - 호출자가 같은 prop 을 따로 주면 호출자 값이 우선(오버라이드 가능).
 *
 *  · 의존: Button, TextButton, Paragraph, Badge — 미로드 시 native 폴백 + 폴백 클래스.
 * ========================================================================== */

// =============================================================================
// 보조 — chev SVG (셀렉터 / RightArrow)
// =============================================================================
function __TopChevDown({ size = 16, color, ariaHidden = true }) {
  // 위에서 아래로 펼치는 셀렉터 — 16x16 viewbox
  return (
    <svg
      className="tds-top__chev"
      width={size}
      height={size}
      viewBox="0 0 24 24"
      fill="none"
      focusable="false"
      aria-hidden={ariaHidden ? "true" : undefined}
      style={color ? { color } : undefined}
    >
      <polyline
        points="6 9 12 15 18 9"
        stroke="currentColor"
        strokeWidth="2"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  );
}

function __TopChevRight({ size = 20, color, ariaHidden = true, ariaLabel }) {
  return (
    <svg
      className="tds-top__chev tds-top__chev--right"
      width={size}
      height={size}
      viewBox="0 0 24 24"
      fill="none"
      focusable="false"
      role={ariaLabel ? "img" : undefined}
      aria-label={ariaLabel || undefined}
      aria-hidden={!ariaLabel && ariaHidden ? "true" : undefined}
      style={color ? { color } : undefined}
    >
      <polyline
        points="9 6 15 12 9 18"
        stroke="currentColor"
        strokeWidth="2"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  );
}

// =============================================================================
// 보조 — typography 힌트 (TDS t3/st2 ↔ 우리 ty-3/sub-ty-2 등)
// =============================================================================
function __topTypoForTitleSize(size) {
  // 22 → t3 / 28 → st2  (스펙)
  if (size === 28) return "st2";
  return "t3";
}

function __topTypoForSubtitleSize(size) {
  // 13 → t7 / 15 → t6 / 17 → t5  (스펙)
  if (size === 13) return "t7";
  if (size === 15) return "t6";
  return "t5";
}

function __topFwForSubtitleSize(size) {
  // 13/15 → regular / 17 → medium  (스펙)
  if (size === 13 || size === 15) return "regular";
  return "medium";
}

// =============================================================================
// Root — Top
// =============================================================================
function Top({
  title,
  upperGap = 24,
  lowerGap = 24,
  upper,
  lower,
  subtitleTop,
  subtitleBottom,
  right,
  rightVerticalAlign = "center",
  className = "",
  style,
  ...rest
}) {
  const cls = [
    "tds-top",
    rightVerticalAlign === "end" ? "tds-top--right-end" : "tds-top--right-center",
    className,
  ]
    .filter(Boolean)
    .join(" ");

  // upperGap / lowerGap 은 number → `${n}px`. 음수/NaN 은 0 으로.
  const safeNum = function (v, fallback) {
    if (typeof v !== "number" || !isFinite(v) || v < 0) return fallback;
    return v;
  };
  const padTop = safeNum(upperGap, 24);
  const padBottom = safeNum(lowerGap, 24);

  const mergedStyle = Object.assign(
    {
      paddingTop: `${padTop}px`,
      paddingBottom: `${padBottom}px`,
    },
    style || {}
  );

  return (
    <div className={cls} style={mergedStyle} {...rest}>
      {upper ? <div className="tds-top__upper">{upper}</div> : null}

      {/* 본문 — 좌측 텍스트 컬럼 + 우측 슬롯 */}
      {(title || subtitleTop || subtitleBottom || right) ? (
        <div className="tds-top__main">
          <div className="tds-top__center">
            {subtitleTop ? <div className="tds-top__subtitle tds-top__subtitle--top">{subtitleTop}</div> : null}
            {title ? <div className="tds-top__title">{title}</div> : null}
            {subtitleBottom ? <div className="tds-top__subtitle tds-top__subtitle--bottom">{subtitleBottom}</div> : null}
          </div>
          {right ? <div className="tds-top__right">{right}</div> : null}
        </div>
      ) : null}

      {lower ? <div className="tds-top__lower">{lower}</div> : null}
    </div>
  );
}

// =============================================================================
// Top.TitleParagraph
// =============================================================================
function TopTitleParagraph({
  size = 22,
  color,
  typography,
  fontWeight = "bold",
  className = "",
  children,
  // 접근성 자동 부여 — 호출자가 명시하면 그쪽 우선
  role,
  "aria-level": ariaLevel,
  ...rest
}) {
  // size 검증 — 22 / 28 만
  if (size !== 22 && size !== 28) {
    if (window.console && console.warn) {
      console.warn(`[Top.TitleParagraph] size 는 22 | 28 만 가능. 받은 값: ${size}. 22 폴백.`);
    }
    size = 22;
  }
  const tg = typography || __topTypoForTitleSize(size);

  // 색은 인라인으로 주입(Paragraph 는 color prop 지원). 기본 grey-800.
  const effectiveColor = color || "var(--tds-grey-800)";

  const cls = ["tds-top__title-paragraph", className].filter(Boolean).join(" ");

  // Paragraph 컴포넌트 위임 — 미로드 시 <p> 폴백
  if (typeof window.Paragraph === "function") {
    return (
      <window.Paragraph
        typography={tg}
        fontWeight={fontWeight}
        color={effectiveColor}
        className={cls}
        role={role || "heading"}
        aria-level={typeof ariaLevel === "number" || typeof ariaLevel === "string" ? ariaLevel : 1}
        {...rest}
      >
        {children}
      </window.Paragraph>
    );
  }
  return (
    <p
      className={`${cls} tds-top__title-paragraph--fallback`}
      role={role || "heading"}
      aria-level={typeof ariaLevel === "number" || typeof ariaLevel === "string" ? ariaLevel : 1}
      style={{ color: effectiveColor, fontWeight: fontWeight === "bold" ? 700 : 500 }}
      {...rest}
    >
      {children}
    </p>
  );
}

// =============================================================================
// Top.TitleTextButton — 타이틀이 텍스트 버튼처럼 동작
// =============================================================================
function TopTitleTextButton({
  size = "xlarge",
  variant,
  color,
  className = "",
  children,
  ...rest
}) {
  const cls = ["tds-top__title-text-button", className].filter(Boolean).join(" ");
  const effectiveColor = color || "var(--tds-grey-800)";

  if (typeof window.TextButton === "function") {
    return (
      <window.TextButton
        size={size}
        variant={variant}
        color={effectiveColor}
        className={cls}
        // 타이틀 자리이므로 굵게 + heading 시맨틱 보강
        fontWeight="bold"
        role="heading"
        aria-level={1}
        {...rest}
      >
        {children}
      </window.TextButton>
    );
  }
  // 폴백 — TextButton 미로드 시 native button
  return (
    <button
      type="button"
      className={`${cls} tds-top__title-text-button--fallback`}
      style={{ color: effectiveColor }}
      role="heading"
      aria-level={1}
      {...rest}
    >
      {children}
    </button>
  );
}

// =============================================================================
// Top.TitleSelector — 타이틀이 셀렉터 (chev-down + aria-haspopup="listbox")
// =============================================================================
function TopTitleSelector({
  color,
  typography,
  fontWeight = "bold",
  className = "",
  children,
  // 접근성 자동
  role,
  "aria-level": ariaLevel,
  "aria-haspopup": ariaHaspopup,
  onClick,
  ...rest
}) {
  // 타이틀 셀렉터는 spec 상 size 별 토큰 — typography 만 있고 size 가 없는 형태.
  // 우리는 ty-3 (=22 라인) 을 기본으로 두고, 호출자가 typography 로 덮어쓸 수 있게.
  const tg = typography || "t3";
  const effectiveColor = color || "var(--tds-grey-800)";

  const cls = ["tds-top__title-selector", className].filter(Boolean).join(" ");

  return (
    <button
      type="button"
      className={cls}
      onClick={onClick}
      role={role || "heading"}
      aria-level={typeof ariaLevel === "number" || typeof ariaLevel === "string" ? ariaLevel : 1}
      aria-haspopup={ariaHaspopup || "listbox"}
      style={{ color: effectiveColor }}
      {...rest}
    >
      <span className={`tds-top__title-selector-label tds-top__typo-${tg} tds-top__fw-${fontWeight}`}>
        {children}
      </span>
      <span className="tds-top__title-selector-arrow" aria-hidden="true">
        <__TopChevDown size={20} />
      </span>
    </button>
  );
}

// =============================================================================
// Top.SubtitleParagraph
// =============================================================================
function TopSubtitleParagraph({
  size = 17,
  color,
  typography,
  fontWeight,
  className = "",
  children,
  role,
  "aria-level": ariaLevel,
  ...rest
}) {
  if (size !== 13 && size !== 15 && size !== 17) {
    if (window.console && console.warn) {
      console.warn(`[Top.SubtitleParagraph] size 는 13 | 15 | 17 만 가능. 받은 값: ${size}. 17 폴백.`);
    }
    size = 17;
  }
  const tg = typography || __topTypoForSubtitleSize(size);
  const fw = fontWeight || __topFwForSubtitleSize(size);
  const effectiveColor = color || "var(--tds-grey-700)";

  const cls = ["tds-top__subtitle-paragraph", className].filter(Boolean).join(" ");

  if (typeof window.Paragraph === "function") {
    return (
      <window.Paragraph
        typography={tg}
        fontWeight={fw}
        color={effectiveColor}
        className={cls}
        role={role || "heading"}
        aria-level={typeof ariaLevel === "number" || typeof ariaLevel === "string" ? ariaLevel : 2}
        {...rest}
      >
        {children}
      </window.Paragraph>
    );
  }
  return (
    <p
      className={`${cls} tds-top__subtitle-paragraph--fallback`}
      role={role || "heading"}
      aria-level={typeof ariaLevel === "number" || typeof ariaLevel === "string" ? ariaLevel : 2}
      style={{ color: effectiveColor, fontWeight: fw === "medium" ? 500 : 400 }}
      {...rest}
    >
      {children}
    </p>
  );
}

// =============================================================================
// Top.SubtitleTextButton
// =============================================================================
function TopSubtitleTextButton({
  size = "medium",
  variant = "arrow",
  color,
  className = "",
  children,
  ...rest
}) {
  const cls = ["tds-top__subtitle-text-button", className].filter(Boolean).join(" ");
  const effectiveColor = color || "var(--tds-grey-700)";

  if (typeof window.TextButton === "function") {
    return (
      <window.TextButton
        size={size}
        variant={variant}
        color={effectiveColor}
        className={cls}
        {...rest}
      >
        {children}
      </window.TextButton>
    );
  }
  return (
    <button
      type="button"
      className={`${cls} tds-top__subtitle-text-button--fallback`}
      style={{ color: effectiveColor }}
      {...rest}
    >
      {children}
    </button>
  );
}

// =============================================================================
// Top.SubtitleSelector — 부제목이 셀렉터 (chev-down + aria-haspopup="listbox")
// =============================================================================
function TopSubtitleSelector({
  size = 17,
  color,
  typography,
  fontWeight,
  type = "arrow", // "arrow" 면 chev-down 표시, 그 외(none 등) 면 표시 안 함
  className = "",
  children,
  "aria-haspopup": ariaHaspopup,
  onClick,
  ...rest
}) {
  if (size !== 13 && size !== 15 && size !== 17) {
    if (window.console && console.warn) {
      console.warn(`[Top.SubtitleSelector] size 는 13 | 15 | 17 만 가능. 받은 값: ${size}. 17 폴백.`);
    }
    size = 17;
  }
  const tg = typography || __topTypoForSubtitleSize(size);
  const fw = fontWeight || __topFwForSubtitleSize(size);
  const effectiveColor = color || "var(--tds-grey-700)";

  // chev 크기 — size 와 1:1 (16/14/12)
  const chevPx = size === 13 ? 14 : size === 15 ? 16 : 18;

  const cls = ["tds-top__subtitle-selector", className].filter(Boolean).join(" ");

  return (
    <button
      type="button"
      className={cls}
      onClick={onClick}
      aria-haspopup={ariaHaspopup || "listbox"}
      style={{ color: effectiveColor }}
      {...rest}
    >
      <span className={`tds-top__subtitle-selector-label tds-top__typo-${tg} tds-top__fw-${fw}`}>
        {children}
      </span>
      {type === "arrow" ? (
        <span className="tds-top__subtitle-selector-arrow" aria-hidden="true">
          <__TopChevDown size={chevPx} />
        </span>
      ) : null}
    </button>
  );
}

// =============================================================================
// Top.SubtitleBadges
// =============================================================================
function TopSubtitleBadges({
  badges,
  className = "",
  ...rest
}) {
  if (!Array.isArray(badges)) {
    if (window.console && console.warn) {
      console.warn("[Top.SubtitleBadges] badges 는 배열이 필요해요.");
    }
    return null;
  }

  const cls = ["tds-top__subtitle-badges", className].filter(Boolean).join(" ");

  return (
    <div className={cls} {...rest}>
      {badges.map(function (b, i) {
        if (!b || typeof b !== "object") return null;
        // 별칭 정규화 — TDS spec 의 type/style 도 받음
        const color = b.color || b.type || "blue";
        const variant = b.variant || b.style || "weak";
        const text = b.text;
        const key = b.key != null ? b.key : `top-badge-${i}`;
        if (typeof window.Badge === "function") {
          return (
            <window.Badge key={key} color={color} variant={variant} size="small">
              {text}
            </window.Badge>
          );
        }
        return (
          <span key={key} className={`tds-top__badge-fallback tds-top__badge-fallback--${variant}-${color}`}>
            {text}
          </span>
        );
      })}
    </div>
  );
}

// =============================================================================
// Top.UpperAssetContent — upper 슬롯 Asset 래퍼 (여백 규칙)
// =============================================================================
function TopUpperAssetContent({
  content,
  className = "",
  ...rest
}) {
  const cls = ["tds-top__upper-asset", className].filter(Boolean).join(" ");
  return (
    <div className={cls} {...rest}>
      {content}
    </div>
  );
}

// =============================================================================
// Top.RightAssetContent — right 슬롯 Asset 래퍼
// =============================================================================
function TopRightAssetContent({
  content,
  className = "",
  ...rest
}) {
  const cls = ["tds-top__right-asset", className].filter(Boolean).join(" ");
  return (
    <div className={cls} {...rest}>
      {content}
    </div>
  );
}

// =============================================================================
// Top.RightButton — Button 위임 (size 기본 medium)
// =============================================================================
function TopRightButton({
  size = "medium",
  color = "primary",
  variant,
  className = "",
  children,
  ...rest
}) {
  const cls = ["tds-top__right-button", className].filter(Boolean).join(" ");

  if (typeof window.Button === "function") {
    return (
      <window.Button
        size={size}
        color={color}
        variant={variant}
        className={cls}
        {...rest}
      >
        {children}
      </window.Button>
    );
  }
  return (
    <button
      type="button"
      className={`${cls} tds-top__right-button--fallback`}
      {...rest}
    >
      {children}
    </button>
  );
}

// =============================================================================
// Top.RightArrow — chev-right 아이콘 단독 (Icon 위임 자리에 inline SVG)
// =============================================================================
function TopRightArrow({
  color = "var(--tds-grey-600)",
  size = 20,
  name, // 호환용 — 무시되지만 받아둠
  className = "",
  ...rest
}) {
  const cls = ["tds-top__right-arrow", className].filter(Boolean).join(" ");
  return (
    <span className={cls} {...rest}>
      <__TopChevRight size={size} color={color} />
    </span>
  );
}

// =============================================================================
// Top.LowerButton — 작은 보조 버튼 1개 (size 기본 small)
// =============================================================================
function TopLowerButton({
  size = "small",
  color = "primary",
  variant = "weak",
  display = "inline",
  className = "",
  children,
  ...rest
}) {
  const cls = ["tds-top__lower-button", className].filter(Boolean).join(" ");

  if (typeof window.Button === "function") {
    return (
      <window.Button
        size={size}
        color={color}
        variant={variant}
        display={display}
        className={cls}
        {...rest}
      >
        {children}
      </window.Button>
    );
  }
  return (
    <button
      type="button"
      className={`${cls} tds-top__lower-button--fallback`}
      {...rest}
    >
      {children}
    </button>
  );
}

// =============================================================================
// Top.LowerCTA — 두 버튼 가로 배치 (type="2-button")
// =============================================================================
function TopLowerCTA({
  type = "2-button",
  leftButton,
  rightButton,
  className = "",
  ...rest
}) {
  if (type !== "2-button") {
    if (window.console && console.warn) {
      console.warn(`[Top.LowerCTA] type 은 "2-button" 만 지원해요. 받은 값: ${type}.`);
    }
  }
  const cls = ["tds-top__lower-cta", `tds-top__lower-cta--${type}`, className]
    .filter(Boolean)
    .join(" ");

  return (
    <div className={cls} role="group" {...rest}>
      <div className="tds-top__lower-cta-slot tds-top__lower-cta-slot--left">{leftButton}</div>
      <div className="tds-top__lower-cta-slot tds-top__lower-cta-slot--right">{rightButton}</div>
    </div>
  );
}

// =============================================================================
// Top.LowerCTAButton — LowerCTA 안 버튼 (size 기본 large)
// =============================================================================
function TopLowerCTAButton({
  size = "large",
  color = "primary",
  variant,
  display = "block",
  className = "",
  children,
  ...rest
}) {
  const cls = ["tds-top__lower-cta-button", className].filter(Boolean).join(" ");

  if (typeof window.Button === "function") {
    return (
      <window.Button
        size={size}
        color={color}
        variant={variant}
        display={display}
        className={cls}
        {...rest}
      >
        {children}
      </window.Button>
    );
  }
  return (
    <button
      type="button"
      className={`${cls} tds-top__lower-cta-button--fallback`}
      {...rest}
    >
      {children}
    </button>
  );
}

// =============================================================================
// 서브 매달기
// =============================================================================
Top.TitleParagraph = TopTitleParagraph;
Top.TitleTextButton = TopTitleTextButton;
Top.TitleSelector = TopTitleSelector;
Top.SubtitleParagraph = TopSubtitleParagraph;
Top.SubtitleTextButton = TopSubtitleTextButton;
Top.SubtitleSelector = TopSubtitleSelector;
Top.SubtitleBadges = TopSubtitleBadges;
Top.UpperAssetContent = TopUpperAssetContent;
Top.RightAssetContent = TopRightAssetContent;
Top.RightButton = TopRightButton;
Top.RightArrow = TopRightArrow;
Top.LowerButton = TopLowerButton;
Top.LowerCTA = TopLowerCTA;
Top.LowerCTAButton = TopLowerCTAButton;

window.Top = Top;
Object.assign(window, { Top });
