#!/usr/bin/env python3
"""컨셉 #07 Impact Number v2 - hybrid-image 파이프라인
Gemini 배경 생성 + Playwright HTML 오버레이 합성
"""

from __future__ import annotations

import base64
import json
import shutil
import sys
import time
from pathlib import Path
from typing import Any

import requests

# ─── 경로 설정 ────────────────────────────────────────────────────────────────
SCRIPT_DIR = Path(__file__).parent
sys.path.insert(0, str(SCRIPT_DIR))

OUTPUT_DIR = Path("/home/jay/workspace/output/meta-ads/concept-catalog/07-impact-number")
BG_PATH = OUTPUT_DIR / "bg_v2_impact.jpg"
SAMPLE_PATH = OUTPUT_DIR / "sample-v2.png"
FINAL_PATH = OUTPUT_DIR / "07-impact-number-v2.png"
HTML_PATH = OUTPUT_DIR / "overlay_impact_v2.html"

FONT_DIR = Path.home() / ".local/share/fonts/Pretendard"

# ─── Gemini 배경 프롬프트 ──────────────────────────────────────────────────────
BG_PROMPT = (
    "Very dark navy blue background (#121928), minimal abstract composition. "
    "Subtle golden radial glow emanating from center, soft warm amber-gold light diffusion. "
    "Pure dark gradient background, no patterns, no text, no objects, no people. "
    "Just deep dark navy with a gentle golden center glow. "
    "Clean, simple, elegant. 1080x1080 square format."
)

# ─── HTML 오버레이 템플릿 ──────────────────────────────────────────────────────
HTML_TEMPLATE = """<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<style>
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{font_dir}/Pretendard-Regular.otf') format('opentype');
    font-weight: 400;
    font-style: normal;
  }}
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{font_dir}/Pretendard-Medium.otf') format('opentype');
    font-weight: 500;
    font-style: normal;
  }}
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{font_dir}/Pretendard-SemiBold.otf') format('opentype');
    font-weight: 600;
    font-style: normal;
  }}
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{font_dir}/Pretendard-Bold.otf') format('opentype');
    font-weight: 700;
    font-style: normal;
  }}
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{font_dir}/Pretendard-Black.otf') format('opentype');
    font-weight: 900;
    font-style: normal;
  }}

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

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

  .canvas {{
    width: 1080px;
    height: 1080px;
    position: relative;
    background-image: url('file://{bg_path}');
    background-size: cover;
    background-position: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }}

  /* 배경 다크 오버레이 (배경 이미지 너무 밝을 경우 보정) */
  .canvas::before {{
    content: '';
    position: absolute;
    inset: 0;
    background: radial-gradient(
      ellipse 60% 55% at 50% 50%,
      rgba(240, 200, 74, 0.08) 0%,
      rgba(18, 25, 40, 0.0) 60%,
      rgba(18, 25, 40, 0.3) 100%
    );
    pointer-events: none;
  }}

  .content-stack {{
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0;
    /* 수직 중앙 정렬은 부모 flex center로 처리 */
  }}

  /* 1. 서브 라벨 */
  .sub-label {{
    font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    font-weight: 400;
    font-size: 48px;
    color: #E0E8F0;
    text-align: center;
    letter-spacing: -0.5px;
    margin-bottom: 16px;
  }}

  /* 2. 임팩트 숫자 */
  .impact-number {{
    font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    font-weight: 900;
    font-size: 200px;
    color: #F0C84A;
    text-align: center;
    letter-spacing: -6px;
    line-height: 1;
    white-space: nowrap;
    /* 골드 글로우 효과 */
    text-shadow:
      0 0 40px rgba(240, 200, 74, 0.9),
      0 0 80px rgba(240, 200, 74, 0.5),
      0 0 120px rgba(240, 200, 74, 0.3),
      0 0 200px rgba(240, 200, 74, 0.15);
    margin-bottom: 32px;
  }}

  /* 3. 구분선 */
  .divider {{
    width: 120px;
    height: 1px;
    background: #F0C84A;
    margin-bottom: 28px;
    opacity: 0.85;
  }}

  /* 4. 긴급성 */
  .urgency {{
    font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    font-weight: 700;
    font-size: 52px;
    color: #E06060;
    text-align: center;
    letter-spacing: -0.5px;
    line-height: 1.2;
    margin-bottom: 20px;
  }}

  /* 5. CTA */
  .cta {{
    font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    font-weight: 600;
    font-size: 44px;
    color: #FFFFFF;
    text-align: center;
    letter-spacing: -0.3px;
    opacity: 0.95;
  }}
</style>
</head>
<body>
  <div class="canvas">
    <div class="content-stack">
      <div class="sub-label">신입 정착지원금 최대</div>
      <div class="impact-number">1,000만원</div>
      <div class="divider"></div>
      <div class="urgency">2026년 7월, 조건이 바뀝니다</div>
      <div class="cta">지금 상담 신청하기</div>
    </div>
  </div>
</body>
</html>
"""


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

