#!/usr/bin/env python3
"""Venus A-5 CTA slide — Meta Carousel Slide (밝은 CTA 슬라이드).

Hybrid: Gemini background (brightest dawn/light scene) +
        Playwright HTML overlay (Korean text, gold CTA button, trust anchors).
Output: /home/jay/workspace/output/meta-ads/a-group-venus/venus-A5-cta.png

Design:
- Background: Brightest in the carousel — warm light streaming through doorway/window
- Headline: "전략을 바꿀 준비가 됐다면, 지금 딱 한 번 물어보세요." (딱 한 번 gold accent)
- Subheadline: "서울대보험쌤 팀장이 직접 답합니다. 조건 없는 상담, 당신 상황에 맞는 방향 제시."
- CTA Button: "무료 상담 신청하기" — dark text #1A0E00 on gold background (WCAG AAA)
- Trust anchors: "조건 없음 · 무료 상담 · 팀장 직접 응대"
- Page indicator: 5/5
"""

from __future__ import annotations

import base64
import sys
import time
from pathlib import Path

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

# ── paths ──────────────────────────────────────────────────────────────────────
OUTPUT_DIR = WORKSPACE_ROOT / "output/meta-ads/a-group-venus"
BG_PATH    = OUTPUT_DIR / "_bg_venus_a5_cta.jpg"
HTML_PATH  = OUTPUT_DIR / "_venus_a5_cta_template.html"
OUT_PATH   = OUTPUT_DIR / "venus-A5-cta.png"
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)

# ── Gemini config ──────────────────────────────────────────────────────────────
sys.path.insert(0, str(WORKSPACE_ROOT / "tools/ai-image-gen"))
import gcloud_auth  # noqa: E402

GEMINI_API_BASE = "https://generativelanguage.googleapis.com/v1beta"
MODEL_PRIMARY   = "gemini-3-pro-image-preview"
MODEL_FALLBACK  = "gemini-3.1-flash-image-preview"
MODEL_FALLBACK2 = "gemini-2.5-flash-preview-04-17"
SCOPE           = "https://www.googleapis.com/auth/generative-language"

# ── Background prompt: brightest, most hopeful slide ──────────────────────────
BG_PROMPT = """
Photorealistic warm sunrise/dawn light pouring through a wide open doorway or large floor-to-ceiling window.
Brilliant golden morning sunlight streams dramatically inward, creating beautiful volumetric god-rays
and warm bokeh particles floating in the air. The scene radiates hope, new beginnings, and forward momentum.

COMPOSITION: 1:1 square, 1080x1080px. Full bleed. No text, no people, no faces, no logos.

VISUAL CONCEPT:
A threshold moment — standing at the edge of a bright new beginning. Warm golden light floods in
from a large open door or expansive window, suggesting the final step into a new chapter.
_SIZE_34PX = 34
_CTA_PX = CTA_MIN_PX
_SIZE_50PX = 50
_SIZE_70PX = 70
_SIZE_78PX = 78
_LH_1_24 = 1.24
_LH_1_72 = 1.72
The light is brilliant, warm, and enveloping — not harsh, but luminous and welcoming.
Soft lens flare and golden dust motes drift in the air, catching the dawn light.
This is the BRIGHTEST image in a 5-slide carousel series — maximum warmth and luminosity.

BACKGROUND ELEMENTS:
- Dominant warm cream/ivory base (#F5F0E8, #FFF8EC) — luminous and bright
- Brilliant warm golden sunrise light (#E8C870 / #C9A84C tones) streaming from center-top or upper portion
- Beautiful volumetric light rays (god rays) piercing through the opening
- Soft golden bokeh circles and light particles floating in the air
- A subtle architectural element: door frame or window frame barely visible as a silhouette
- The lower 40% of the image is slightly darker warm cream — space for text overlay
- Overall: airy, premium, "threshold of hope and success" feeling

MOOD / ATMOSPHERE:
- Hope. New beginning. Clarity. The courage to take one step.
- "Just one question away from change" — lowest possible barrier perception
- Premium Korean financial advisory — warm and welcoming
- Action-ready energy: the dawn of a new strategy

COLOR PALETTE:
- Primary: Warm cream (#FFF8EC), golden ivory (#F5EDD8), soft off-white (#FFFDF7)
- Golden accent glow: #E8C870 to #C9A84C — rich, warm, visible but gentle
- No dark tones whatsoever — this is the brightest, most hopeful slide
- No cool tones — only warm cream/gold/ivory family
- Maximum warmth: the payoff moment after a dark-to-light journey

PHOTOGRAPHIC QUALITY:
- Shot on Hasselblad H6D-100c, 35mm lens, f/2.0 aperture
- Shallow depth of field with beautiful bokeh background
- Soft natural vignette at edges — bright center convergence
- Cinematic warmth — Christopher Nolan / Terrence Malick golden hour aesthetic

STYLE REQUIREMENTS:
- NO people, faces, hands, or figures
- NO text, numbers, labels, or UI elements
- NO dark zones — entire image must be bright and luminous
- Photorealistic commercial photography quality
- Premium advertising background — supportive of overlaid dark text
- The content overlay will use dark text (#1A0E00) so background MUST remain bright throughout
- Ensure the center and bottom areas have sufficient brightness and warmth
"""


