#!/usr/bin/env python3
"""
Production A-4 (Social Proof) — Meta Carousel Slide
Warm navy + gold palette, testimonial quote cards
Hybrid: Gemini background + Playwright HTML overlay
Output: 1080x1080 PNG
"""

import base64
import sys
import time
from pathlib import Path

import requests
from playwright.sync_api import sync_playwright

# ── paths ──────────────────────────────────────────────────────────────────────
OUTPUT_DIR = Path("/home/jay/workspace/output/meta-ads/a-group-v6/production")
BG_PATH    = OUTPUT_DIR / "_bg_a4_proof.jpg"
HTML_PATH  = OUTPUT_DIR / "_a4_proof_template.html"
OUT_PATH   = OUTPUT_DIR / "meta-A4-proof.png"
FONT_DIR   = Path.home() / ".local/share/fonts/Pretendard"
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)

# ── Gemini config ──────────────────────────────────────────────────────────────
sys.path.insert(0, "/home/jay/workspace/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
- 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 — backgrounds 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.07) 0%, transparent 65%),
      linear-gradient(
        180deg,
        rgba(255, 252, 245, 0.10) 0%,
        rgba(255, 252, 240, 0.05) 30%,
        rgba(245, 240, 230, 0.05) 70%,
        rgba(240, 235, 220, 0.12) 100%
      );
    pointer-events: none;
  }}

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

  /* ── TOP ZONE (15%) ── */
  .top-zone {{
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 162px;
    flex-shrink: 0;
  }}

  .brand-badge {{
    display: inline-flex;
    align-items: center;
    gap: 10px;
    border: 1.5px solid rgba(201, 168, 76, 0.55);
    border-radius: 6px;
    padding: 10px 20px;
    background: rgba(255, 255, 255, 0.75);
  }}

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

  .badge-text {{
    font-weight: 700;
    font-size: 26px;
    color: #C9A84C;
    letter-spacing: 0.04em;
    line-height: 1;
  }}

  .slide-num {{
    font-size: 20px;
    font-weight: 400;
    color: rgba(120, 100, 60, 0.65);
    letter-spacing: 0.06em;
  }}

  /* ── HEADLINE (top 15% area) ── */
  .headline-zone {{
    flex-shrink: 0;
    margin-bottom: 32px;
  }}

  .headline {{
    font-size: 72px;
    font-weight: 800;
    line-height: 1.18;
    letter-spacing: -0.028em;
    color: #1A202C;
    word-break: keep-all;
    text-shadow: none;
  }}

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

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

  /* Premium testimonial card */
  .quote-card {{
    background: rgba(255, 255, 255, 0.85);
    border: 1.5px solid rgba(201, 168, 76, 0.60);
    border-radius: 12px;
    padding: 32px 36px 32px 44px;
    position: relative;
    backdrop-filter: blur(6px);
    box-shadow:
      0 4px 24px rgba(0,0,0,0.10),
      0 0 0 0.5px rgba(201, 168, 76, 0.18) inset;
  }}

  /* Left gold vertical accent bar */
  .quote-card::before {{
    content: '';
    position: absolute;
    left: 0;
    top: 12px;
    bottom: 12px;
    width: 4px;
    background: linear-gradient(180deg, #C9A84C 0%, rgba(201, 168, 76, 0.4) 100%);
    border-radius: 0 2px 2px 0;
  }}

  /* Large decorative quote mark */
  .quote-mark {{
    font-size: 72px;
    font-weight: 900;
    color: rgba(201, 168, 76, 0.30);
    line-height: 0.7;
    float: left;
    margin-right: 10px;
    margin-top: 6px;
    font-family: 'Georgia', serif;
  }}

  .quote-body {{
    font-size: 42px;
    font-weight: 500;
    line-height: 1.55;
    color: rgba(30, 30, 40, 0.88);
    letter-spacing: -0.015em;
    word-break: keep-all;
    display: block;
    overflow: hidden;
  }}

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

  .attr-line {{
    width: 24px;
    height: 1.5px;
    background: rgba(201, 168, 76, 0.60);
    flex-shrink: 0;
  }}

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

  /* Mini icon badge per card — CSS-only gold diamond */
  .card-icon {{
    position: absolute;
    top: 20px;
    right: 24px;
    width: 36px;
    height: 36px;
    background: rgba(201, 168, 76, 0.15);
    border: 1px solid rgba(201, 168, 76, 0.35);
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
  }}

  /* Gold diamond shape inside icon badge */
  .card-icon::after {{
    content: '';
    width: 14px;
    height: 14px;
    background: rgba(201, 168, 76, 0.80);
    transform: rotate(45deg);
    border-radius: 2px;
  }}

  /* ── BOTTOM ZONE (25%) ── */
  .bottom-zone {{
    flex-shrink: 0;
    margin-top: 28px;
  }}

  .bottom-divider {{
    width: 100%;
    height: 1px;
    background: linear-gradient(90deg, rgba(201, 168, 76, 0.50) 0%, rgba(201, 168, 76, 0.05) 100%);
    margin-bottom: 20px;
  }}

  .bottom-attribution {{
    font-size: 34px;
    font-weight: 400;
    color: rgba(80, 80, 90, 0.65);
    letter-spacing: -0.01em;
    line-height: 1.55;
    font-style: italic;
    word-break: keep-all;
  }}

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

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

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

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

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

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

    <!-- QUOTE CARDS (center 60%) -->
    <div class="cards-zone">

      <!-- Card 1 -->
      <div class="quote-card">
        <div class="card-icon"></div>
        <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="card-icon"></div>
        <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 -->
    <div class="bottom-zone">
      <div class="bottom-divider"></div>
      <p class="bottom-attribution">
        <span class="brand-name">서울대보험쌤 팀</span>의 5가지 시스템 안에서 시작한 이야기입니다.
      </p>
    </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("Production 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}초 총 소요)")
