#!/usr/bin/env python3
"""
Meta carousel slide A-5 (CTA) 생성 스크립트
Hybrid pipeline: Gemini background + HTML/CSS Playwright overlay
Output: /home/jay/workspace/output/meta-ads/a-group-v6/pilot/pilot-A5-cta.png
"""

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 WORKSPACE_ROOT

# ──────────────────────────────────────────────────────
# 경로 설정
# ──────────────────────────────────────────────────────
TOOL_DIR = Path(__file__).parent
OUTPUT_DIR = WORKSPACE_ROOT / "output/meta-ads/a-group-v6/pilot"
BG_PATH = OUTPUT_DIR / "pilot-A5-bg.jpg"
HTML_PATH = OUTPUT_DIR / "pilot-A5-overlay.html"
FINAL_PATH = OUTPUT_DIR / "pilot-A5-cta.png"

# gcloud_auth 모듈 경로 추가
sys.path.insert(0, str(TOOL_DIR))
import gcloud_auth
_SIZE_22PX = 22
_SIZE_26PX = 26
_SIZE_36PX = 36
_SIZE_46PX = 46
_SIZE_68PX = 68
_LH_1_22 = 1.22
_LH_1_65 = 1.65

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

GEMINI_BG_PROMPT = """
Create a cinematic, premium insurance consultation advertisement background image.

COMPOSITION: Square 1:1 format (1080x1080px). Abstract architectural space.
SCENE: Dark, deep navy interior space — like the threshold of an important decision.
View from slightly below center, looking toward a wide-open double door or archway.
Through the opening: warm golden-amber volumetric light cascades in dramatic god-rays,
illuminating floating dust particles. The space beyond is warm, brilliant, inviting.
The foreground/corridor is deep navy (#1A2F5E) fading to almost black at corners.

LIGHTING: Extreme chiaroscuro. Deep navy darkness in corners and edges.
Brilliant golden-amber glow (#C9A84C tones) streaming through the center opening.
Volumetric light rays — like sunlight through cathedral glass. Cinematic depth.
Subtle radial glow emanating from center-top area of the image.

COLOR GRADE: Deep navy (#1A2F5E) dominant background. Warm gold (#C9A84C) light source center.
Rich navy-to-gold gradient across the image. No cold blues, no grey. Warm and vivid.

STYLE: Like Denis Villeneuve / Christopher Nolan cinematography. Ultra-premium.
Clean, abstract — NO people, NO faces, NO text, NO logos, NO UI elements.
No arrows, no buttons, no symbols. Pure atmospheric cinematic background only.

MOOD: The warmest, most vivid, most hopeful slide of a 5-slide series.
"A door opening at the end of a long journey." Clear, solid energy. Decisive.

ASPECT: Exactly 1:1 square, 1080x1080px. Maximum cinematic quality.
"""


MODELS_TO_TRY = [
    "gemini-2.5-flash-image",
    "gemini-3-pro-image-preview",
    "gemini-3.1-flash-image-preview",
]


def generate_gemini_background(token: str, output_path: Path) -> bool:
    """Gemini REST API로 배경 이미지 생성 (SA Bearer 토큰 사용)."""
    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json",
    }
    payload = {
        "contents": [{"parts": [{"text": GEMINI_BG_PROMPT}]}],
        "generationConfig": {"responseModalities": ["IMAGE", "TEXT"]},
    }

    for model_id in MODELS_TO_TRY:
        url = f"https://generativelanguage.googleapis.com/v1beta/models/{model_id}:generateContent"
        print(f"[배경 생성] 모델 {model_id} 호출 중...")
        start = time.time()

        try:
            resp = requests.post(url, headers=headers, json=payload, timeout=180)
        except requests.RequestException 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]}")
            return False

        elapsed = time.time() - start
        data = resp.json()

        candidates = data.get("candidates", [])
        if not candidates:
            print(f"[ERROR] candidates 없음: {json.dumps(data)[:300]}")
            return False

        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:
            text_parts = [p.get("text", "") for p in parts if "text" in p]
            print(f"[ERROR] 이미지 파트 없음. 텍스트: {text_parts[:2]}")
            return False

        image_bytes = base64.b64decode(image_part["inlineData"]["data"])
        output_path.write_bytes(image_bytes)
        print(f"[배경 생성] 완료: {output_path} ({len(image_bytes):,} bytes, {elapsed:.1f}초)")
        return True

    print("[ERROR] 모든 모델 시도 실패.")
    return False


# ──────────────────────────────────────────────────────
# HTML 오버레이 템플릿 생성
# ──────────────────────────────────────────────────────

