#!/usr/bin/env python3
"""M3-2 서울대보험쌤 × 관리자 비전 Google 광고 배너 생성
- m3-2-1200x628.png (가로형)
- m3-2-1080x1080.png (정사각형)

컬러 팔레트 (M3-2: 밝은 톤):
- 헤드라인: 딥 브라운 #3E2723 (크림 위)
- 서브카피: 다크 골드 #A07828 (크림 위, 밝은 배경이므로 반드시 다크 골드)
- 배경 오버레이: 크림 #FFF8E7
- 브랜드 뱃지: 골드 #C9A84C 배경, 텍스트 #1A0E00
- CTA: 골드 그라데이션 #C9A84C → #D4B87A, 텍스트 #1A0E00
"""

from __future__ import annotations

import base64
import json
import sys
import time
from pathlib import Path

import requests
from playwright.sync_api import sync_playwright
from gen_config import CTA_MIN_PX, FONT_DIR, WORKSPACE_ROOT

# ── 디자인 토큰 ──
_CTA_PX = CTA_MIN_PX
_SIZE_42PX = 42
_SIZE_44PX = 44
_SIZE_48PX = 48
_SIZE_58PX = 58
_SIZE_62PX = 62
_LH_1_2 = 1.2


# ── 경로 설정 ────────────────────────────────────────────────────────────────
BASE_DIR = Path(__file__).parent
OUTPUT_DIR = WORKSPACE_ROOT / "output/google-ads/banners/m3"
TMP_DIR = BASE_DIR / "output" / "v4-hybrid"
BG_PATH = TMP_DIR / "bg_m3_2.jpg"

# Gemini API 설정
GEMINI_API_BASE = "https://generativelanguage.googleapis.com/v1beta"
MODEL_ID = "gemini-3-pro-image-preview"
FALLBACK_MODEL_ID = "gemini-3.1-flash-image-preview"

# ── 배경 프롬프트 (M3-2: 밝은 코워킹 오피스) ────────────────────────────────────
BG_PROMPT = (
    "Photographic scene of a modern, warm co-working office with private "
    "glass-walled offices visible in the background. Wide shot, eye-level "
    "from the entrance. Open workspace in the foreground with individual "
    "desks, MacBooks, warm Edison-style pendant lights. A glass-walled "
    "private office visible on the right background — door open, suggesting "
    "availability and openness. Monstera deliciosa plants in two spots for "
    "organic warmth. Light walnut wood tones throughout furniture. Warm, "
    "diffused afternoon natural light — mix of sunlight and warm artificial. "
    "The space feels like it's designed for both independence and collaboration "
    "— individual desks but connected community. People are present in the "
    "background, blurred — some seated, some moving. Feels like a growing, "
    "purposeful team. No text. No logos. No icons. No graphics."
)


# ── Gemini 배경 생성 ──────────────────────────────────────────────────────────

def get_auth_token() -> str:
    """gcloud_auth 모듈로 Bearer 토큰을 획득합니다."""
    sys.path.insert(0, str(BASE_DIR))
    import gcloud_auth
    return gcloud_auth.get_access_token()


def _call_model(token: str, api_key: str | None, model: str, payload: dict) -> requests.Response:
    """SA 토큰 우선, 실패 시 API 키로 Gemini 호출."""
    url_bearer = f"{GEMINI_API_BASE}/models/{model}:generateContent"
    headers_bearer = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
    resp = requests.post(url_bearer, headers=headers_bearer, json=payload, timeout=300)
    if resp.status_code == 200:
        return resp
    # API 키 폴백
    if api_key:
        url_key = f"{GEMINI_API_BASE}/models/{model}:generateContent?key={api_key}"
        headers_key = {"Content-Type": "application/json"}
        return requests.post(url_key, headers=headers_key, json=payload, timeout=300)
    return resp


