#!/usr/bin/env python3
"""M3-2 서울대보험쌤 × 관리자 비전 Google 광고 배너 생성.

Gemini AI 배경 + Playwright HTML 오버레이 하이브리드 방식.
출력: snu-leader-1200x628.png, snu-leader-1080x1080.png
"""

from __future__ import annotations

import base64
import sys
import time
from pathlib import Path

import requests

# gcloud_auth 임포트를 위해 경로 추가
sys.path.insert(0, "/home/jay/workspace/tools/ai-image-gen")
import gcloud_auth

from playwright.sync_api import sync_playwright

OUTPUT_DIR = Path("/home/jay/workspace/output/google-ads/banners")
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)

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

# Gemini 모델
MODEL_ID = "gemini-2.0-flash-preview-image-generation"
FALLBACK_MODEL_ID = "gemini-2.0-flash-exp"
GEMINI_API_BASE = "https://generativelanguage.googleapis.com/v1beta"

# 배경 이미지 프롬프트 (공유 오피스 장면)
BG_PROMPT = (
    "Photo of a modern shared office space in Seoul. Wide shot showing individual "
    "workstations and a meeting area coexisting. On one side, a private office is visible "
    "through glass partitions. Bright natural sunlight streaming through large windows. "
    "Plant decorations throughout, warm wooden tone furniture. The look of a growing "
    "organization in its early stages. Photorealistic quality, warm yet organized atmosphere. "
    "No people. Warm tones, beige and wood colors dominating. Soft shadows, professional "
    "interior photography style. High resolution, sharp focus."
)


def generate_gemini_background(output_path: Path) -> bool:
    """Gemini API로 배경 이미지 생성 (SA 토큰 우선)."""
    print(f"[배경] Gemini 이미지 생성 중...")

    # SA 토큰 우선 시도
    sa_token = None
    try:
        sa_token = gcloud_auth.get_service_account_token()
        print(f"[배경] SA Bearer 토큰 인증 사용 (길이: {len(sa_token)})")
    except Exception as e:
        print(f"[배경] SA 토큰 실패: {e}, API Key fallback 시도...")

    if sa_token:
        headers = {
            "Authorization": f"Bearer {sa_token}",
            "Content-Type": "application/json",
        }
        models_to_try = ["gemini-3-pro-image-preview", "gemini-3.1-flash-image-preview"]
        base_url_fmt = f"{GEMINI_API_BASE}/models/{{model}}:generateContent"
    else:
        api_key = gcloud_auth.get_api_key("GEMINI_API_KEY")
        if not api_key:
            print("[오류] 인증 수단 없음")
            return False
        headers = {"Content-Type": "application/json"}
        models_to_try = ["gemini-3-pro-image-preview", "gemini-3.1-flash-image-preview", "gemini-2.5-flash-image"]
        base_url_fmt = f"{GEMINI_API_BASE}/models/{{model}}:generateContent?key={api_key}"

    payload = {
        "contents": [{"parts": [{"text": BG_PROMPT}]}],
        "generationConfig": {"responseModalities": ["IMAGE", "TEXT"]},
    }

    for model in models_to_try:
        url = base_url_fmt.format(model=model)
        print(f"[배경] 모델 시도: {model}")
        try:
            start = time.time()
            resp = requests.post(url, headers=headers, json=payload, timeout=120)

            if resp.status_code not in (200,):
                print(f"[배경] {model} 실패 ({resp.status_code}): {resp.text[:150]}")
                continue

            data = resp.json()
            parts = data.get("candidates", [{}])[0].get("content", {}).get("parts", [])
            image_part = next((p for p in parts if "inlineData" in p), None)

            if not image_part:
                print(f"[배경] {model}: 이미지 없음. {[p.get('text','') for p in parts][:1]}")
                continue

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

        except Exception as e:
            print(f"[오류] {model} 호출 실패: {type(e).__name__}: {e}")
            continue

    print("[오류] 모든 모델 실패")
    return False


# ────────────────────────────────────────────────────────────────
# HTML 템플릿: 1200x628 (가로형)
# ────────────────────────────────────────────────────────────────

