#!/usr/bin/env python3
"""GA 배너 M2-3 'GA × 영업지원' 세트 생성 — 하이브리드 방식 (Gemini 배경 + Playwright 오버레이).

산출물:
  /home/jay/workspace/output/google-ads/banners/m2/m2-3-1200x628.png
  /home/jay/workspace/output/google-ads/banners/m2/m2-3-1080x1080.png
"""

from __future__ import annotations

import base64
import sys
import time
from pathlib import Path

import requests
from playwright.sync_api import sync_playwright

# ──────────────────────────────────────────────────────────
# 경로 설정
# ──────────────────────────────────────────────────────────
TOOL_DIR = Path("/home/jay/workspace/tools/ai-image-gen")
sys.path.insert(0, str(TOOL_DIR))

import gcloud_auth  # noqa: E402

OUTPUT_DIR = Path("/home/jay/workspace/output/google-ads/banners/m2")
BG_IMAGE_PATH = OUTPUT_DIR / "m2-3-bg.jpg"

OUTPUT_1200x628 = OUTPUT_DIR / "m2-3-1200x628.png"
OUTPUT_1080x1080 = OUTPUT_DIR / "m2-3-1080x1080.png"

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

# ──────────────────────────────────────────────────────────
# Gemini 배경 생성 프롬프트 (M2-3 영업지원 — 소규모 협업 팀)
# ──────────────────────────────────────────────────────────
GEMINI_BG_PROMPT = (
    "Photographic scene of a small, bright team working space in Seoul. "
    "Medium shot, eye-level angle from the side. A round table with 2-3 "
    "young professionals (20s-30s) seated, one laptop open in the center. "
    "They are looking at the screen together in a collaborative, relaxed "
    "posture — not formal. No one is presenting or leading; it feels like "
    "a peer discussion. Natural light from a large window on the left. "
    "White and light wood interior. A small succulent plant in the corner "
    "of the table. People are in business casual — light shirts, no ties. "
    "Faces are angled away or partially obscured by looking at the screen. "
    "Warm, inviting, supportive atmosphere — feels like a good team to join. "
    "Background: clean white wall, one simple plant on a shelf. "
    "사진 품질, 실사, 소규모 협업 팀 장면, 밝고 따뜻한 분위기."
)

GEMINI_API_BASE = "https://generativelanguage.googleapis.com/v1beta"
GEMINI_SCOPE = "https://www.googleapis.com/auth/generative-language"

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


def generate_background() -> Path:
    """Gemini API로 배경 이미지를 생성하고 저장합니다."""
    print("[배경 생성] Gemini API 호출 중...")

    # API 키 우선 시도
    api_key = gcloud_auth.get_api_key("GEMINI_API_KEY")

    if api_key:
        print("  인증: API 키 사용")
        for model in MODELS_TO_TRY:
            print(f"  모델 시도: {model}")
            try:
                url = f"{GEMINI_API_BASE}/models/{model}:generateContent?key={api_key}"
                payload = {
                    "contents": [{"parts": [{"text": GEMINI_BG_PROMPT}]}],
                    "generationConfig": {"responseModalities": ["IMAGE", "TEXT"]},
                }
                resp = requests.post(url, json=payload, timeout=120)
                if resp.status_code == 200:
                    data = resp.json()
                    candidates = data.get("candidates", [])
                    if candidates:
                        parts = candidates[0].get("content", {}).get("parts", [])
                        for part in parts:
                            if "inlineData" in part:
                                img_b64 = part["inlineData"]["data"]
                                img_bytes = base64.b64decode(img_b64)
                                BG_IMAGE_PATH.write_bytes(img_bytes)
                                print(f"  배경 생성 완료: {BG_IMAGE_PATH} ({len(img_bytes):,} bytes)")
                                return BG_IMAGE_PATH
                print(f"  {model} 응답 {resp.status_code}: {resp.text[:200]}")
            except Exception as e:
                print(f"  {model} 오류: {e}")

    # SA 토큰 시도
    print("  API 키 실패, SA 토큰 시도...")
    try:
        token = gcloud_auth.get_service_account_token(GEMINI_SCOPE)
        for model in MODELS_TO_TRY:
            try:
                url = f"{GEMINI_API_BASE}/models/{model}:generateContent"
                headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
                payload = {
                    "contents": [{"parts": [{"text": GEMINI_BG_PROMPT}]}],
                    "generationConfig": {"responseModalities": ["IMAGE", "TEXT"]},
                }
                resp = requests.post(url, headers=headers, json=payload, timeout=120)
                if resp.status_code == 200:
                    data = resp.json()
                    candidates = data.get("candidates", [])
                    if candidates:
                        parts = candidates[0].get("content", {}).get("parts", [])
                        for part in parts:
                            if "inlineData" in part:
                                img_b64 = part["inlineData"]["data"]
                                img_bytes = base64.b64decode(img_b64)
                                BG_IMAGE_PATH.write_bytes(img_bytes)
                                print(f"  배경 생성 완료 (SA): {BG_IMAGE_PATH}")
                                return BG_IMAGE_PATH
                print(f"  SA/{model} 응답 {resp.status_code}: {resp.text[:200]}")
            except Exception as e:
                print(f"  SA/{model} 오류: {e}")
    except Exception as e:
        print(f"  SA 토큰 오류: {e}")

    raise RuntimeError("모든 Gemini API 인증 방법 실패 — 배경 이미지를 생성할 수 없습니다.")


