#!/usr/bin/env python3
"""
Venus A-4 (Social Proof) — Meta Carousel Slide
Bright cream/white background, testimonial quote cards with gold accents
Hybrid: Gemini background + Playwright HTML overlay
Output: 1080x1080 PNG → /home/jay/workspace/output/meta-ads/a-group-venus/venus-A4-proof.png
"""

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_a4_proof.jpg"
HTML_PATH  = OUTPUT_DIR / "_venus_a4_proof_template.html"
OUT_PATH   = OUTPUT_DIR / "venus-A4-proof.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"
SCOPE           = "https://www.googleapis.com/auth/generative-language"

BG_PROMPT = """
Create a warm, serene, light-toned abstract background for a premium Korean insurance team advertisement.

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

VISUAL CONCEPT:
A bright, airy cream and off-white background suffused with soft golden light rays gently
streaming downward from the upper area of the canvas. Minimal, clean, and sophisticated.
Like warm morning sunlight filtering through sheer curtains in an elegant space.

BACKGROUND ELEMENTS:
- Warm cream / off-white base (#F5F0E8 to #FAFAF5) — light, airy, and calming
- Soft golden light rays (#C9A84C tones at very low opacity, ~10-15%) streaming diagonally
  from upper-left to center, creating a gentle glow without harshness
_SIZE_26PX = 26
_SIZE_34PX = 34
_CTA_PX = CTA_MIN_PX
_SIZE_44PX = 44
_SIZE_66PX = 66
_SIZE_80PX = 80
_LH_1 = 1
_LH_1_20 = 1.20
_LH_0_65 = 0.65
_LH_1_52 = 1.52
_LH_1_50 = 1.50
- Very subtle warm beige texture — like fine linen or smooth matte paper surface
- Gentle gradient: slightly warmer (more golden-ivory) at center, fading to pure cream at edges
- Top zone (top 20%): slightly lighter/cleaner area for text readability on light background
- Bottom zone: barely perceptible warm ivory shadow, soft and non-distracting
- Overall feel: low-saturation, minimal, photographic quality — background recedes behind content

MOOD / ATMOSPHERE:
- Trust. Transparency. Credibility. Warmth.
- Clean premium consulting feel — trustworthy and human
- "Real results, real people" — intimate and credible, not hype-filled
- Like a bright, beautifully lit minimalist studio where genuine testimonials were shared

COLOR PALETTE:
- Primary base: Warm cream (#F5F0E8), off-white (#FAFAF5), ivory (#F0EBE0)
- Accent glow: Very subtle golden-amber (#C9A84C at 8-12% opacity) as soft light wash
- No dark tones, no navy, no deep shadows
- No cool gray, no blue — pure warm cream/ivory family only
- Maximum luminosity; bright but never harsh or clinical white

STYLE REQUIREMENTS:
- NO stock photography aesthetic
- NO people, faces, hands, or human figures
- NO text, numbers, or labels
- NO dark backgrounds or high contrast zones
- Minimalist, ultra-premium advertising quality — background is supportive, not dominant
- Photographic texture quality — fine, subtle, warm
- The testimonial cards will overlay this background, so keep it clean and uncluttered
"""

# ── 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"]},
        }
        return requests.post(url, headers=headers, json=payload, timeout=300)

    t0 = time.time()
    resp = _call(MODEL_PRIMARY)
    if resp.status_code in (403, 404):
        print(f"[BG] Pro 모델 실패 (HTTP {resp.status_code}), fallback 시도...")
        resp = _call(MODEL_FALLBACK)
    resp.raise_for_status()

    data = resp.json()
    candidates = data.get("candidates", [])
    if not candidates:
        raise RuntimeError(f"candidates 없음: {str(data)[:300]}")

    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]
        raise RuntimeError(f"이미지 없음. 텍스트 응답: {texts[:2]}")

    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


