#!/usr/bin/env python3
"""인카다이렉트 M1-2 '관리자 비전' Google 광고 배너 생성기.

Gemini API로 서울 고층빌딩 프라이빗 오피스 배경을 생성하고,
HTML/CSS + Playwright로 한글 텍스트를 정밀하게 오버레이합니다.

출력:
  - /home/jay/workspace/output/google-ads/banners/m1/m1-2-1200x628.png
  - /home/jay/workspace/output/google-ads/banners/m1/m1-2-1080x1080.png
"""

from __future__ import annotations

import base64
import json
import sys
import time
from pathlib import Path

import requests
from playwright.sync_api import sync_playwright

# ─── 경로 설정 ────────────────────────────────────────────────────────────────

TOOL_DIR = Path(__file__).parent
sys.path.insert(0, str(TOOL_DIR))

import gcloud_auth  # noqa: E402

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

TMP_DIR = TOOL_DIR / "output" / "v4-hybrid" / "m1-2-leader"
TMP_DIR.mkdir(parents=True, exist_ok=True)

# ─── Gemini API 설정 ──────────────────────────────────────────────────────────

GEMINI_API_BASE = "https://generativelanguage.googleapis.com/v1beta"
GEMINI_SCOPE = "https://www.googleapis.com/auth/generative-language"
MODEL_ID = "gemini-2.0-flash-preview-image-generation"
FALLBACK_MODEL_ID = "gemini-2.5-flash-image"

# ─── 배경 프롬프트 ────────────────────────────────────────────────────────────

BG_PROMPT = (
    "Photographic scene of a spacious, modern private office in a Seoul "
    "high-rise building. Wide angle shot from the doorway, looking in. "
    "Floor-to-ceiling windows spanning the back wall reveal a panoramic "
    "Seoul cityscape with afternoon natural light streaming through. "
    "A clean, uncluttered desk made of warm walnut wood in the foreground, "
    "with a MacBook Pro open and two neatly stacked documents. "
    "A single leather executive chair behind the desk — empty, suggesting "
    "the owner's presence without showing a person. No clutter on the "
    "desk except a sleek desk lamp on the right corner. The room feels "
    "owned and purposeful, not just leased. Warm, directional late afternoon "
    "sunlight. Bokeh background city view. Shot on full-frame camera, "
    "f/2.8 equivalent quality. Professional, aspirational, ownership feeling."
)

# ─── HTML 템플릿 ──────────────────────────────────────────────────────────────