# ──────────────────────────────────────────────────────────
# HTML 템플릿 — 1200x628 (가로형)
# 디자인 스펙 (M2-3 밝은 톤):
#   - 배경 전체 깔림 + 좌측 720px 라이트 그린 소프트 패널 #E8F5E9 opacity 0.80
#   - 패딩: 좌 60px, 상 52px
#   - 헤드라인: 52px Bold #2E7D32 (밝은 배경, 다크 텍스트), line-height 1.2
#   - 지원 항목(서브카피): 44px Medium #546E7A, gap 20px
#   - 보조 정보: 40px Medium #2E7D32, gap 16px
#   - CTA: y:530px 고정, 높이 56px, 너비 280px, round 8px, 틸 #00897B, 텍스트 #1A3320 44px Bold
#   - 모서리 radius 8px
# ──────────────────────────────────────────────────────────
def build_html_1200x628(bg_image_path: str) -> str:
    return f"""<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
  @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;
  }}
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{FONT_DIR}/Pretendard-Regular.otf') format('opentype');
    font-weight: 400;
  }}

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

  body {{
    width: 1200px;
    height: 628px;
    overflow: hidden;
    font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
  }}

  .canvas {{
    width: 1200px;
    height: 628px;
    position: relative;
    overflow: hidden;
    border-radius: 0;
  }}

  /* 전체 배경 이미지 (우측에 팀 협업 장면 표시) */
  .bg-full {{
    position: absolute;
    top: 0;
    left: 0;
    width: 1200px;
    height: 628px;
    background-image: url('file://{bg_image_path}');
    background-size: cover;
    background-position: center center;
  }}

  /* 좌측 720px 라이트 그린 소프트 패널 (opacity 0.80) */
  .overlay-left {{
    position: absolute;
    top: 0;
    left: 0;
    width: 720px;
    height: 628px;
    background: linear-gradient(
      to right,
      rgba(232, 245, 233, 0.80) 0%,
      rgba(232, 245, 233, 0.80) 75%,
      rgba(232, 245, 233, 0.40) 88%,
      rgba(232, 245, 233, 0.0) 100%
    );
  }}

  /* 텍스트 영역 — 좌측 720px, 패딩 좌 60px 상 52px */
  .text-area {{
    position: absolute;
    top: 0;
    left: 0;
    width: 720px;
    height: 628px;
    padding-left: 60px;
    padding-top: 52px;
    padding-right: 40px;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: flex-start;
  }}

  /* 헤드라인: 58px Bold #2E7D32, line-height 1.2 */
  .headline {{
    font-size: 58px;
    font-weight: 700;
    color: #2E7D32;
    line-height: 1.2;
    letter-spacing: -1px;
    margin-top: 20px;
    white-space: pre-line;
  }}

  /* 지원 항목(서브카피): 44px Medium #546E7A, gap 20px */
  .subcopy {{
    font-size: 44px;
    font-weight: 500;
    color: #546E7A;
    line-height: 1.3;
    margin-top: 20px;
  }}

  /* 보조 정보: 40px Medium #2E7D32, gap 16px */
  .aux-info {{
    font-size: 40px;
    font-weight: 500;
    color: #2E7D32;
    line-height: 1.3;
    margin-top: 16px;
  }}

  /* CTA: y:530px 고정, 높이 56px, 너비 400px, round 4px */
  .cta-btn {{
    position: absolute;
    top: 530px;
    left: 60px;
    width: 400px;
    height: 56px;
    background: #00695C;
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 40px;
    font-weight: 700;
    color: #FFFFFF;
    white-space: nowrap;
    letter-spacing: -0.5px;
    padding: 0 16px;
  }}
</style>
</head>
<body>
<div class="canvas">

  <!-- 전체 배경 -->
  <div class="bg-full"></div>

  <!-- 좌측 라이트 그린 소프트 패널 오버레이 -->
  <div class="overlay-left"></div>

  <!-- 텍스트 영역 -->
  <div class="text-area">
    <div class="headline">영업이 힘들다면,&#10;시스템 있는 GA로</div>
    <div class="subcopy">DB 제공  |  교육  |  함께 성장</div>
    <div class="aux-info">혼자 뛰지 않는 보험영업 구조</div>
  </div>

  <!-- CTA 버튼 (y:530px 고정) -->
  <div class="cta-btn">영업지원 GA 알아보기 →</div>

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


# ──────────────────────────────────────────────────────────
# HTML 템플릿 — 1080x1080 (정사각형)
# 디자인 스펙 (M2-3 밝은 톤):
#   - 배경 전체 깔림 + 라이트 그린 반투명 오버레이 전체 opacity 0.35
#   - 패딩: 좌우 72px, 상 88px, 하 80px
#   - 헤드라인: 58px Bold #2E7D32, 중앙 정렬, line-height 1.2
#   - 지원 항목(서브카피): 44px Medium #546E7A, 중앙 정렬, gap 24px
#   - 보조 정보: 40px Medium #2E7D32, 중앙 정렬, gap 16px
#   - CTA: 중앙 정렬, 높이 68px, 너비 380px, round 8px, 틸 #00897B, 텍스트 #1A3320 48px Bold, gap 36px
# ──────────────────────────────────────────────────────────
def build_html_1080x1080(bg_image_path: str) -> str:
    return f"""<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
  @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;
  }}
  @font-face {{
    font-family: 'Pretendard';
    src: url('file://{FONT_DIR}/Pretendard-Regular.otf') format('opentype');
    font-weight: 400;
  }}

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

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

  .canvas {{
    width: 1080px;
    height: 1080px;
    position: relative;
    overflow: hidden;
    border-radius: 0;
  }}

  /* 전체 배경 이미지 (팀 협업 장면이 보여야 함) */
  .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 center;
  }}

  /* 라이트 그린 전체 오버레이 opacity 0.25 (배경 협업 장면이 더 보임) */
  .overlay-full {{
    position: absolute;
    top: 0;
    left: 0;
    width: 1080px;
    height: 1080px;
    background: rgba(232, 245, 233, 0.35);
  }}

  /* 반투명 화이트 텍스트 패널 */
  .text-panel {{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 800px;
    padding: 60px 48px;
    background: rgba(255, 255, 255, 0.88);
    border-radius: 12px;
    backdrop-filter: blur(4px);
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
  }}

  /* 콘텐츠 영역: 패딩 좌우 72px, 상 88px, 하 80px, 중앙 정렬 */
  .content-area {{
    position: absolute;
    top: 0;
    left: 0;
    width: 1080px;
    height: 1080px;
    padding: 88px 72px 80px 72px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
  }}

  /* 헤드라인: 60px Bold #2E7D32 (포레스트 그린), 중앙 정렬, line-height 1.2 */
  .headline {{
    font-size: 60px;
    font-weight: 700;
    color: #2E7D32;
    line-height: 1.2;
    letter-spacing: -1.5px;
    text-align: center;
    white-space: pre-line;
    text-shadow: 0 1px 3px rgba(232, 245, 233, 0.8);
  }}

  /* 지원 항목(서브카피): 44px Medium #546E7A (쿨 그레이), 중앙 정렬, gap 24px */
  .subcopy {{
    font-size: 44px;
    font-weight: 500;
    color: #546E7A;
    line-height: 1.3;
    text-align: center;
    margin-top: 24px;
    text-shadow: 0 1px 3px rgba(232, 245, 233, 0.8);
  }}

  /* 보조 정보: 40px Medium #2E7D32 (포레스트 그린), 중앙 정렬, gap 16px */
  .aux-info {{
    font-size: 40px;
    font-weight: 500;
    color: #2E7D32;
    line-height: 1.3;
    text-align: center;
    margin-top: 16px;
    text-shadow: 0 1px 3px rgba(232, 245, 233, 0.8);
  }}

  /* CTA: 중앙, 높이 68px, 너비 380px, round 4px, gap 36px */
  .cta-btn {{
    margin-top: 36px;
    width: 380px;
    height: 68px;
    background: #00695C;
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 44px;
    font-weight: 700;
    color: #FFFFFF;
    white-space: nowrap;
    letter-spacing: -0.5px;
    text-shadow: none;
  }}