def build_html_1200x628(bg_image_path: str) -> str:
    font_dir = str(FONT_DIR)
    return f"""<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
  @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-SemiBold.otf') format('opentype');
    font-weight: 600;
  }}
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{font_dir}/Pretendard-Medium.otf') format('opentype');
    font-weight: 500;
  }}

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

  body {{
    width: 1200px;
    height: 628px;
    overflow: hidden;
    background: #FFF8E7;
  }}

  .canvas {{
    width: 1200px;
    height: 628px;
    position: relative;
    font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    background: #FFF8E7;
    overflow: hidden;
  }}

  /* 우측 배경 이미지 (45%) */
  .bg-image {{
    position: absolute;
    top: 0;
    right: 0;
    width: 570px;
    height: 628px;
    background-image: url('file://{bg_image_path}');
    background-size: cover;
    background-position: center;
  }}

  /* 좌측 → 투명 그라데이션 (배경 위) */
  .bg-gradient-overlay {{
    position: absolute;
    top: 0;
    left: 0;
    width: 780px;
    height: 628px;
    background: linear-gradient(to right, #FFF8E7 0%, #FFF8E7 55%, rgba(255,248,231,0) 100%);
    z-index: 2;
  }}

  /* 좌측 텍스트 영역 */
  .text-area {{
    position: absolute;
    top: 0;
    left: 0;
    width: 660px;
    height: 628px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 0 60px 0 64px;
    z-index: 10;
  }}

  /* 뱃지 */
  .badge {{
    display: inline-flex;
    align-items: center;
    background: #C9A84C;
    color: #1A0E00;
    font-size: 28px;
    font-weight: 700;
    padding: 10px 22px;
    border-radius: 6px;
    margin-bottom: 28px;
    width: fit-content;
    letter-spacing: -0.3px;
  }}

  .badge-dot {{
    width: 10px;
    height: 10px;
    background: #1A0E00;
    border-radius: 50%;
    margin-right: 10px;
    flex-shrink: 0;
  }}

  /* 헤드라인 */
  .headline {{
    font-size: 50px;
    font-weight: 700;
    color: #3E2723;
    line-height: 1.25;
    letter-spacing: -1.5px;
    margin-bottom: 22px;
    white-space: pre-line;
  }}

  /* 서브 카피 */
  .subcopy {{
    font-size: 32px;
    font-weight: 600;
    color: #A07828;
    letter-spacing: -0.5px;
    margin-bottom: 40px;
    line-height: 1.4;
  }}

  /* CTA 버튼 */
  .cta-btn {{
    display: inline-flex;
    align-items: center;
    background: linear-gradient(135deg, #C9A84C 0%, #D4B87A 100%);
    color: #1A0E00;
    font-size: 30px;
    font-weight: 700;
    padding: 18px 36px;
    border-radius: 6px;
    letter-spacing: -0.3px;
    width: fit-content;
    box-shadow: 0 4px 16px rgba(160,120,40,0.30);
  }}

  .cta-arrow {{
    margin-left: 10px;
    font-size: 26px;
  }}
</style>
</head>
<body>
<div class="canvas">

  <!-- 우측 배경 이미지 -->
  <div class="bg-image"></div>

  <!-- 그라데이션 오버레이 -->
  <div class="bg-gradient-overlay"></div>

  <!-- 좌측 텍스트 영역 -->
  <div class="text-area">

    <!-- 뱃지 -->
    <div class="badge">
      <span class="badge-dot"></span>
      서울대보험쌤
    </div>

    <!-- 헤드라인 -->
    <div class="headline">서울대 출신 지점장과<br>함께 시작</div>

    <!-- 서브 카피 -->
    <div class="subcopy">AI자동화 | 멘토링 | 100일 로드맵</div>

    <!-- CTA 버튼 -->
    <div class="cta-btn">
      조직 설계 상담 받기
      <span class="cta-arrow">→</span>
    </div>

  </div>

</div>
</body>
</html>"""