# ── Step 1: Generate Gemini background ────────────────────────────────────────

def generate_background() -> Path:
    if BG_PATH.exists():
        print(f"[BG] 기존 배경 이미지 재사용: {BG_PATH}")
        return BG_PATH

    print("[BG] Gemini API로 배경 이미지 생성 중...")
    token = gcloud_auth.get_service_account_token(SCOPE)

    def _call(model_id: str) -> requests.Response:
        url = f"{GEMINI_API_BASE}/models/{model_id}:generateContent"
        headers = {
            "Authorization": f"Bearer {token}",
            "Content-Type": "application/json",
        }
        payload = {
            "contents": [{"parts": [{"text": BG_PROMPT}]}],
            "generationConfig": {
                "responseModalities": ["IMAGE", "TEXT"],
                "temperature": 1.0,
            },
        }
        return requests.post(url, headers=headers, json=payload, timeout=300)

    t0 = time.time()
    for model_id in [MODEL_PRIMARY, MODEL_FALLBACK, MODEL_FALLBACK2]:
        print(f"  -> 모델 시도: {model_id}")
        try:
            resp = _call(model_id)
        except Exception as e:
            print(f"  [WARN] 요청 실패: {e}")
            continue

        if resp.status_code in (403, 404, 429):
            print(f"  [WARN] HTTP {resp.status_code} — 다음 모델 시도")
            continue

        try:
            resp.raise_for_status()
        except requests.HTTPError as e:
            print(f"  [ERROR] HTTP {e.response.status_code}: {e.response.text[:300]}")
            continue

        data = resp.json()
        candidates = data.get("candidates", [])
        if not candidates:
            print(f"  [WARN] candidates 없음: {str(data)[:200]}")
            continue

        parts = candidates[0].get("content", {}).get("parts", [])
        img_part = next((p for p in parts if "inlineData" in p), None)
        if img_part is None:
            texts = [p.get("text", "") for p in parts if "text" in p]
            print(f"  [WARN] 이미지 없음. 텍스트: {texts[:2]}")
            continue

        mime  = img_part["inlineData"].get("mimeType", "image/jpeg")
        b64   = img_part["inlineData"]["data"]
        ext   = ".jpg" if "jpeg" in mime else ".png"
        fpath = BG_PATH.with_suffix(ext)
        fpath.write_bytes(base64.b64decode(b64))
        print(f"[BG] 완료: {fpath.name} ({fpath.stat().st_size:,} bytes, {time.time()-t0:.1f}초)")
        return fpath

    raise RuntimeError("[BG] 모든 모델 시도 실패")


# ── Step 2: Build HTML overlay ──────────────────────────────────────────────────