def generate_background(token: str) -> bool:
    """Gemini API로 배경 이미지 생성 후 BG_PATH에 저장."""
    models = ["gemini-2.0-flash-preview-image-generation", "gemini-3-pro-image-preview", "gemini-3.1-flash-image-preview"]
    api_base = "https://generativelanguage.googleapis.com/v1beta"

    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json",
    }
    payload: dict[str, Any] = {
        "contents": [{"parts": [{"text": BG_PROMPT}]}],
        "generationConfig": {"responseModalities": ["IMAGE", "TEXT"]},
    }

    for model_id in models:
        url = f"{api_base}/models/{model_id}:generateContent"
        print(f"[배경] Gemini 모델 시도: {model_id}")
        try:
            resp = requests.post(url, headers=headers, json=payload, timeout=120)
            if resp.status_code in (403, 404):
                print(f"  → HTTP {resp.status_code}, 다음 모델로 시도...")
                continue
            resp.raise_for_status()
            data = resp.json()
            candidates = data.get("candidates", [])
            if not candidates:
                print(f"  → 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"  → 이미지 파트 없음, 다음 모델로...")
                continue
            image_bytes = base64.b64decode(image_part["inlineData"]["data"])
            BG_PATH.write_bytes(image_bytes)
            print(f"  → 배경 저장: {BG_PATH} ({len(image_bytes):,} bytes)")
            return True
        except Exception as e:
            print(f"  → 오류: {e}")
            continue

    return False


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

def capture_overlay() -> None:
    """HTML 오버레이를 Playwright로 캡처하여 SAMPLE_PATH에 저장."""
    from playwright.sync_api import sync_playwright

    # HTML 파일 저장
    html_content = HTML_TEMPLATE.format(
        font_dir=str(FONT_DIR),
        bg_path=str(BG_PATH) if BG_PATH.exists() else "",
    )
    HTML_PATH.write_text(html_content, encoding="utf-8")
    print(f"[HTML] 템플릿 저장: {HTML_PATH}")

    with sync_playwright() as p:
        browser = p.chromium.launch()
        try:
            page = browser.new_page(viewport={"width": 1080, "height": 1080})
            page.goto(f"file://{HTML_PATH.resolve()}", wait_until="networkidle")
            # 폰트 렌더링 대기
            page.wait_for_timeout(2000)
            SAMPLE_PATH.parent.mkdir(parents=True, exist_ok=True)
            page.screenshot(path=str(SAMPLE_PATH), type="png")
            print(f"[캡처] {SAMPLE_PATH} ({SAMPLE_PATH.stat().st_size:,} bytes)")
        finally:
            browser.close()


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

def main() -> None:
    import gcloud_auth

    print("=" * 60)
    print("컨셉 #07 Impact Number v2 — hybrid-image 생성")
    print("=" * 60)

    # 1. 인증
    print("\n[인증] 토큰 획득 중...")
    try:
        token = gcloud_auth.get_access_token()
        print(f"[인증] 토큰 획득 성공 ({len(token)} chars)")
    except Exception as e:
        print(f"[인증 실패] {e}")
        print("[폴백] 배경 없이 단색 배경으로 진행합니다.")
        token = None

    # 2. 배경 생성
    if token:
        print("\n[배경] Gemini 이미지 생성 중...")
        bg_ok = generate_background(token)
        if not bg_ok:
            print("[배경] 모든 모델 실패 — 단색 배경 폴백")
    else:
        bg_ok = False

    # 배경이 없으면 HTML에서 CSS 단색 배경으로 처리 (canvas에 background: #121928)
    if not bg_ok:
        # 빈 BG_PATH 처리 — HTML 템플릿의 background-image가 빈 값이면 CSS background-color로 폴백
        print("[배경] CSS 단색 다크 배경 + 황금 글로우로 대체합니다.")

    # 3. Playwright 캡처
    print("\n[캡처] HTML 오버레이 렌더링 중...")
    capture_overlay()

    # 4. 복사
    shutil.copy2(SAMPLE_PATH, FINAL_PATH)
    print(f"[복사] {FINAL_PATH}")

    print("\n" + "=" * 60)
    print("생성 완료!")
    print(f"  sample-v2.png : {SAMPLE_PATH}")
    print(f"  07-impact-number-v2.png : {FINAL_PATH}")
    print("=" * 60)


if __name__ == "__main__":
    main()
