#!/usr/bin/env python3
"""
Sample C — 좌우 분할 솔루션형 (Split-Layout Solution) 배너 생성기
Gemini AI 배경 + HTML/CSS Playwright 오버레이 하이브리드 파이프라인
"""

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

# ─────────────────────────────────────────────────────────────────────────────
# 경로 상수
# ─────────────────────────────────────────────────────────────────────────────

BASE_DIR = Path("/home/jay/workspace/tools/ai-image-gen")
OUTPUT_DIR = Path("/home/jay/workspace/output/meta-ads/angle-A/concept-samples")
TEMP_DIR = BASE_DIR / "output" / "v4-hybrid"
BG_PATH = TEMP_DIR / "bg_sample_c_split.jpg"
TEMPLATE_PATH = TEMP_DIR / "sample_c_split_template.html"
FINAL_OUTPUT = OUTPUT_DIR / "sample-C-split.png"

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

# Gemini 배경 프롬프트 (영어로 최적화 — 한글 프롬프트보다 이미지 품질 우수)
BG_PROMPT = (
    "Create a dramatic split-layout image for a Korean business advertisement. "
    "Left half: A stressed Korean office worker silhouette in a dark, gloomy environment. "
    "Dark gray tones (#3A3A3A, #555555), desaturated, cold blue-gray shadows, "
    "heavy atmosphere, fluorescent office lighting casting harsh downward shadows, "
    "feeling of anxiety and stagnation. Person hunched at desk or standing with slumped shoulders. "
    "Right half: A bright, hopeful business environment with a successful Korean professional. "
    "Vibrant emerald green and teal tones (#00B894, #00CEC9), warm morning sunlight streaming through floor-to-ceiling windows, "
    "modern clean office space, Seoul skyline visible, feeling of growth and success. "
    "The center dividing line should be a natural gradient blend transitioning from dark gray to emerald green. "
    "No text in image. Professional advertising photography quality. 1080x1080px square format. "
    "Cinematic, aspirational, high contrast between left darkness and right brightness."
)


# ─────────────────────────────────────────────────────────────────────────────
# Step 1: Gemini 배경 이미지 생성
# ─────────────────────────────────────────────────────────────────────────────

def generate_background() -> Path:
    """Gemini API로 배경 이미지를 생성하고 저장합니다."""
    sys.path.insert(0, str(BASE_DIR))
    import gcloud_auth

    print("[1/3] Gemini API로 배경 이미지 생성 중...")
    token = gcloud_auth.get_service_account_token(GEMINI_SCOPE)
    print(f"      SA 토큰 획득 성공 (길이: {len(token)} chars)")

    # Pro 모델 우선, 실패 시 flash fallback
    for model_id in ["gemini-3-pro-image-preview", "gemini-3.1-flash-image-preview", "gemini-2.0-flash-preview-image-generation"]:
        print(f"      모델 시도: {model_id}")
        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"]},
        }

        try:
            resp = requests.post(url, headers=headers, json=payload, timeout=120)
            if resp.status_code in (403, 404):
                print(f"      HTTP {resp.status_code} — 다음 모델로 시도")
                continue
            resp.raise_for_status()
        except requests.HTTPError as e:
            print(f"      HTTP 오류: {e} — 다음 모델로 시도")
            continue

        data = resp.json()
        candidates = data.get("candidates", [])
        if not candidates:
            print(f"      candidates 없음 — 다음 모델로 시도")
            continue

        parts = 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"      이미지 데이터 없음 — 다음 모델로 시도")
            continue

        mime_type = image_part["inlineData"].get("mimeType", "image/jpeg")
        image_bytes = base64.b64decode(image_part["inlineData"]["data"])
        BG_PATH.write_bytes(image_bytes)
        print(f"      배경 저장: {BG_PATH} ({len(image_bytes):,} bytes, mime={mime_type})")
        return BG_PATH

    raise RuntimeError("모든 Gemini 모델 실패 — 배경 이미지 생성 불가")


# ─────────────────────────────────────────────────────────────────────────────
# Step 2: HTML 오버레이 템플릿 생성
# ─────────────────────────────────────────────────────────────────────────────