# ────────────────────────────────────────────────────────────────
# HTML 템플릿: 1080x1080 (정사각형)
# ────────────────────────────────────────────────────────────────

def build_html_1080x1080(bg_image_path: str) -> str:
    font_dir = str(FONT_DIR)
    return f"""<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
  @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-SemiBold.otf') format('opentype');
    font-weight: 600;
  }}
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{font_dir}/Pretendard-Medium.otf') format('opentype');
    font-weight: 500;
  }}

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

  body {{
    width: 1080px;
    height: 1080px;
    overflow: hidden;
    background: #FFF8E7;
  }}

  .canvas {{
    width: 1080px;
    height: 1080px;
    position: relative;
    font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    overflow: hidden;
  }}

  /* 전체 배경 이미지 */
  .bg-full {{
    position: absolute;
    top: 0;
    left: 0;
    width: 1080px;
    height: 1080px;
    background-image: url('file://{bg_image_path}');
    background-size: cover;
    background-position: center;
    z-index: 1;
  }}

  /* 크림 반투명 오버레이 (하단 2/3) */
  .overlay {{
    position: absolute;
    top: 0;
    left: 0;
    width: 1080px;
    height: 1080px;
    background: linear-gradient(
      to bottom,
      rgba(255,248,231,0.15) 0%,
      rgba(255,248,231,0.25) 20%,
      rgba(255,248,231,0.50) 45%,
      rgba(255,248,231,0.82) 65%,
      rgba(255,248,231,0.95) 80%,
      rgba(255,248,231,1.00) 100%
    );
    z-index: 2;
  }}

  /* 전체 콘텐츠 래퍼 */
  .content {{
    position: absolute;
    top: 0;
    left: 0;
    width: 1080px;
    height: 1080px;
    z-index: 10;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 0 80px;
  }}

  /* 상단 뱃지 영역 (상단 12%) */
  .badge-wrap {{
    padding-top: 64px;
    display: flex;
    justify-content: center;
    width: 100%;
  }}

  .badge {{
    display: inline-flex;
    align-items: center;
    background: #C9A84C;
    color: #1A0E00;
    font-size: 34px;
    font-weight: 700;
    padding: 12px 28px;
    border-radius: 6px;
    letter-spacing: -0.3px;
  }}

  .badge-dot {{
    width: 12px;
    height: 12px;
    background: #1A0E00;
    border-radius: 50%;
    margin-right: 12px;
    flex-shrink: 0;
  }}

  /* 헤드라인 영역 (중앙 상단 35%) */
  .headline-wrap {{
    margin-top: 48px;
    text-align: center;
    flex: 0 0 auto;
  }}

  .headline {{
    font-size: 66px;
    font-weight: 700;
    color: #3E2723;
    line-height: 1.25;
    letter-spacing: -2px;
    text-align: center;
  }}

  /* 서브 카피 (중앙 25%) */
  .subcopy-wrap {{
    margin-top: 36px;
    text-align: center;
  }}

  .subcopy {{
    font-size: 42px;
    font-weight: 600;
    color: #A07828;
    letter-spacing: -0.8px;
    line-height: 1.4;
    text-align: center;
  }}

  /* 구분선 */
  .divider {{
    width: 120px;
    height: 3px;
    background: linear-gradient(to right, transparent, #C9A84C, transparent);
    margin: 32px auto 0;
  }}

  /* CTA 영역 (하단 28%) */
  .cta-wrap {{
    margin-top: auto;
    padding-bottom: 80px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 20px;
    width: 100%;
  }}

  .cta-btn {{
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, #C9A84C 0%, #D4B87A 100%);
    color: #1A0E00;
    font-size: 44px;
    font-weight: 700;
    padding: 24px 64px;
    border-radius: 6px;
    letter-spacing: -0.5px;
    box-shadow: 0 6px 24px rgba(160,120,40,0.35);
    width: 100%;
    max-width: 780px;
  }}

  .cta-arrow {{
    margin-left: 14px;
    font-size: 38px;
  }}

  /* URL 힌트 */
  .url-hint {{
    font-size: 26px;
    font-weight: 500;
    color: #8D6E3E;
    letter-spacing: 0;
  }}
</style>
</head>
<body>
<div class="canvas">

  <!-- 배경 이미지 -->
  <div class="bg-full"></div>

  <!-- 크림 오버레이 -->
  <div class="overlay"></div>

  <!-- 콘텐츠 -->
  <div class="content">

    <!-- 상단 뱃지 -->
    <div class="badge-wrap">
      <div class="badge">
        <span class="badge-dot"></span>
        서울대보험쌤
      </div>
    </div>

    <!-- 헤드라인 -->
    <div class="headline-wrap">
      <div class="headline">서울대 출신 지점장과<br>함께 시작</div>
    </div>

    <!-- 서브 카피 -->
    <div class="subcopy-wrap">
      <div class="subcopy">AI자동화 | 멘토링 | 100일 로드맵</div>
      <div class="divider"></div>
    </div>

    <!-- CTA 영역 -->
    <div class="cta-wrap">
      <div class="cta-btn">
        조직 설계 상담 받기
        <span class="cta-arrow">→</span>
      </div>
      <div class="url-hint">incar-top.tistory.com</div>
    </div>

  </div>

</div>
</body>
</html>"""