def generate_background() -> Path:
    """Gemini API로 배경 이미지를 생성하고 경로를 반환합니다."""
    if BG_PATH.exists() and BG_PATH.stat().st_size > 50_000:
        print(f"[배경] 기존 배경 이미지 재사용: {BG_PATH}")
        return BG_PATH

    print("[배경] Gemini API로 배경 이미지 생성 중...")
    token = get_auth_token()
    sys.path.insert(0, str(BASE_DIR))
    import gcloud_auth as ga
    api_key = ga.get_api_key("GEMINI_API_KEY")

    payload = {
        "contents": [{"parts": [{"text": BG_PROMPT}]}],
        "generationConfig": {"responseModalities": ["IMAGE", "TEXT"]},
    }

    models_to_try = [MODEL_ID, FALLBACK_MODEL_ID]
    last_error = None

    for attempt, model in enumerate(models_to_try, 1):
        print(f"  시도 {attempt}: 모델={model}")
        try:
            resp = _call_model(token, api_key, model, payload)
        except Exception as e:
            last_error = str(e)
            print(f"  요청 실패: {e}")
            continue

        if resp.status_code in (400, 403, 404):
            print(f"  모델 접근 실패 ({resp.status_code}: {resp.text[:200]})")
            last_error = f"HTTP {resp.status_code}"
            continue

        if resp.status_code != 200:
            print(f"  HTTP {resp.status_code}: {resp.text[:300]}")
            last_error = f"HTTP {resp.status_code}"
            continue

        data = resp.json()
        candidates = data.get("candidates", [])
        if not candidates:
            print(f"  응답에 candidates 없음: {json.dumps(data)[:200]}")
            last_error = "No candidates"
            continue

        parts = candidates[0].get("content", {}).get("parts", [])
        image_part = next((p for p in parts if "inlineData" in p), None)

        if image_part is None:
            print(f"  이미지 없음. parts: {[list(p.keys()) for p in parts]}")
            last_error = "No inlineData"
            continue

        mime = image_part["inlineData"].get("mimeType", "image/jpeg")
        img_bytes = base64.b64decode(image_part["inlineData"]["data"])
        BG_PATH.write_bytes(img_bytes)
        print(f"  [배경] 저장 완료: {BG_PATH} ({len(img_bytes):,} bytes, mime={mime})")
        return BG_PATH

    raise RuntimeError(f"배경 이미지 생성 실패: {last_error}")


# ── HTML 템플릿 ───────────────────────────────────────────────────────────────