def build_html(bg_path: Path) -> str:
    bg_url = f"file://{bg_path.resolve()}"
    font_dir = str(FONT_DIR)

    return f"""<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<style>
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{font_dir}/PretendardVariable.ttf') format('truetype');
    font-weight: 100 900;
  }}
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{font_dir}/Pretendard-Black.otf') format('opentype');
    font-weight: 900;
  }}
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{font_dir}/Pretendard-ExtraBold.otf') format('opentype');
    font-weight: 800;
  }}
  @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-Regular.otf') format('opentype');
    font-weight: 400;
  }}

  * {{ margin: 0; padding: 0; box-sizing: border-box; }}

  html, body {{
    width: 1080px;
    height: 1080px;
    overflow: hidden;
    background: #FFF8EC;
  }}

  /* ── Canvas: background image ── */
  .canvas {{
    width: 1080px;
    height: 1080px;
    position: relative;
    background-image: url('{bg_url}');
    background-size: cover;
    background-position: center center;
    font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    overflow: hidden;
  }}

  /* ── Very light warm overlay — preserves bright background, adds bottom contrast ── */
  .overlay {{
    position: absolute;
    inset: 0;
    background:
      radial-gradient(ellipse 80% 50% at 50% 30%, rgba(255, 252, 240, 0.25) 0%, transparent 70%),
      linear-gradient(
        180deg,
        rgba(255, 252, 245, 0.30) 0%,
        rgba(255, 250, 238, 0.15) 30%,
        rgba(245, 240, 228, 0.05) 55%,
        rgba(255, 248, 228, 0.45) 75%,
        rgba(255, 245, 215, 0.70) 100%
      );
    pointer-events: none;
  }}

  /* All content above overlay */
  .content {{
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 0 72px;
  }}

  /* ── PAGE INDICATOR (bottom-right absolute) ── */
  .page-indicator {{
    position: absolute;
    bottom: 52px;
    right: 58px;
    font-family: 'Pretendard', sans-serif;
    font-size: {_SIZE_34PX}px;
    font-weight: 500;
    color: rgba(100, 75, 25, 0.55);
    letter-spacing: 0.06em;
    z-index: 10;
    font-variant-numeric: tabular-nums;
  }}

  /* ── TOP SPACER ── */
  .top-spacer {{
    height: 108px;
    flex-shrink: 0;
  }}

  /* ── HEADLINE SECTION — center ── */
  .headline-section {{
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 0 8px;
  }}

  /* Decorative top element — small gold ornament above headline */
  .top-ornament {{
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 32px;
  }}

  .ornament-line {{
    width: 60px;
    height: 1.5px;
    background: linear-gradient(90deg, transparent, #C9A84C);
  }}

  .ornament-line.right {{
    background: linear-gradient(90deg, #C9A84C, transparent);
  }}

  .ornament-diamond {{
    width: 10px;
    height: 10px;
    background: #C9A84C;
    transform: rotate(45deg);
    box-shadow: 0 0 8px rgba(201, 168, 76, 0.60);
    flex-shrink: 0;
  }}

  /* Headline */
  .headline {{
    font-family: 'Pretendard', sans-serif;
    font-size: {_SIZE_70PX}px;
    font-weight: 900;
    line-height: {_LH_1_24};
    letter-spacing: -0.030em;
    color: #1A0E00;
    word-break: keep-all;
    text-align: center;
    margin-bottom: 28px;
  }}

  /* "딱 한 번" accent: gold color + underline + slightly larger */
  .headline .accent {{
    color: #C9A84C;
    font-weight: 900;
    text-decoration: underline;
    text-decoration-color: rgba(201, 168, 76, 0.80);
    text-decoration-thickness: 4px;
    text-underline-offset: 8px;
    font-size: {_SIZE_78PX}px;
  }}

  /* Gold divider: line-dot-line */
  .divider {{
    display: flex;
    align-items: center;
    gap: 14px;
    width: 100%;
    max-width: 500px;
    margin-bottom: 28px;
  }}

  .divider-line {{
    flex: 1;
    height: 1.5px;
    background: linear-gradient(90deg, transparent, rgba(201, 168, 76, 0.50), transparent);
  }}

  .divider-dot {{
    width: 8px;
    height: 8px;
    background: #C9A84C;
    border-radius: 50%;
    flex-shrink: 0;
    box-shadow: 0 0 8px rgba(201, 168, 76, 0.65);
  }}

  /* Subheadline */
  .subcopy {{
    font-family: 'Pretendard', sans-serif;
    font-size: {_CTA_PX}px;
    font-weight: 500;
    line-height: {_LH_1_72};
    color: rgba(40, 28, 8, 0.78);
    text-align: center;
    word-break: keep-all;
    letter-spacing: -0.015em;
  }}

  /* ── BOTTOM SECTION ── */
  .bottom-section {{
    width: 100%;
    padding: 0 0 68px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 24px;
    flex-shrink: 0;
  }}

  /* ── CTA BUTTON ── */
  /* SUCCESS pattern #10: dark text on gold — WCAG AAA (#1A0E00 on gold = 8.5:1+) */
  .cta-btn {{
    width: 100%;
    max-width: 880px;
    background: linear-gradient(
      135deg,
      #D4A84C 0%,
      #F0CA60 35%,
      #E8C255 55%,
      #C9A030 80%,
      #B88A20 100%
    );
    color: #1A0E00;
    font-family: 'Pretendard', sans-serif;
    font-size: {_SIZE_50PX}px;
    font-weight: 900;
    letter-spacing: -0.020em;
    text-align: center;
    padding: 36px 48px;
    border-radius: 20px;
    word-break: keep-all;
    box-shadow:
      0 0 56px rgba(201, 168, 76, 0.45),
      0 10px 36px rgba(0, 0, 0, 0.18),
      inset 0 2px 0 rgba(255, 255, 255, 0.42),
      inset 0 -3px 0 rgba(0, 0, 0, 0.10);
    position: relative;
    overflow: hidden;
  }}

  /* Subtle inner highlight */
  .cta-btn::after {{
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 45%;
    background: linear-gradient(180deg, rgba(255,255,255,0.20) 0%, transparent 100%);
    border-radius: 20px 20px 0 0;
  }}

  /* ── TRUST ANCHOR ── */
  .trust-row {{
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 18px;
  }}

  .trust-item {{
    display: flex;
    align-items: center;
    gap: 8px;
    font-family: 'Pretendard', sans-serif;
    font-size: {_SIZE_34PX}px;
    font-weight: 600;
    color: rgba(60, 42, 10, 0.70);
    letter-spacing: -0.01em;
  }}

  .trust-icon {{
    width: 26px;
    height: 26px;
    flex-shrink: 0;
  }}

  .trust-sep {{
    width: 5px;
    height: 5px;
    background: rgba(201, 168, 76, 0.60);
    border-radius: 50%;
    flex-shrink: 0;
  }}

</style>
</head>
<body>
<div class="canvas">

  <!-- Warm overlay -->
  <div class="overlay"></div>

  <!-- Page indicator (absolute bottom-right) -->
  <div class="page-indicator">5/5</div>

  <!-- Content layer -->
  <div class="content">

    <!-- Top spacer -->
    <div class="top-spacer"></div>

    <!-- HEADLINE SECTION: center -->
    <div class="headline-section">

      <!-- Gold ornament above headline -->
      <div class="top-ornament">
        <div class="ornament-line"></div>
        <div class="ornament-diamond"></div>
        <div class="ornament-line right"></div>
      </div>

      <!-- Headline: "딱 한 번" accented in gold with underline + larger size -->
      <h1 class="headline">
        전략을 바꿀 준비가 됐다면,<br>
        지금 <span class="accent">딱 한 번</span> 물어보세요.
      </h1>

      <!-- Divider: line-dot-line -->
      <div class="divider">
        <div class="divider-line"></div>
        <div class="divider-dot"></div>
        <div class="divider-line"></div>
      </div>

      <!-- Subheadline -->
      <p class="subcopy">
        서울대보험쌤 팀장이 직접 답합니다.<br>
        조건 없는 상담, 당신 상황에 맞는 방향 제시.
      </p>

    </div>

    <!-- BOTTOM: CTA + Trust -->
    <div class="bottom-section">

      <!-- CTA Button: dark text #1A0E00 on gold (WCAG AAA, SUCCESS pattern #10) -->
      <div class="cta-btn">무료 상담 신청하기</div>

      <!-- Trust anchors: "조건 없음 · 무료 상담 · 팀장 직접 응대" -->
      <div class="trust-row">
        <div class="trust-item">
          <!-- Checkmark icon -->
          <svg class="trust-icon" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
            <circle cx="13" cy="13" r="11" stroke="#C9A84C" stroke-width="2"/>
            <path d="M7.5 13L11 16.5L18.5 9" stroke="#C9A84C" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
          </svg>
          조건 없음
        </div>
        <div class="trust-sep"></div>
        <div class="trust-item">
          <!-- Gift/free icon -->
          <svg class="trust-icon" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
            <rect x="4" y="11" width="18" height="12" rx="2" stroke="#C9A84C" stroke-width="2"/>
            <path d="M13 11V23" stroke="#C9A84C" stroke-width="2" stroke-linecap="round"/>
            <path d="M4 15H22" stroke="#C9A84C" stroke-width="2" stroke-linecap="round"/>
            <path d="M13 11C13 11 10 8 10 6C10 4.9 10.9 4 12 4C13 4 13 5.5 13 5.5C13 5.5 13 4 14 4C15.1 4 16 4.9 16 6C16 8 13 11 13 11Z" stroke="#C9A84C" stroke-width="1.8" stroke-linejoin="round"/>
          </svg>
          무료 상담
        </div>
        <div class="trust-sep"></div>
        <div class="trust-item">
          <!-- Person/direct icon -->
          <svg class="trust-icon" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
            <circle cx="13" cy="9" r="4.5" stroke="#C9A84C" stroke-width="2"/>
            <path d="M4.5 23C4.5 18.9 8.4 15.5 13 15.5C17.6 15.5 21.5 18.9 21.5 23" stroke="#C9A84C" stroke-width="2" stroke-linecap="round"/>
          </svg>
          팀장 직접 응대
        </div>
      </div>

    </div>

  </div><!-- /content -->
</div><!-- /canvas -->
</body>
</html>"""