HTML_1200x628 = """<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1200">
<style>
  @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;500;700;900&display=swap');

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

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

  .banner {{
    position: relative;
    width: 1200px;
    height: 628px;
    overflow: hidden;
    background: #1B365D;
  }}

  /* 배경 이미지 - 전체, 우측 중심 */
  .bg-image {{
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    background-image: url('{bg_url}');
    background-size: cover;
    background-position: center right;
  }}

  /* 좌측 코퍼레이트 블루 그라데이션 오버레이 (0~660px) */
  .left-overlay {{
    position: absolute;
    top: 0; left: 0;
    width: 660px;
    height: 100%;
    background: linear-gradient(
      to right,
      rgba(43, 87, 151, 0.88) 0%,
      rgba(43, 87, 151, 0.82) 70%,
      rgba(43, 87, 151, 0.40) 90%,
      rgba(43, 87, 151, 0.00) 100%
    );
  }}

  /* 골드 세로 액센트바 */
  .accent-bar {{
    position: absolute;
    top: 80px; left: 0;
    width: 4px; height: 460px;
    background: linear-gradient(to bottom, #C5A572, #D4B87A);
    border-radius: 2px;
  }}

  /* 텍스트 콘텐츠 영역 */
  .text-area {{
    position: absolute;
    top: 0; left: 0;
    width: 620px;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 52px 60px;
  }}

  /* 뱃지 */
  .badge {{
    display: inline-block;
    background: #C5A572;
    color: #1B365D;
    font-size: 40px;
    font-weight: 700;
    height: 48px;
    line-height: 48px;
    padding: 8px 20px;
    border-radius: 4px;
    letter-spacing: -0.03em;
    white-space: nowrap;
    box-sizing: content-box;
    margin-bottom: 24px;
  }}

  /* 메인 헤드라인 */
  .headline {{
    font-size: 58px;
    font-weight: 700;
    color: #F0F4F8;
    line-height: 1.2;
    letter-spacing: -0.01em;
    margin-bottom: 20px;
    word-break: keep-all;
  }}

  /* 혜택 나열 */
  .benefits {{
    font-size: 44px;
    font-weight: 500;
    color: #F0F4F8;
    line-height: 1.4;
    letter-spacing: -0.03em;
    margin-bottom: 36px;
    word-break: keep-all;
    white-space: nowrap;
    text-shadow: 0 1px 3px rgba(0,0,0,0.4);
  }}

  /* CTA 버튼 - 절대 위치 */
  .cta-btn {{
    position: absolute;
    bottom: 52px;
    left: 60px;
    display: inline-block;
    background: linear-gradient(135deg, #C5A572 0%, #D4B87A 100%);
    color: #1A0E00;
    font-size: 44px;
    font-weight: 700;
    padding: 14px 36px;
    border-radius: 6px;
    letter-spacing: 0.02em;
    min-width: 280px;
    text-align: center;
    line-height: 1.2;
    box-shadow: 0 4px 16px rgba(197, 165, 114, 0.35);
    white-space: nowrap;
  }}
</style>
</head>
<body>
<div class="banner">
  <div class="bg-image"></div>
  <div class="left-overlay"></div>
  <div class="accent-bar"></div>
  <div class="text-area">
    <div class="badge">인카금융서비스 | 지점장 성장</div>
    <div class="headline"><span style="color:#C5A572">모든 권한</span>으로<br>조직 운영하세요</div>
    <div class="benefits">개설비 전액 지원 | 리쿠르팅 협업</div>
  </div>
  <div class="cta-btn">지점 개설 조건 확인 →</div>
</div>
</body>
</html>"""

