#!/usr/bin/env python3
"""
컨셉 #33 메리츠 스타일 — 프로덕션 배너 생성기
1200x628 (landscape) + 1200x1200 (square)
Gemini AI 배경 + HTML 텍스트 오버레이 하이브리드
"""

from __future__ import annotations

import base64
import sys
import time
from pathlib import Path

import requests
from playwright.sync_api import sync_playwright

# ─── 경로 설정 ─────────────────────────────────────────────────────────────────
TOOLS_DIR = Path("/home/jay/workspace/tools/ai-image-gen")
OUTPUT_DIR = Path("/home/jay/workspace/output/meta-ads/production-banners/33-meritz-style")
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)

sys.path.insert(0, str(TOOLS_DIR))
import gcloud_auth  # noqa: E402

# ─── Gemini 설정 ───────────────────────────────────────────────────────────────
GEMINI_API_BASE = "https://generativelanguage.googleapis.com/v1beta"
MODELS = ["gemini-3-pro-image-preview", "gemini-2.0-flash-preview-image-generation", "gemini-3.1-flash-image-preview"]

GEMINI_PROMPT = (
    "Dark technology workspace with server racks and circuit board patterns, "
    "orange-red ambient glow from below left, futuristic data center aesthetic, "
    "cool and warm contrast, glowing circuit traces on dark surfaces, "
    "deep charcoal and near-black tones (#0D0D0D), warm orange-red light source "
    "emanating from lower left corner casting subtle glow on tech surfaces, "
    "no people, no text, no logos, photorealistic, cinematic lighting, "
    "high contrast dramatic atmosphere, ultra-sharp detail"
)

# ─── 배너 설정 ─────────────────────────────────────────────────────────────────
BANNERS = [
    {
        "name": "1200x628",
        "width": 1200,
        "height": 628,
        "bg_path": OUTPUT_DIR / "bg_1200x628.jpg",
        "html_path": OUTPUT_DIR / "c33-1200x628.html",
        "png_path": OUTPUT_DIR / "c33-1200x628.png",
    },
    {
        "name": "1200x1200",
        "width": 1200,
        "height": 1200,
        "bg_path": OUTPUT_DIR / "bg_1200x1200.jpg",
        "html_path": OUTPUT_DIR / "c33-1200x1200.html",
        "png_path": OUTPUT_DIR / "c33-1200x1200.png",
    },
]


# ─── Gemini 배경 생성 ──────────────────────────────────────────────────────────

def generate_background(bg_path: Path, width: int, height: int) -> Path:
    """Gemini API로 배경 이미지를 생성합니다."""
    print(f"  [Gemini] 배경 생성 중 ({width}x{height})...")

    token = gcloud_auth.get_service_account_token()
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {token}",
    }

    size_hint = f"{width}x{height} pixels, " if width != height else ""
    prompt = GEMINI_PROMPT + f", {size_hint}aspect ratio {'landscape wide' if width > height else 'square'}"

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

    for model in MODELS:
        url = f"{GEMINI_API_BASE}/models/{model}:generateContent"
        print(f"    모델 시도: {model}")
        for attempt in range(2):
            try:
                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_data = base64.b64decode(part["inlineData"]["data"])
                                bg_path.write_bytes(img_data)
                                print(f"    배경 저장: {bg_path} ({len(img_data):,} bytes)")
                                return bg_path
                    print(f"    응답 구조 이상: {list(data.keys())}")
                else:
                    print(f"    API 오류 {resp.status_code}: {resp.text[:200]}")
            except Exception as e:
                print(f"    시도 {attempt + 1} 실패: {e}")
            if attempt < 1:
                time.sleep(3)

    raise RuntimeError(f"Gemini 배경 생성 실패 ({bg_path.name})")


# ─── HTML에 배경 경로 주입 ─────────────────────────────────────────────────────

def inject_bg_path(html_path: Path, bg_path: Path) -> str:
    """HTML 파일을 읽어 bg_path를 절대 file:// URI로 교체한 내용을 반환합니다."""
    html = html_path.read_text(encoding="utf-8")
    bg_uri = bg_path.as_uri()
    # src="bg_1200x628.jpg" or src="bg_1200x1200.jpg" 를 절대 URI로 교체
    html = html.replace(f'src="{bg_path.name}"', f'src="{bg_uri}"')
    return html


# ─── Playwright 캡처 ──────────────────────────────────────────────────────────

def capture_html_to_png(html_path: Path, bg_path: Path, png_path: Path, width: int, height: int) -> Path:
    """HTML을 Playwright로 렌더링하여 PNG로 캡처합니다."""
    print(f"  [Playwright] 캡처 중 ({width}x{height})...")

    # 배경 URI를 절대 경로로 교체한 임시 HTML 작성
    html_content = inject_bg_path(html_path, bg_path)
    tmp_html = html_path.parent / f"_tmp_{html_path.name}"
    tmp_html.write_text(html_content, encoding="utf-8")

    try:
        with sync_playwright() as p:
            browser = p.chromium.launch(
                headless=True,
                args=["--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage"],
            )
            context = browser.new_context(
                viewport={"width": width, "height": height},
                device_scale_factor=1,
            )
            page = context.new_page()
            page.goto(f"file://{tmp_html.resolve()}", wait_until="networkidle", timeout=30000)
            page.evaluate("() => document.fonts.ready")
            page.wait_for_timeout(2000)
            page.screenshot(
                path=str(png_path),
                clip={"x": 0, "y": 0, "width": width, "height": height},
                type="png",
            )
            browser.close()
    finally:
        if tmp_html.exists():
            tmp_html.unlink()

    size_kb = png_path.stat().st_size / 1024
    print(f"    PNG 저장: {png_path} ({size_kb:.0f} KB)")
    return png_path


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

def main():
    print("=" * 60)
    print("컨셉 #33 메리츠 스타일 — 프로덕션 배너 생성")
    print(f"출력 경로: {OUTPUT_DIR}")
    print("=" * 60)

    total_start = time.time()
    results = []

    for banner in BANNERS:
        name = banner["name"]
        print(f"\n[{name}] 시작")
        start = time.time()

        try:
            # 1. Gemini 배경 생성
            bg_path = generate_background(banner["bg_path"], banner["width"], banner["height"])

            # 2. Playwright 캡처
            png_path = capture_html_to_png(
                banner["html_path"],
                bg_path,
                banner["png_path"],
                banner["width"],
                banner["height"],
            )

            elapsed = time.time() - start
            print(f"[{name}] 완료! ({elapsed:.1f}초)")
            results.append({"name": name, "status": "OK", "path": str(png_path)})

        except Exception as e:
            elapsed = time.time() - start
            print(f"[{name}] 실패: {e} ({elapsed:.1f}초)")
            results.append({"name": name, "status": "FAIL", "error": str(e)})

    total_elapsed = time.time() - total_start
    print(f"\n{'=' * 60}")
    print(f"전체 완료: {total_elapsed:.1f}초")
    for r in results:
        status = r["status"]
        if status == "OK":
            print(f"  [{status}] {r['name']} → {r['path']}")
        else:
            print(f"  [{status}] {r['name']} → {r.get('error', '알 수 없는 오류')}")
    print("=" * 60)


if __name__ == "__main__":
    main()