def make_html_1200x628(bg_path: Path) -> str:
    """1200x628 가로형 배너 HTML 생성 (M3-2 밝은 톤)."""
    bg_uri = f"file://{bg_path.resolve()}"
    return f"""<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{FONT_DIR}/Pretendard-Bold.otf') format('opentype');
    font-weight: 700;
  }}
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{FONT_DIR}/Pretendard-Medium.otf') format('opentype');
    font-weight: 500;
  }}
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{FONT_DIR}/Pretendard-SemiBold.otf') format('opentype');
    font-weight: 600;
  }}
  * {{ margin: 0; padding: 0; box-sizing: border-box; }}

  body {{
    width: 1200px;
    height: 628px;
    overflow: hidden;
    font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    background: #FFF8E7;
  }}

  .container {{
    position: relative;
    width: 1200px;
    height: 628px;
    overflow: hidden;
  }}

  /* Gemini 배경 이미지: 전체 */
  .bg-image {{
    position: absolute;
    inset: 0;
    background-image: url('{bg_uri}');
    background-size: cover;
    background-position: center right;
  }}

  /* 크림 소프트 패널: 좌측 660px, opacity 0.88 */
  .cream-panel {{
    position: absolute;
    top: 0;
    left: 0;
    width: 660px;
    height: 100%;
    background: rgba(255, 248, 231, 0.88);
  }}

  /* 패널 우측 경계 블렌딩: 120px gradient(크림→투명) */
  .cream-blend {{
    position: absolute;
    top: 0;
    left: 540px;
    width: 240px;
    height: 100%;
    background: linear-gradient(
      to right,
      rgba(255, 248, 231, 0.88) 0%,
      rgba(255, 248, 231, 0.5) 30%,
      rgba(255, 248, 231, 0.15) 70%,
      transparent 100%
    );
  }}

  /* 골드 세로 액센트바 */
  .accent-bar {{
    position: absolute;
    top: 80px;
    left: 0;
    width: 4px;
    height: 460px;
    background: linear-gradient(to bottom, #C9A84C, #D4B87A);
    border-radius: 2px;
  }}

  /* 텍스트 영역: 좌측 패딩 60px, 상 48px */
  .text-area {{
    position: absolute;
    left: 0;
    top: 0;
    width: 620px;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 48px 40px 48px 60px;
    gap: 0;
  }}

  /* 브랜드 뱃지 */
  .brand-badge {{
    display: inline-flex;
    align-items: center;
    background: #C9A84C;
    color: #1A0E00;
    font-size: {_CTA_PX}px;
    font-weight: 700;
    height: 48px;
    padding: 0 20px;
    border-radius: 6px;
    letter-spacing: -0.5px;
    margin-bottom: 24px;
    width: fit-content;
    white-space: nowrap;
  }}

  /* 헤드라인: 딥 브라운 #3E2723 */
  .headline {{
    font-size: {_SIZE_58PX}px;
    font-weight: 700;
    color: #3E2723;
    line-height: {_LH_1_2};
    letter-spacing: -1px;
    margin-bottom: 18px;
    white-space: pre-line;
    text-shadow: 0 1px 2px rgba(0,0,0,0.15);
  }}

  /* 서브카피: 다크 골드 #A07828 (밝은 배경이므로) */
  .sub-copy {{
    font-size: {_CTA_PX}px;
    font-weight: 500;
    color: #A07828;
    letter-spacing: -0.5px;
    margin-bottom: 34px;
    white-space: nowrap;
  }}

  /* CTA 버튼 */
  .cta-btn {{
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, #C9A84C 0%, #D4B87A 100%);
    color: #1A0E00;
    font-size: {_SIZE_44PX}px;
    font-weight: 700;
    height: 56px;
    width: 280px;
    border-radius: 6px;
    letter-spacing: -0.5px;
    box-shadow: 0 4px 16px rgba(201,168,76,0.35);
    white-space: nowrap;
  }}
</style>
</head>
<body>
<div class="container">
  <!-- Gemini 배경 이미지 -->
  <div class="bg-image"></div>
  <!-- 크림 패널 -->
  <div class="cream-panel"></div>
  <!-- 크림 블렌딩 -->
  <div class="cream-blend"></div>
  <!-- 골드 세로 액센트바 -->
  <div class="accent-bar"></div>
  <!-- 텍스트 영역 -->
  <div class="text-area">
    <div class="brand-badge">서울대보험쌤 · TOP사업단</div>
    <div class="headline">서울대 출신 <span style="color:#A07828">지점장</span>과<br>함께 시작합니다</div>
    <div class="sub-copy">AI자동화&nbsp;&nbsp;|&nbsp;&nbsp;멘토링&nbsp;&nbsp;|&nbsp;&nbsp;100일 로드맵</div>
    <div class="cta-btn">조직 설계 상담 받기 →</div>
  </div>
</div>
</body>
</html>"""