HTML_1080x1080 = """<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1080">
<style>
  @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;500;700;900&display=swap');

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

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

  .banner {{
    position: relative;
    width: 1080px;
    height: 1080px;
    overflow: hidden;
    background: #1B365D;
  }}

  /* 배경 이미지 전체 */
  .bg-image {{
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    background-image: url('{bg_url}');
    background-size: cover;
    background-position: center center;
  }}

  /* 상단 코퍼레이트 블루 그라데이션 오버레이 (70% 높이) */
  .top-overlay {{
    position: absolute;
    top: 0; left: 0;
    width: 100%;
    height: 70%;
    background: linear-gradient(
      to bottom,
      rgba(43, 87, 151, 0.85) 0%,
      rgba(43, 87, 151, 0.70) 40%,
      rgba(43, 87, 151, 0.50) 70%,
      rgba(43, 87, 151, 0.00) 100%
    );
  }}

  /* 하단 코퍼레이트 블루 그라데이션 오버레이 (38% 높이) */
  .bottom-overlay {{
    position: absolute;
    bottom: 0; left: 0;
    width: 100%;
    height: 38%;
    background: linear-gradient(
      to top,
      rgba(43, 87, 151, 0.92) 0%,
      rgba(43, 87, 151, 0.70) 60%,
      rgba(43, 87, 151, 0.00) 100%
    );
  }}

  /* 전체 텍스트 레이아웃 */
  .content {{
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 60px 80px;
    justify-content: center;
  }}

  /* 뱃지 */
  .badge {{
    display: inline-block;
    background: #C5A572;
    color: #1B365D;
    font-size: 40px;
    font-weight: 700;
    height: 52px;
    line-height: 52px;
    padding: 10px 24px;
    border-radius: 4px;
    letter-spacing: -0.03em;
    white-space: nowrap;
    box-sizing: content-box;
    margin-bottom: 32px;
  }}

  /* 메인 헤드라인 */
  .headline {{
    font-size: 62px;
    font-weight: 700;
    color: #F0F4F8;
    line-height: 1.35;
    letter-spacing: -0.01em;
    text-align: center;
    margin-bottom: 36px;
    word-break: keep-all;
  }}

  /* 골드 구분선 */
  .divider {{
    width: 60px;
    height: 3px;
    background: linear-gradient(to right, #C5A572, #D4B87A);
    margin: 0 auto 36px auto;
    border-radius: 2px;
    flex-shrink: 0;
  }}

  /* 혜택 목록 */
  .benefits {{
    display: flex;
    flex-direction: column;
    gap: 18px;
    width: 100%;
    align-items: center;
    margin-bottom: 0;
  }}

  .benefit-item {{
    font-size: 44px;
    font-weight: 500;
    color: #FFFFFF;
    line-height: 1.4;
    text-align: center;
    word-break: keep-all;
    padding: 0 20px;
    text-shadow: 0 2px 6px rgba(0,0,0,0.6);
  }}

  /* CTA 버튼 - 절대 위치 */
  .cta-btn {{
    position: absolute;
    bottom: 60px;
    left: 50%;
    transform: translateX(-50%);
    display: inline-block;
    background: linear-gradient(135deg, #C5A572 0%, #D4B87A 100%);
    color: #1A0E00;
    font-size: 40px;
    font-weight: 700;
    padding: 18px 56px;
    border-radius: 6px;
    letter-spacing: 0.03em;
    min-width: 300px;
    text-align: center;
    line-height: 1.3;
    box-shadow: 0 6px 24px rgba(197, 165, 114, 0.40);
    white-space: nowrap;
  }}
</style>
</head>
<body>
<div class="banner">
  <div class="bg-image"></div>
  <div class="top-overlay"></div>
  <div class="bottom-overlay"></div>
  <div class="content">
    <div class="badge">인카금융서비스 | 지점장 성장</div>
    <div class="headline"><span style="color:#C5A572">모든 권한</span>으로<br>조직 운영하세요</div>
    <div class="divider"></div>
    <div class="benefits">
      <div class="benefit-item"><span style="color:#C5A572">개설비 전액 | 리쿠르팅 협업</span></div>
      <div class="benefit-item">조직 확장 시스템 지원</div>
    </div>
  </div>
  <div class="cta-btn">지점 개설 조건 확인 →</div>
</div>
</body>
</html>"""


# ─── Gemini 이미지 생성 ───────────────────────────────────────────────────────

def generate_bg_image(token: str, output_path: Path) -> Path:
    """Gemini API로 배경 이미지를 생성하고 저장합니다."""
    print(f"[배경] Gemini API로 오피스 배경 생성 중... (모델: {MODEL_ID})")
    start = time.time()

    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"]},
    }

    response = requests.post(url, headers=headers, json=payload, timeout=300)

    # fallback
    if response.status_code in (400, 403, 404):
        print(f"[배경] 모델 {MODEL_ID} 실패 (HTTP {response.status_code}). Fallback: {FALLBACK_MODEL_ID}")
        url2 = f"{GEMINI_API_BASE}/models/{FALLBACK_MODEL_ID}:generateContent"
        response = requests.post(url2, headers=headers, json=payload, timeout=300)

    if not response.ok:
        print(f"[배경] API 오류: {response.status_code} - {response.text[:400]}")
        response.raise_for_status()

    data = response.json()
    candidates = data.get("candidates", [])
    if not candidates:
        raise RuntimeError(f"응답에 candidates 없음: {json.dumps(data)[:300]}")

    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:
        text_parts = [p.get("text", "") for p in parts if "text" in p]
        raise RuntimeError(f"이미지 데이터 없음. 텍스트: {text_parts[:2]}")

    mime_type = image_part["inlineData"].get("mimeType", "image/jpeg")
    image_bytes = base64.b64decode(image_part["inlineData"]["data"])

    ext = ".jpg" if "jpeg" in mime_type else ".png"
    final_path = output_path.with_suffix(ext)
    final_path.write_bytes(image_bytes)

    elapsed = time.time() - start
    print(f"[배경] 완료: {final_path.name} ({len(image_bytes):,} bytes, {elapsed:.1f}초)")
    return final_path