HTML_TEMPLATE = """<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=1080" />
  <title>Meta Ad A-5 CTA</title>
  <style>
    @font-face {{
      font-family: 'Pretendard';
      src: local('Pretendard-Black'),
           url('/home/jay/.local/share/fonts/Pretendard/Pretendard-Black.otf') format('opentype');
      font-weight: 900;
    }}
    @font-face {{
      font-family: 'Pretendard';
      src: local('Pretendard-Bold'),
           url('/home/jay/.local/share/fonts/Pretendard/Pretendard-Bold.otf') format('opentype');
      font-weight: 700;
    }}
    @font-face {{
      font-family: 'Pretendard';
      src: local('Pretendard-SemiBold'),
           url('/home/jay/.local/share/fonts/Pretendard/Pretendard-SemiBold.otf') format('opentype');
      font-weight: 600;
    }}
    @font-face {{
      font-family: 'Pretendard';
      src: local('Pretendard-Medium'),
           url('/home/jay/.local/share/fonts/Pretendard/Pretendard-Medium.otf') format('opentype');
      font-weight: 500;
    }}
    @font-face {{
      font-family: 'Pretendard';
      src: local('Pretendard-Regular'),
           url('/home/jay/.local/share/fonts/Pretendard/Pretendard-Regular.otf') format('opentype');
      font-weight: 400;
    }}

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

    html, body {{
      width: 1080px;
      height: 1080px;
      overflow: hidden;
      -webkit-font-smoothing: antialiased;
      text-rendering: optimizeLegibility;
    }}

    body {{
      font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
      position: relative;
      background: #0a1225;
    }}

    /* ── 배경 레이어 ── */
    #bg {{
      position: absolute;
      inset: 0;
      z-index: 0;
      background-image: url('file://{bg_path}');
      background-size: cover;
      background-position: center center;
    }}

    /* ── 상단 어두운 오버레이 (텍스트 가독성) ── */
    #overlay {{
      position: absolute;
      inset: 0;
      z-index: 1;
      background: linear-gradient(
        180deg,
        rgba(15, 22, 50, 0.72) 0%,
        rgba(15, 22, 50, 0.45) 35%,
        rgba(15, 22, 50, 0.20) 55%,
        rgba(10, 18, 40, 0.60) 80%,
        rgba(10, 18, 40, 0.85) 100%
      );
    }}

    /* ── 중앙 골드 광원 효과 ── */
    #glow {{
      position: absolute;
      inset: 0;
      z-index: 2;
      background: radial-gradient(
        ellipse 60% 50% at 50% 42%,
        rgba(201, 168, 76, 0.12) 0%,
        transparent 70%
      );
      pointer-events: none;
    }}

    /* ── 전체 래퍼 ── */
    #wrapper {{
      position: relative;
      width: 1080px;
      height: 1080px;
      z-index: 10;
      display: flex;
      flex-direction: column;
      align-items: center;
    }}

    /* ── 브랜드 로고 (상단 10%) ── */
    #brand-logo {{
      margin-top: 48px;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 8px;
    }}

    .brand-emblem {{
      width: 52px;
      height: 52px;
      position: relative;
    }}

    .brand-emblem svg {{
      width: 52px;
      height: 52px;
    }}

    .brand-name {{
      font-family: 'Pretendard', sans-serif;
      font-size: {_SIZE_22PX}px;
      font-weight: 700;
      color: #C9A84C;
      letter-spacing: 0.04em;
      text-shadow: 0 0 20px rgba(201, 168, 76, 0.5);
    }}

    /* ── 헤드라인 영역 (상단~중앙 40%) ── */
    #headline-section {{
      flex: 1;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      padding: 0 70px;
      margin-top: -20px;
    }}

    .headline {{
      font-family: 'Pretendard', sans-serif;
      font-size: {_SIZE_68PX}px;
      font-weight: 900;
      line-height: {_LH_1_22};
      letter-spacing: -0.03em;
      color: #ffffff;
      text-align: center;
      word-break: keep-all;
      text-shadow:
        0 2px 20px rgba(0, 0, 0, 0.6),
        0 4px 50px rgba(0, 0, 0, 0.4);
      margin-bottom: 28px;
    }}

    .headline .accent {{
      color: #C9A84C;
      text-decoration: underline;
      text-decoration-color: rgba(201, 168, 76, 0.7);
      text-decoration-thickness: 3px;
      text-underline-offset: 6px;
      text-shadow:
        0 0 30px rgba(201, 168, 76, 0.6),
        0 2px 20px rgba(0, 0, 0, 0.5);
    }}

    /* ── 구분 장식선 ── */
    .divider {{
      display: flex;
      align-items: center;
      gap: 16px;
      width: 100%;
      max-width: 540px;
      margin-bottom: 28px;
    }}

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

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

    /* ── 서브카피 (중앙 25%) ── */
    .subcopy {{
      font-family: 'Pretendard', sans-serif;
      font-size: {_SIZE_36PX}px;
      font-weight: 400;
      line-height: {_LH_1_65};
      color: rgba(255, 255, 255, 0.82);
      text-align: center;
      word-break: keep-all;
      letter-spacing: -0.01em;
    }}

    /* ── 하단 영역 (하단 25%) ── */
    #bottom-section {{
      width: 100%;
      padding: 0 60px 56px;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 24px;
    }}

    /* ── CTA 버튼 ── */
    .cta-btn {{
      width: 100%;
      max-width: 840px;
      background: linear-gradient(
        135deg,
        #C9A84C 0%,
        #E8C870 40%,
        #D4AD52 70%,
        #B8922A 100%
      );
      color: #ffffff;
      font-family: 'Pretendard', sans-serif;
      font-size: {_SIZE_46PX}px;
      font-weight: 900;
      letter-spacing: -0.02em;
      text-align: center;
      padding: 34px 48px;
      border-radius: 18px;
      word-break: keep-all;
      box-shadow:
        0 0 40px rgba(201, 168, 76, 0.55),
        0 8px 30px rgba(0, 0, 0, 0.45),
        inset 0 2px 0 rgba(255, 255, 255, 0.35),
        inset 0 -3px 0 rgba(0, 0, 0, 0.20);
      text-shadow: 0 1px 4px rgba(0, 0, 0, 0.30);
      position: relative;
      overflow: hidden;
    }}

    .cta-btn::after {{
      content: '';
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      height: 50%;
      background: linear-gradient(180deg, rgba(255,255,255,0.15) 0%, transparent 100%);
      border-radius: 18px 18px 0 0;
    }}

    /* ── 트러스트 앵커 배지 ── */
    .trust-row {{
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 24px;
    }}

    .trust-item {{
      display: flex;
      align-items: center;
      gap: 8px;
      font-family: 'Pretendard', sans-serif;
      font-size: {_SIZE_26PX}px;
      font-weight: 500;
      color: rgba(255, 255, 255, 0.68);
      letter-spacing: 0.01em;
    }}

    .trust-icon {{
      width: 20px;
      height: 20px;
      color: #C9A84C;
    }}

    .trust-sep {{
      width: 4px;
      height: 4px;
      background: rgba(201, 168, 76, 0.5);
      border-radius: 50%;
    }}

    /* ── 페이지 인디케이터 ── */
    #page-indicator {{
      position: absolute;
      top: 54px;
      right: 54px;
      z-index: 20;
      font-family: 'Pretendard', sans-serif;
      font-size: {_SIZE_22PX}px;
      font-weight: 500;
      color: rgba(255, 255, 255, 0.45);
      letter-spacing: 0.05em;
    }}
  </style>
</head>
<body>

  <!-- 배경 -->
  <div id="bg"></div>

  <!-- 어두운 오버레이 -->
  <div id="overlay"></div>

  <!-- 중앙 골드 글로우 -->
  <div id="glow"></div>

  <!-- 페이지 인디케이터 -->
  <div id="page-indicator">5 / 5</div>

  <!-- 메인 래퍼 -->
  <div id="wrapper">

    <!-- 브랜드 로고 -->
    <div id="brand-logo">
      <div class="brand-emblem">
        <!-- 서울대보험쌤 심볼 (미니멀 방패+별) -->
        <svg viewBox="0 0 52 52" fill="none" xmlns="http://www.w3.org/2000/svg">
          <defs>
            <linearGradient id="g1" x1="0%" y1="0%" x2="100%" y2="100%">
              <stop offset="0%" style="stop-color:#E8C870"/>
              <stop offset="100%" style="stop-color:#B8922A"/>
            </linearGradient>
          </defs>
          <!-- 방패 외형 -->
          <path d="M26 4 L46 13 L46 30 C46 40 36 47 26 50 C16 47 6 40 6 30 L6 13 Z"
                fill="url(#g1)" opacity="0.15" stroke="url(#g1)" stroke-width="1.5"/>
          <!-- 별 심볼 -->
          <path d="M26 14 L28.4 21.2 L36 21.2 L30 25.6 L32.4 32.8 L26 28.4 L19.6 32.8 L22 25.6 L16 21.2 L23.6 21.2 Z"
                fill="url(#g1)"/>
        </svg>
      </div>
      <div class="brand-name">서울대보험쌤</div>
    </div>

    <!-- 헤드라인 섹션 -->
    <div id="headline-section">
      <h1 class="headline">전략을 바꿀 준비가 됐다면,<br>지금 <span class="accent">딱 한 번</span> 물어보세요.</h1>

      <div class="divider">
        <div class="divider-line"></div>
        <div class="divider-dot"></div>
        <div class="divider-line"></div>
      </div>

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

    <!-- 하단 CTA 영역 -->
    <div id="bottom-section">
      <div class="cta-btn">무료 상담 신청하기</div>

      <!-- 트러스트 앵커 -->
      <div class="trust-row">
        <div class="trust-item">
          <svg class="trust-icon" viewBox="0 0 20 20" fill="none">
            <path d="M10 2L12.2 7.4L18 7.8L13.6 11.8L15.2 17.4L10 14.4L4.8 17.4L6.4 11.8L2 7.8L7.8 7.4Z"
                  fill="#C9A84C"/>
          </svg>
          조건 없음
        </div>
        <div class="trust-sep"></div>
        <div class="trust-item">
          <svg class="trust-icon" viewBox="0 0 20 20" fill="none">
            <circle cx="10" cy="10" r="8" stroke="#C9A84C" stroke-width="1.5"/>
            <path d="M7 10L9.5 12.5L14 7.5" stroke="#C9A84C" stroke-width="1.5" stroke-linecap="round"/>
          </svg>
          무료 상담
        </div>
        <div class="trust-sep"></div>
        <div class="trust-item">
          <svg class="trust-icon" viewBox="0 0 20 20" fill="none">
            <path d="M10 2C7.2 2 5 4.2 5 7C5 9.8 7.2 12 10 12C12.8 12 15 9.8 15 7C15 4.2 12.8 2 10 2Z"
                  stroke="#C9A84C" stroke-width="1.5"/>
            <path d="M3 18C3 15.2 6.1 13 10 13C13.9 13 17 15.2 17 18"
                  stroke="#C9A84C" stroke-width="1.5" stroke-linecap="round"/>
          </svg>
          팀장 직접 응대
        </div>
      </div>
    </div>

  </div>

</body>
</html>
"""