def make_html_1080x1080(bg_path: Path) -> str:
    """1080x1080 정사각형 배너 HTML 생성 (M3-2 밝은 톤)."""
    bg_uri = f"file://{bg_path.resolve()}"
    return f"""<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{FONT_DIR}/Pretendard-Bold.otf') format('opentype');
    font-weight: 700;
  }}
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{FONT_DIR}/Pretendard-Medium.otf') format('opentype');
    font-weight: 500;
  }}
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{FONT_DIR}/Pretendard-SemiBold.otf') format('opentype');
    font-weight: 600;
  }}
  * {{ margin: 0; padding: 0; box-sizing: border-box; }}

  body {{
    width: 1080px;
    height: 1080px;
    overflow: hidden;
    font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    background: #FFF8E7;
  }}

  .container {{
    position: relative;
    width: 1080px;
    height: 1080px;
    overflow: hidden;
  }}

  /* Gemini 배경 이미지: 전체 */
  .bg-image {{
    position: absolute;
    inset: 0;
    background-image: url('{bg_uri}');
    background-size: cover;
    background-position: center;
  }}

  /* 크림 반투명 오버레이: 전체 opacity 0.55 */
  .cream-overlay {{
    position: absolute;
    inset: 0;
    background: rgba(255, 248, 231, 0.55);
  }}

  /* 콘텐츠 레이아웃: 패딩 좌우 72px, 상하 80px, 중앙정렬 */
  .content {{
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 80px 72px;
    gap: 32px;
    text-align: center;
  }}

  /* 크림 반투명 텍스트 패널 */
  .text-panel {{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 860px;
    padding: 56px 48px;
    background: rgba(255, 248, 231, 0.82);
    border-radius: 12px;
    backdrop-filter: blur(4px);
    box-shadow: 0 4px 20px rgba(0,0,0,0.08);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 32px;
    text-align: center;
  }}

  /* 브랜드 뱃지 */
  .brand-badge {{
    display: inline-flex;
    align-items: center;
    background: #C9A84C;
    color: #1A0E00;
    font-size: {_CTA_PX}px;
    font-weight: 700;
    height: 52px;
    padding: 0 24px;
    border-radius: 6px;
    letter-spacing: -0.5px;
    white-space: nowrap;
  }}

  /* 헤드라인: 딥 브라운 #3E2723, 58px ExtraBold, 중앙정렬 */
  .headline {{
    font-size: {_SIZE_58PX}px;
    font-weight: 800;
    color: #3E2723;
    line-height: {_LH_1_2};
    letter-spacing: -1px;
    text-align: center;
    white-space: pre-line;
    text-shadow: 0 1px 8px rgba(255, 248, 231, 0.6);
  }}

  /* 서브카피: 다크 골드 #8A6520, 44px SemiBold */
  .sub-copy {{
    font-size: {_SIZE_44PX}px;
    font-weight: 600;
    color: #8A6520;
    letter-spacing: -0.5px;
    text-align: center;
    text-shadow: 0 0 6px rgba(255, 248, 231, 0.7);
    white-space: nowrap;
  }}

  /* CTA 버튼 */
  .cta-btn {{
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, #C9A84C 0%, #D4B87A 100%);
    color: #1A0E00;
    font-size: {_SIZE_48PX}px;
    font-weight: 700;
    height: 68px;
    width: 420px;
    border-radius: 6px;
    letter-spacing: -0.5px;
    box-shadow: 0 6px 24px rgba(201,168,76,0.40);
    white-space: nowrap;
  }}
</style>
</head>
<body>
<div class="container">
  <!-- Gemini 배경 이미지 -->
  <div class="bg-image"></div>
  <!-- 크림 반투명 오버레이 (opacity 0.55) -->
  <div class="cream-overlay"></div>

  <!-- 크림 반투명 텍스트 패널 -->
  <div class="text-panel">
    <div class="brand-badge">서울대보험쌤 · TOP사업단</div>
    <div class="headline">서울대 출신 <span style="color:#A07828">지점장</span>과<br>함께 시작합니다</div>
    <div class="sub-copy">AI자동화&nbsp;&nbsp;|&nbsp;&nbsp;멘토링&nbsp;&nbsp;|&nbsp;&nbsp;100일 로드맵</div>
    <div class="cta-btn">조직 설계 상담 받기 →</div>
  </div>
</div>
</body>
</html>"""


# ── 폴백 HTML (배경 이미지 없을 때: 따뜻한 크림 그라데이션) ─────────────────────────