# ─── Playwright HTML → PNG 캡처 ───────────────────────────────────────────────

def capture_html_to_png(
    html_content: str,
    bg_path: Path,
    output_path: Path,
    width: int,
    height: int,
) -> None:
    """HTML 템플릿에 배경 이미지 URL을 삽입하고 Playwright로 PNG 캡처합니다."""
    bg_url = f"file://{bg_path.resolve()}"
    html_filled = html_content.format(bg_url=bg_url)

    # 임시 HTML 파일 저장
    tmp_html = TMP_DIR / f"tmp_{width}x{height}.html"
    tmp_html.write_text(html_filled, encoding="utf-8")

    print(f"[캡처] Playwright로 {width}x{height} 캡처 중...")
    with sync_playwright() as p:
        browser = p.chromium.launch(args=["--no-sandbox", "--disable-gpu"])
        try:
            page = browser.new_page(viewport={"width": width, "height": height})
            page.goto(f"file://{tmp_html.resolve()}", wait_until="networkidle")
            # 폰트 로딩 대기
            page.wait_for_timeout(2500)
            output_path.parent.mkdir(parents=True, exist_ok=True)
            page.screenshot(path=str(output_path), type="png", clip={
                "x": 0, "y": 0, "width": width, "height": height
            })
            print(f"[캡처] 저장 완료: {output_path}")
        finally:
            browser.close()

    tmp_html.unlink(missing_ok=True)


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

def main() -> None:
    print("=" * 60)
    print("인카다이렉트 M1-2 '관리자 비전' Google 배너 생성 시작")
    print("=" * 60)

    # 1. 인증 토큰 획득
    print("\n[인증] SA 토큰 획득 중...")
    try:
        token = gcloud_auth.get_access_token()
        print(f"[인증] 토큰 획득 성공 (길이: {len(token)} chars)")
    except Exception as e:
        print(f"[인증] 실패: {e}")
        raise SystemExit(1) from e

    # 2. Gemini 배경 이미지 생성 (공유 배경) — 이미 존재하면 재사용
    print("\n[배경] 배경 이미지 확인 중...")
    bg_tmp_path = TMP_DIR / "bg_m1_2_leader"
    existing = list(TMP_DIR.glob("bg_m1_2_leader.*"))
    if existing:
        bg_path = existing[0]
        print(f"[배경] 기존 이미지 재사용: {bg_path.name}")
    else:
        try:
            bg_path = generate_bg_image(token, bg_tmp_path)
        except Exception as e:
            print(f"[배경] 생성 실패: {e}")
            raise SystemExit(1) from e

    # 3. 배너 1: 1200x628 가로형
    print("\n[배너 1] 1200x628 가로형 생성 중...")
    output_1200 = OUTPUT_DIR / "m1-2-1200x628.png"
    try:
        capture_html_to_png(
            html_content=HTML_1200x628,
            bg_path=bg_path,
            output_path=output_1200,
            width=1200,
            height=628,
        )
        size_kb = output_1200.stat().st_size / 1024
        print(f"[배너 1] 완료: {output_1200} ({size_kb:.0f} KB)")
    except Exception as e:
        print(f"[배너 1] 실패: {e}")
        import traceback; traceback.print_exc()

    # 4. 배너 2: 1080x1080 정사각형
    print("\n[배너 2] 1080x1080 정사각형 생성 중...")
    output_1080 = OUTPUT_DIR / "m1-2-1080x1080.png"
    try:
        capture_html_to_png(
            html_content=HTML_1080x1080,
            bg_path=bg_path,
            output_path=output_1080,
            width=1080,
            height=1080,
        )
        size_kb = output_1080.stat().st_size / 1024
        print(f"[배너 2] 완료: {output_1080} ({size_kb:.0f} KB)")
    except Exception as e:
        print(f"[배너 2] 실패: {e}")
        import traceback; traceback.print_exc()

    print("\n" + "=" * 60)
    print("생성 완료")
    print(f"  배너 1: {output_1200}")
    print(f"  배너 2: {output_1080}")
    print("=" * 60)


if __name__ == "__main__":
    main()