def create_html(bg_path: Path, output_html_path: Path) -> None:
    """HTML 오버레이 파일 생성."""
    html_content = HTML_TEMPLATE.format(bg_path=str(bg_path))
    output_html_path.write_text(html_content, encoding="utf-8")
    print(f"[HTML] 오버레이 생성: {output_html_path}")


def capture_screenshot(html_path: Path, output_png_path: Path) -> None:
    """Playwright로 HTML → PNG 캡처."""
    print("[캡처] 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")
            page.wait_for_timeout(2500)  # 폰트 + 이미지 로딩 대기
            output_png_path.parent.mkdir(parents=True, exist_ok=True)
            page.screenshot(path=str(output_png_path), type="png")
            print(f"[캡처] 완료: {output_png_path}")
        finally:
            browser.close()


def main():
    print("=" * 60)
    print("Meta 캐러셀 A-5 CTA 슬라이드 생성")
    print("=" * 60)
    OUTPUT_DIR.mkdir(parents=True, exist_ok=True)

    # 1. SA Bearer 토큰 획득
    print("[인증] SA 서비스 계정 토큰 획득 중...")
    try:
        token = gcloud_auth.get_service_account_token()
        print(f"[인증] SA 토큰 획득 완료 (길이: {len(token)})")
    except Exception as e:
        print(f"[ERROR] SA 토큰 획득 실패: {e}")
        sys.exit(1)

    # 2. 배경 이미지 생성
    if BG_PATH.exists():
        print(f"[배경] 기존 배경 이미지 재사용: {BG_PATH}")
    else:
        success = generate_gemini_background(token, BG_PATH)
        if not success:
            print("[ERROR] 배경 이미지 생성 실패. 중단합니다.")
            sys.exit(1)

    # 3. HTML 오버레이 생성
    create_html(BG_PATH, HTML_PATH)

    # 4. Playwright 캡처
    capture_screenshot(HTML_PATH, FINAL_PATH)

    # 5. 완료 보고
    if FINAL_PATH.exists():
        size_kb = FINAL_PATH.stat().st_size / 1024
        print(f"\n[완료] {FINAL_PATH}")
        print(f"       파일 크기: {size_kb:.0f} KB")
        print(f"       해상도: 1080x1080px")
    else:
        print("[ERROR] 최종 이미지 파일이 생성되지 않았습니다.")
        sys.exit(1)


if __name__ == "__main__":
    main()