def make_html_no_bg_1200x628() -> str:
    """배경 이미지 없는 1200x628 폴백 배너 (크림 그라데이션)."""
    return f"""<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{FONT_DIR}/Pretendard-Bold.otf') format('opentype');
    font-weight: 700;
  }}
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{FONT_DIR}/Pretendard-Medium.otf') format('opentype');
    font-weight: 500;
  }}
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{FONT_DIR}/Pretendard-SemiBold.otf') format('opentype');
    font-weight: 600;
  }}
  * {{ margin: 0; padding: 0; box-sizing: border-box; }}

  body {{
    width: 1200px;
    height: 628px;
    overflow: hidden;
    font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    background: #FFF8E7;
  }}

  .container {{
    position: relative;
    width: 1200px;
    height: 628px;
    overflow: hidden;
    background: linear-gradient(135deg, #FFF8E7 0%, #F5E8C8 40%, #EDD9A0 70%, #E8CC88 100%);
  }}

  .text-area {{
    position: absolute;
    left: 0;
    top: 0;
    width: 700px;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 48px 40px 48px 60px;
    gap: 0;
  }}

  .brand-badge {{
    display: inline-flex;
    align-items: center;
    background: #C9A84C;
    color: #1A0E00;
    font-size: {_CTA_PX}px;
    font-weight: 700;
    height: 48px;
    padding: 0 20px;
    border-radius: 6px;
    letter-spacing: -0.5px;
    margin-bottom: 24px;
    width: fit-content;
    white-space: nowrap;
  }}

  .headline {{
    font-size: {_SIZE_58PX}px;
    font-weight: 700;
    color: #3E2723;
    line-height: {_LH_1_2};
    letter-spacing: -1px;
    margin-bottom: 18px;
    white-space: pre-line;
  }}

  .sub-copy {{
    font-size: {_SIZE_42PX}px;
    font-weight: 500;
    color: #A07828;
    letter-spacing: -0.5px;
    margin-bottom: 34px;
  }}

  .cta-btn {{
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, #C9A84C 0%, #D4B87A 100%);
    color: #1A0E00;
    font-size: {_SIZE_44PX}px;
    font-weight: 700;
    height: 56px;
    width: 280px;
    border-radius: 6px;
    letter-spacing: -0.5px;
    box-shadow: 0 4px 16px rgba(201,168,76,0.35);
    white-space: nowrap;
  }}
</style>
</head>
<body>
<div class="container">
  <div class="text-area">
    <div class="brand-badge">서울대보험쌤 · TOP사업단</div>
    <div class="headline">서울대 출신 지점장과&#10;함께 시작합니다</div>
    <div class="sub-copy">AI자동화&nbsp;&nbsp;|&nbsp;&nbsp;멘토링&nbsp;&nbsp;|&nbsp;&nbsp;100일 로드맵</div>
    <div class="cta-btn">조직 설계 상담 받기 →</div>
  </div>
</div>
</body>
</html>"""


def make_html_no_bg_1080x1080() -> str:
    """배경 이미지 없는 1080x1080 폴백 배너 (크림 그라데이션)."""
    return f"""<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{FONT_DIR}/Pretendard-Bold.otf') format('opentype');
    font-weight: 700;
  }}
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{FONT_DIR}/Pretendard-Medium.otf') format('opentype');
    font-weight: 500;
  }}
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{FONT_DIR}/Pretendard-SemiBold.otf') format('opentype');
    font-weight: 600;
  }}
  * {{ margin: 0; padding: 0; box-sizing: border-box; }}

  body {{
    width: 1080px;
    height: 1080px;
    overflow: hidden;
    font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
  }}

  .container {{
    position: relative;
    width: 1080px;
    height: 1080px;
    overflow: hidden;
    background: linear-gradient(160deg, #FFF8E7 0%, #F5E8C8 30%, #EDD9A0 60%, #E8CC88 100%);
  }}

  .content {{
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 80px 72px;
    gap: 32px;
    text-align: center;
  }}

  .brand-badge {{
    display: inline-flex;
    align-items: center;
    background: #C9A84C;
    color: #1A0E00;
    font-size: {_CTA_PX}px;
    font-weight: 700;
    height: 52px;
    padding: 0 24px;
    border-radius: 6px;
    letter-spacing: -0.5px;
    white-space: nowrap;
  }}

  .headline {{
    font-size: {_SIZE_62PX}px;
    font-weight: 700;
    color: #3E2723;
    line-height: {_LH_1_2};
    letter-spacing: -1px;
    text-align: center;
    white-space: pre-line;
  }}

  .sub-copy {{
    font-size: {_SIZE_44PX}px;
    font-weight: 500;
    color: #A07828;
    letter-spacing: -0.5px;
    text-align: center;
  }}

  .cta-btn {{
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, #C9A84C 0%, #D4B87A 100%);
    color: #1A0E00;
    font-size: {_SIZE_48PX}px;
    font-weight: 700;
    height: 68px;
    width: 420px;
    border-radius: 6px;
    letter-spacing: -0.5px;
    box-shadow: 0 6px 24px rgba(201,168,76,0.40);
    white-space: nowrap;
  }}
</style>
</head>
<body>
<div class="container">
  <div class="content">
    <div class="brand-badge">서울대보험쌤 · TOP사업단</div>
    <div class="headline">서울대 출신 지점장과&#10;함께 시작합니다</div>
    <div class="sub-copy">AI자동화&nbsp;&nbsp;·&nbsp;&nbsp;멘토링&nbsp;&nbsp;·&nbsp;&nbsp;100일 로드맵</div>
    <div class="cta-btn">조직 설계 상담 받기 →</div>
  </div>
</div>
</body>
</html>"""