</style>
</head>
<body>
<div class="canvas">

  <!-- 전체 배경 -->
  <div class="bg-full"></div>

  <!-- 라이트 그린 전체 오버레이 (opacity 0.25, 배경 협업 장면 더 보임) -->
  <div class="overlay-full"></div>

  <!-- 반투명 화이트 텍스트 패널 (배경과 텍스트 분리) -->
  <div class="text-panel">
    <div class="headline">영업이 힘들다면,&#10;시스템 있는 GA로</div>
    <div class="subcopy">DB 제공  |  교육  |  함께 성장</div>
    <div class="aux-info">혼자 뛰지 않는 보험영업 구조</div>
    <div class="cta-btn">영업지원 GA 알아보기 →</div>
  </div>

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


# ──────────────────────────────────────────────────────────
# Playwright 캡처
# ──────────────────────────────────────────────────────────
def capture(html_content: str, output_path: Path, width: int, height: int) -> None:
    html_file = output_path.parent / f"_tmp_{output_path.stem}.html"
    html_file.write_text(html_content, encoding="utf-8")
    print(f"  HTML 템플릿 저장: {html_file}")

    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")
            print(f"  캡처 완료: {output_path} ({output_path.stat().st_size:,} bytes)")
        finally:
            browser.close()


# ──────────────────────────────────────────────────────────
# 메인
# ──────────────────────────────────────────────────────────
def main() -> None:
    OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
    print("=" * 60)
    print("GA 배너 M2-3 'GA × 영업지원' 하이브리드 이미지 생성")
    print("=" * 60)

    # 1. Gemini 배경 생성
    t0 = time.time()
    bg_path = generate_background()
    print(f"  배경 생성 소요: {time.time()-t0:.1f}초\n")

    bg_str = str(bg_path.resolve())

    # 2. 1200x628 생성
    print("[1/2] 1200x628 가로형 배너 생성...")
    t1 = time.time()
    html_wide = build_html_1200x628(bg_str)
    capture(html_wide, OUTPUT_1200x628, 1200, 628)
    print(f"  소요: {time.time()-t1:.1f}초\n")

    # 3. 1080x1080 생성
    print("[2/2] 1080x1080 정사각형 배너 생성...")
    t2 = time.time()
    html_sq = build_html_1080x1080(bg_str)
    capture(html_sq, OUTPUT_1080x1080, 1080, 1080)
    print(f"  소요: {time.time()-t2:.1f}초\n")

    print("=" * 60)
    print("완료!")
    print(f"  {OUTPUT_1200x628}")
    print(f"  {OUTPUT_1080x1080}")
    print(f"  총 소요: {time.time()-t0:.1f}초")


if __name__ == "__main__":
    main()