# ── 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;
  }}
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{font_dir}/Pretendard-Light.otf') format('opentype');
    font-weight: 300;
  }}

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

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

  /* ── 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;
  }}

  /* ── Light overlay: very subtle warm glow, preserves bright background ── */
  .overlay {{
    position: absolute;
    inset: 0;
    background:
      radial-gradient(ellipse 65% 50% at 50% 45%, rgba(201, 168, 76, 0.06) 0%, transparent 65%),
      linear-gradient(
        180deg,
        rgba(255, 252, 245, 0.08) 0%,
        rgba(255, 252, 240, 0.04) 30%,
        rgba(245, 240, 230, 0.04) 70%,
        rgba(240, 235, 220, 0.10) 100%
      );
    pointer-events: none;
  }}

  /* All content above overlay */
  .content {{
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    padding: 52px 68px 52px 68px;
  }}

  /* ── TOP ZONE ── */
  .top-zone {{
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 80px;
    flex-shrink: 0;
    margin-bottom: 20px;
  }}

  .brand-badge {{
    display: inline-flex;
    align-items: center;
    gap: 10px;
    border: 1.5px solid rgba(160, 120, 40, 0.50);
    border-radius: 6px;
    padding: 8px 18px;
    background: rgba(255, 255, 255, 0.80);
  }}

  .badge-dot {{
    width: 7px;
    height: 7px;
    background: #A07828;
    border-radius: 50%;
    flex-shrink: 0;
    box-shadow: 0 0 6px rgba(160, 120, 40, 0.7);
  }}

  .badge-text {{
    font-weight: 700;
    font-size: {_SIZE_26PX}px;
    color: #A07828;
    letter-spacing: 0.04em;
    line-height: {_LH_1};
  }}

  /* ── HEADLINE ── */
  .headline-zone {{
    flex-shrink: 0;
    margin-bottom: 28px;
  }}

  .headline {{
    font-size: {_SIZE_66PX}px;
    font-weight: 800;
    line-height: {_LH_1}.20;
    letter-spacing: -0.026em;
    color: #1A0E00;
    word-break: keep-all;
    text-shadow: none;
  }}

  .headline .gold {{
    color: #A07828;
    font-weight: 900;
  }}

  /* ── QUOTE CARDS ZONE ── */
  .cards-zone {{
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 22px;
    justify-content: center;
    min-height: 0;
  }}

  /* Premium testimonial card on bright background */
  .quote-card {{
    background: rgba(255, 255, 255, 0.92);
    border: 1.5px solid rgba(160, 120, 40, 0.45);
    border-radius: 14px;
    padding: 30px 36px 30px 48px;
    position: relative;
    box-shadow:
      0 4px 20px rgba(0,0,0,0.09),
      0 1px 4px rgba(160, 120, 40, 0.10);
  }}

  /* Left dark gold vertical accent bar */
  .quote-card::before {{
    content: '';
    position: absolute;
    left: 0;
    top: 14px;
    bottom: 14px;
    width: 5px;
    background: linear-gradient(180deg, #A07828 0%, rgba(160, 120, 40, 0.35) 100%);
    border-radius: 0 3px 3px 0;
  }}

  /* Large decorative quote mark */
  .quote-mark {{
    font-size: {_SIZE_80PX}px;
    font-weight: 900;
    color: rgba(160, 120, 40, 0.22);
    line-height: {_LH_0_65};
    float: left;
    margin-right: 12px;
    margin-top: 4px;
    font-family: 'Georgia', serif;
  }}

  .quote-body {{
    font-size: {_SIZE_44PX}px;
    font-weight: 600;
    line-height: {_LH_1}.52;
    color: #1A0E00;
    letter-spacing: -0.016em;
    word-break: keep-all;
    display: block;
    overflow: hidden;
  }}

  .quote-attribution {{
    margin-top: 14px;
    display: flex;
    align-items: center;
    gap: 12px;
    clear: both;
  }}

  .attr-line {{
    width: 28px;
    height: 1.5px;
    background: rgba(160, 120, 40, 0.55);
    flex-shrink: 0;
  }}

  .attr-name {{
    font-size: {_SIZE_34PX}px;
    font-weight: 700;
    color: #A07828;
    letter-spacing: 0.04em;
  }}

  /* ── BOTTOM ZONE ── */
  .bottom-zone {{
    flex-shrink: 0;
    margin-top: 24px;
  }}

  .bottom-divider {{
    width: 100%;
    height: 1px;
    background: linear-gradient(90deg, rgba(160, 120, 40, 0.45) 0%, rgba(160, 120, 40, 0.04) 100%);
    margin-bottom: 18px;
  }}

  .bottom-row {{
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
  }}

  .bottom-attribution {{
    font-size: {_SIZE_34PX}px;
    font-weight: 400;
    color: rgba(60, 50, 30, 0.60);
    letter-spacing: -0.01em;
    line-height: {_LH_1}.50;
    font-style: italic;
    word-break: keep-all;
    flex: 1;
  }}

  .bottom-attribution .brand-name {{
    color: #A07828;
    font-style: normal;
    font-weight: 700;
  }}

  .page-indicator {{
    font-size: {_CTA_PX}px;
    font-weight: 700;
    color: #A07828;
    letter-spacing: 0.06em;
    flex-shrink: 0;
    margin-left: 20px;
    line-height: {_LH_1};
  }}

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

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

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

    <!-- TOP: Brand badge -->
    <div class="top-zone">
      <div class="brand-badge">
        <div class="badge-dot"></div>
        <span class="badge-text">서울대보험쌤</span>
      </div>
    </div>

    <!-- HEADLINE -->
    <div class="headline-zone">
      <h1 class="headline">
        방법을 바꾼 사람들이 말하는<br><span class="gold">실제 변화.</span>
      </h1>
    </div>

    <!-- QUOTE CARDS -->
    <div class="cards-zone">

      <!-- Card 1 -->
      <div class="quote-card">
        <div class="quote-mark">&ldquo;</div>
        <div class="quote-body">거절이 두려웠는데,<br>이제는 고객을 선택합니다.</div>
        <div class="quote-attribution">
          <div class="attr-line"></div>
          <span class="attr-name">이○○</span>
        </div>
      </div>

      <!-- Card 2 -->
      <div class="quote-card">
        <div class="quote-mark">&ldquo;</div>
        <div class="quote-body">자동 유입 시스템으로<br>걱정 없는 영업이 됐습니다.</div>
        <div class="quote-attribution">
          <div class="attr-line"></div>
          <span class="attr-name">김○○</span>
        </div>
      </div>

    </div>

    <!-- BOTTOM: Attribution + Page indicator -->
    <div class="bottom-zone">
      <div class="bottom-divider"></div>
      <div class="bottom-row">
        <p class="bottom-attribution">
          <span class="brand-name">서울대보험쌤 팀</span>의 5가지 시스템 안에서 시작한 이야기입니다.
        </p>
        <div class="page-indicator">4/5</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()
        try:
            page = browser.new_page(viewport={"width": 1080, "height": 1080})
            page.goto(f"file://{html_path.resolve()}", wait_until="networkidle")
            # Wait for fonts and rendering
            page.evaluate("async () => { await document.fonts.ready; }")
            page.wait_for_timeout(2500)
            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-4 (Social Proof) — 하이브리드 이미지 생성")
    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}초 총 소요)")