HTML_TEMPLATE = """<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=1080" />
  <title>Sample C — Split Layout Solution</title>
  <style>
    @import url('file:///home/jay/.local/share/fonts/Pretendard/PretendardVariable.ttf');

    @font-face {{
      font-family: 'Pretendard';
      src: url('file:///home/jay/.local/share/fonts/Pretendard/Pretendard-Black.otf') format('opentype');
      font-weight: 900;
    }}
    @font-face {{
      font-family: 'Pretendard';
      src: url('file:///home/jay/.local/share/fonts/Pretendard/Pretendard-Bold.otf') format('opentype');
      font-weight: 700;
    }}
    @font-face {{
      font-family: 'Pretendard';
      src: url('file:///home/jay/.local/share/fonts/Pretendard/Pretendard-Medium.otf') format('opentype');
      font-weight: 500;
    }}
    @font-face {{
      font-family: 'Pretendard';
      src: url('file:///home/jay/.local/share/fonts/Pretendard/Pretendard-Regular.otf') format('opentype');
      font-weight: 400;
    }}

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

    html, body {{
      width: 1080px;
      height: 1080px;
      overflow: hidden;
      -webkit-font-smoothing: antialiased;
    }}

    body {{
      font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
      position: relative;
      background: #1a1a1a;
    }}

    /* ── 배경 레이어 ── */
    #bg-layer {{
      position: absolute;
      inset: 0;
      z-index: 0;
      background-image: url('{bg_url}');
      background-size: cover;
      background-position: center center;
      background-repeat: no-repeat;
    }}

    /* ── 좌측 어두운 오버레이 ── */
    #left-overlay {{
      position: absolute;
      top: 0;
      left: 0;
      width: 50%;
      height: 100%;
      z-index: 1;
      background: linear-gradient(
        135deg,
        rgba(30, 30, 30, 0.72) 0%,
        rgba(58, 58, 58, 0.55) 70%,
        rgba(30, 30, 30, 0.10) 100%
      );
    }}

    /* ── 우측 밝은 오버레이 ── */
    #right-overlay {{
      position: absolute;
      top: 0;
      right: 0;
      width: 50%;
      height: 100%;
      z-index: 1;
      background: linear-gradient(
        225deg,
        rgba(0, 184, 148, 0.18) 0%,
        rgba(0, 206, 201, 0.12) 60%,
        rgba(0, 184, 148, 0.05) 100%
      );
    }}

    /* ── 중앙 그라디언트 분할선 ── */
    #center-divider {{
      position: absolute;
      top: 0;
      left: calc(50% - 40px);
      width: 80px;
      height: 100%;
      z-index: 2;
      background: linear-gradient(
        90deg,
        rgba(30, 30, 30, 0.30) 0%,
        rgba(100, 100, 100, 0.15) 30%,
        rgba(0, 184, 148, 0.20) 70%,
        rgba(0, 184, 148, 0.10) 100%
      );
    }}

    /* ── 비네트 (공통) ── */
    #vignette {{
      position: absolute;
      inset: 0;
      z-index: 3;
      background: radial-gradient(
        ellipse 90% 90% at center,
        transparent 40%,
        rgba(0, 0, 0, 0.40) 100%
      );
      pointer-events: none;
    }}

    /* ── 콘텐츠 래퍼 ── */
    #content {{
      position: absolute;
      inset: 0;
      z-index: 10;
      display: flex;
      align-items: stretch;
    }}

    /* ── 좌측 텍스트 영역 ── */
    #left-text {{
      flex: 1;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      padding: 60px 40px 180px 60px;
    }}

    .left-label {{
      font-size: 22px;
      font-weight: 500;
      color: rgba(200, 200, 200, 0.70);
      letter-spacing: 0.12em;
      text-transform: uppercase;
      margin-bottom: 24px;
      text-shadow: 0 1px 8px rgba(0,0,0,0.80);
    }}

    .left-headline {{
      font-size: 80px;
      font-weight: 900;
      line-height: 1.15;
      letter-spacing: -0.02em;
      color: #FFFFFF;
      text-align: center;
      word-break: keep-all;
      text-shadow:
        0 2px 12px rgba(0, 0, 0, 0.95),
        0 4px 40px rgba(0, 0, 0, 0.85),
        0 0 80px rgba(0, 0, 0, 0.70);
      background: rgba(15, 15, 15, 0.65);
      padding: 24px 40px;
      border-radius: 16px;
      backdrop-filter: blur(12px);
      -webkit-backdrop-filter: blur(12px);
      border: 1px solid rgba(255, 255, 255, 0.12);
      box-shadow: 0 8px 32px rgba(0,0,0,0.50);
    }}

    .left-accent {{
      width: 60px;
      height: 3px;
      background: linear-gradient(90deg, rgba(136,136,136,0.80), rgba(136,136,136,0.20));
      border-radius: 2px;
      margin-top: 32px;
    }}

    /* ── 우측 텍스트 영역 ── */
    #right-text {{
      flex: 1;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      padding: 60px 60px 180px 40px;
    }}

    .right-label {{
      font-size: 22px;
      font-weight: 500;
      color: rgba(0, 220, 180, 0.85);
      letter-spacing: 0.12em;
      text-transform: uppercase;
      margin-bottom: 24px;
      text-shadow: 0 0 20px rgba(0, 184, 148, 0.60);
    }}

    .right-headline {{
      font-size: 80px;
      font-weight: 900;
      line-height: 1.15;
      letter-spacing: -0.02em;
      color: #FFFFFF;
      text-align: center;
      word-break: keep-all;
      text-shadow:
        0 2px 12px rgba(0, 0, 0, 0.90),
        0 4px 30px rgba(0, 0, 0, 0.80),
        0 0 60px rgba(0, 184, 148, 0.60);
      background: rgba(0, 90, 70, 0.65);
      padding: 24px 40px;
      border-radius: 16px;
      backdrop-filter: blur(12px);
      -webkit-backdrop-filter: blur(12px);
      border: 1px solid rgba(0, 184, 148, 0.50);
      box-shadow:
        0 8px 32px rgba(0,0,0,0.40),
        0 0 40px rgba(0,184,148,0.20);
    }}

    .right-accent {{
      width: 60px;
      height: 3px;
      background: linear-gradient(90deg, rgba(0,184,148,0.30), rgba(0,184,148,0.90));
      border-radius: 2px;
      margin-top: 32px;
    }}

    /* ── 하단 CTA 배너 ── */
    #cta-banner {{
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      z-index: 15;
      height: 130px;
      display: flex;
      align-items: center;
      justify-content: center;
      background: linear-gradient(
        90deg,
        rgba(30, 30, 30, 0.95) 0%,
        rgba(20, 60, 50, 0.95) 50%,
        rgba(0, 100, 80, 0.92) 100%
      );
      border-top: 1px solid rgba(0, 184, 148, 0.40);
    }}

    .cta-text {{
      font-size: 44px;
      font-weight: 900;
      letter-spacing: -0.01em;
      color: #FFFFFF;
      text-align: center;
      word-break: keep-all;
      text-shadow:
        0 2px 8px rgba(0, 0, 0, 0.60),
        0 0 30px rgba(0, 184, 148, 0.40);
    }}

    .cta-text .cta-accent {{
      color: #00F0C0;
      text-shadow:
        0 2px 8px rgba(0, 0, 0, 0.60),
        0 0 20px rgba(0, 240, 192, 0.70);
    }}
  </style>
</head>
<body>

  <!-- 배경 -->
  <div id="bg-layer"></div>

  <!-- 오버레이 -->
  <div id="left-overlay"></div>
  <div id="right-overlay"></div>
  <div id="center-divider"></div>
  <div id="vignette"></div>

  <!-- 콘텐츠 -->
  <div id="content">
    <!-- 좌측: 불안 -->
    <div id="left-text">
      <div class="left-headline">지금의 불안</div>
      <div class="left-accent"></div>
    </div>

    <!-- 우측: 성장 -->
    <div id="right-text">
      <div class="right-headline">내일의 성장</div>
      <div class="right-accent"></div>
    </div>
  </div>

  <!-- 하단 CTA -->
  <div id="cta-banner">
    <div class="cta-text">
      <span class="cta-accent">T.O.P</span> 사업단과 함께
    </div>
  </div>

</body>
</html>
"""