def write_html(bg_path: Path) -> Path:
    html_content = build_html(bg_path)
    HTML_PATH.write_text(html_content, encoding="utf-8")
    print(f"[HTML] 오버레이 저장: {HTML_PATH}")
    return HTML_PATH


# ── Step 3: Playwright screenshot ─────────────────────────────────────────────

def capture(html_path: Path, out_path: Path) -> None:
    print("[RENDER] Playwright 캡처 시작...")
    with sync_playwright() as p:
        browser = p.chromium.launch(args=["--no-sandbox", "--disable-dev-shm-usage"])
        try:
            page = browser.new_page(viewport={"width": 1080, "height": 1080})
            page.goto(f"file://{html_path.resolve()}", wait_until="networkidle")
            # Wait for fonts and background image to fully render
            page.evaluate("async () => { await document.fonts.ready; }")
            page.wait_for_timeout(3000)
            out_path.parent.mkdir(parents=True, exist_ok=True)
            page.screenshot(
                path=str(out_path),
                type="png",
                clip={"x": 0, "y": 0, "width": 1080, "height": 1080},
            )
        finally:
            browser.close()
    size_kb = out_path.stat().st_size / 1024
    print(f"[RENDER] 완료: {out_path} ({size_kb:.0f} KB)")


# ── Main ───────────────────────────────────────────────────────────────────────

if __name__ == "__main__":
    t_start = time.time()
    print("=" * 60)
    print("Venus A-5 CTA — Meta 캐러셀 광고 (밝은 희망 톤)")
    print(f"출력: {OUT_PATH}")
    print("=" * 60)

    bg = generate_background()
    html = write_html(bg)
    capture(html, OUT_PATH)

    elapsed = time.time() - t_start
    print(f"\n[완료] {OUT_PATH.name}  ({elapsed:.1f}초 총 소요)")
    if OUT_PATH.exists():
        print(f"       파일 크기: {OUT_PATH.stat().st_size / 1024:.0f} KB")
        print(f"       경로: {OUT_PATH}")