def capture_banner(html_content: str, output_path: Path, width: int, height: int) -> bool:
    """Playwright로 HTML을 캡처하여 PNG 저장."""
    html_file = output_path.with_suffix(".html")
    html_file.write_text(html_content, encoding="utf-8")
    print(f"[HTML] 템플릿 저장: {html_file}")

    try:
        with sync_playwright() as p:
            browser = p.chromium.launch()
            try:
                page = browser.new_page(viewport={"width": width, "height": height})
                page.goto(f"file://{html_file.resolve()}", wait_until="networkidle")
                page.wait_for_timeout(2500)  # 폰트 렌더링 대기
                page.screenshot(path=str(output_path), type="png")
            finally:
                browser.close()

        size_kb = output_path.stat().st_size / 1024
        print(f"[캡처] 저장 완료: {output_path} ({size_kb:.0f} KB)")
        return True

    except Exception as e:
        print(f"[오류] 캡처 실패: {type(e).__name__}: {e}")
        return False


def main() -> None:
    print("=" * 60)
    print("M3-2 서울대보험쌤 × 관리자 비전 배너 생성")
    print("=" * 60)

    bg_path = OUTPUT_DIR / "snu_leader_bg.jpg"

    # 1. Gemini 배경 생성
    if bg_path.exists():
        print(f"[배경] 기존 이미지 재사용: {bg_path}")
        bg_ok = True
    else:
        bg_ok = generate_gemini_background(bg_path)

    if not bg_ok:
        print("[경고] 배경 생성 실패. 크림 단색 배경으로 대체합니다.")
        # fallback: 빈 크림 배경 (배경 없이도 진행)
        bg_image_path = ""
    else:
        bg_image_path = str(bg_path.resolve())

    results = {}

    # 2. 1200x628 가로형 배너
    print("\n[배너 1] 1200x628 가로형 생성 중...")
    output_1200 = OUTPUT_DIR / "snu-leader-1200x628.png"
    html_1200 = build_html_1200x628(bg_image_path)
    ok1 = capture_banner(html_1200, output_1200, 1200, 628)
    results["1200x628"] = {"path": str(output_1200), "success": ok1}

    # 3. 1080x1080 정사각형 배너
    print("\n[배너 2] 1080x1080 정사각형 생성 중...")
    output_1080 = OUTPUT_DIR / "snu-leader-1080x1080.png"
    html_1080 = build_html_1080x1080(bg_image_path)
    ok2 = capture_banner(html_1080, output_1080, 1080, 1080)
    results["1080x1080"] = {"path": str(output_1080), "success": ok2}

    # 4. 결과 요약
    print("\n" + "=" * 60)
    print("생성 결과 요약")
    print("=" * 60)
    for size, r in results.items():
        status = "성공" if r["success"] else "실패"
        print(f"  [{size}] {status}: {r['path']}")


if __name__ == "__main__":
    main()