def create_html_template(bg_path: Path) -> Path:
    """배경 이미지 경로를 주입한 HTML 템플릿 파일을 생성합니다."""
    print("[2/3] HTML 오버레이 템플릿 생성 중...")
    bg_url = f"file://{bg_path.resolve()}"
    html_content = HTML_TEMPLATE.format(bg_url=bg_url)
    TEMPLATE_PATH.write_text(html_content, encoding="utf-8")
    print(f"      템플릿 저장: {TEMPLATE_PATH}")
    return TEMPLATE_PATH


# ─────────────────────────────────────────────────────────────────────────────
# Step 3: Playwright로 최종 이미지 캡처
# ─────────────────────────────────────────────────────────────────────────────

def capture_final_image(template_path: Path, output_path: Path) -> None:
    """Playwright 헤드리스 브라우저로 HTML을 렌더링하여 PNG로 저장합니다."""
    print("[3/3] Playwright로 최종 이미지 캡처 중...")

    output_path.parent.mkdir(parents=True, exist_ok=True)

    with sync_playwright() as p:
        browser = p.chromium.launch()
        try:
            page = browser.new_page(viewport={"width": 1080, "height": 1080})
            template_url = f"file://{template_path.resolve()}"
            page.goto(template_url, wait_until="networkidle")
            # 폰트 및 배경 이미지 로딩 대기
            page.wait_for_timeout(2500)
            page.screenshot(path=str(output_path), type="png")
            print(f"      최종 이미지 저장: {output_path}")
        finally:
            browser.close()


# ─────────────────────────────────────────────────────────────────────────────
# 메인 파이프라인
# ─────────────────────────────────────────────────────────────────────────────

def main() -> None:
    print("=" * 60)
    print("Sample C — 좌우 분할 솔루션형 배너 생성")
    print("Gemini AI 배경 + HTML 오버레이 하이브리드 파이프라인")
    print("=" * 60)

    start_time = time.time()

    TEMP_DIR.mkdir(parents=True, exist_ok=True)
    OUTPUT_DIR.mkdir(parents=True, exist_ok=True)

    # Step 1: Gemini 배경 생성
    bg_path = generate_background()

    # Step 2: HTML 템플릿 생성
    template_path = create_html_template(bg_path)

    # Step 3: Playwright 캡처
    capture_final_image(template_path, FINAL_OUTPUT)

    elapsed = time.time() - start_time
    size_kb = FINAL_OUTPUT.stat().st_size / 1024

    print()
    print("=" * 60)
    print(f"완료! 총 소요시간: {elapsed:.1f}초")
    print(f"출력 파일: {FINAL_OUTPUT}")
    print(f"파일 크기: {size_kb:.0f} KB")
    print("=" * 60)


if __name__ == "__main__":
    main()