# ── Playwright 캡처 ───────────────────────────────────────────────────────────

def capture_html_to_png(html_content: str, width: int, height: int, output_path: Path) -> None:
    """HTML을 Playwright로 캡처하여 PNG로 저장합니다."""
    tmp_html = TMP_DIR / f"_tmp_m3_2_{width}x{height}.html"
    tmp_html.write_text(html_content, encoding="utf-8")

    with sync_playwright() as p:
        browser = p.chromium.launch()
        try:
            page = browser.new_page(viewport={"width": width, "height": height})
            page.goto(f"file://{tmp_html.resolve()}", wait_until="networkidle")
            page.wait_for_timeout(2000)  # 폰트 로딩 대기
            output_path.parent.mkdir(parents=True, exist_ok=True)
            page.screenshot(path=str(output_path), type="png", clip={
                "x": 0, "y": 0, "width": width, "height": height
            })
            print(f"  [캡처] {output_path} ({output_path.stat().st_size / 1024:.0f} KB)")
        finally:
            browser.close()

    tmp_html.unlink(missing_ok=True)


# ── 메인 ─────────────────────────────────────────────────────────────────────

def main():
    print("=" * 60)
    print("M3-2 서울대보험쌤 × 관리자 비전 배너 생성 시작")
    print("=" * 60)

    TMP_DIR.mkdir(parents=True, exist_ok=True)
    OUTPUT_DIR.mkdir(parents=True, exist_ok=True)

    # 1. 배경 이미지 생성
    try:
        bg_path = generate_background()
    except Exception as e:
        print(f"[오류] 배경 생성 실패: {e}")
        print("[폴백] 크림 그라데이션 배경으로 대체합니다.")
        bg_path = None

    # 2. 1200x628 배너 생성
    out_1200 = OUTPUT_DIR / "m3-2-1200x628.png"
    print("\n[1] 1200x628 가로형 배너 생성 중...")
    try:
        html_1200 = make_html_1200x628(bg_path) if bg_path else make_html_no_bg_1200x628()
        capture_html_to_png(html_1200, 1200, 628, out_1200)
        print(f"  완료: {out_1200}")
    except Exception as e:
        print(f"  [오류] {e}")
        raise

    # 3. 1080x1080 배너 생성
    out_1080 = OUTPUT_DIR / "m3-2-1080x1080.png"
    print("\n[2] 1080x1080 정사각형 배너 생성 중...")
    try:
        html_1080 = make_html_1080x1080(bg_path) if bg_path else make_html_no_bg_1080x1080()
        capture_html_to_png(html_1080, 1080, 1080, out_1080)
        print(f"  완료: {out_1080}")
    except Exception as e:
        print(f"  [오류] {e}")
        raise

    print("\n" + "=" * 60)
    print("생성 완료!")
    print(f"  1200x628 : {out_1200}")
    print(f"  1080x1080: {out_1080}")
    print("=" * 60)


if __name__ == "__main__":
    main()
