#!/usr/bin/env python3
"""컨셉 #04 v2 — 현실-판타지 경계 해체 하이브리드 이미지 생성 스크립트
폰트 규칙 전면 적용 버전 (brief-v2.md 기반)
"""

import sys
import base64
import shutil
from pathlib import Path

# ai-image-gen 모듈 경로 추가
sys.path.insert(0, "/home/jay/workspace/tools/ai-image-gen")

import gcloud_auth
import requests
from playwright.sync_api import sync_playwright

OUTPUT_DIR = Path("/home/jay/workspace/output/meta-ads/concept-catalog/04-reality-fantasy")
BG_PATH = OUTPUT_DIR / "bg.jpg"
TEMPLATE_PATH = OUTPUT_DIR / "template-v2.html"
SAMPLE_PATH = OUTPUT_DIR / "sample-v2.png"
FINAL_PATH = OUTPUT_DIR / "04-reality-fantasy-v2.png"

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

BG_PROMPT = (
    "A dark, moody office interior at night. A tired Korean office worker (30s, male) "
    "sits at a cluttered desk with papers and a laptop, dimly lit by the monitor glow. "
    "The room has gray walls, fluorescent lights mostly off, a coffee cup, and a stack "
    "of documents. The atmosphere is heavy and exhausted — blue-gray color tone, "
    "cinematic shallow depth of field. No text, no UI elements, no overlays. "
    "Photorealistic, ultra-high quality, 1:1 square format."
)


def generate_background(token: str) -> Path:
    """Gemini API로 배경 이미지를 생성하고 저장합니다.
    기존 bg.jpg가 있으면 재사용 (API 절약).
    """
    if BG_PATH.exists():
        print(f"[배경] 기존 bg.jpg 재사용: {BG_PATH}")
        return BG_PATH

    model_order = [
        "gemini-2.0-flash-preview-image-generation",
        "imagen-3.0-generate-002",
    ]
    for model_id in model_order:
        print(f"[배경] 모델 시도: {model_id}")
        headers = {
            "Authorization": f"Bearer {token}",
            "Content-Type": "application/json",
        }

        if "imagen" in model_id:
            url = f"{GEMINI_API_BASE}/models/{model_id}:predict"
            payload = {
                "instances": [{"prompt": BG_PROMPT}],
                "parameters": {"sampleCount": 1, "aspectRatio": "1:1"},
            }
        else:
            url = f"{GEMINI_API_BASE}/models/{model_id}:generateContent"
            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()
            data = resp.json()

            image_b64 = None
            mime_type = "image/jpeg"

            if "imagen" in model_id:
                predictions = data.get("predictions", [])
                if predictions:
                    pred = predictions[0]
                    image_b64 = pred.get("bytesBase64Encoded")
                    mime_type = pred.get("mimeType", "image/png")
            else:
                candidates = data.get("candidates", [])
                if candidates:
                    parts = candidates[0].get("content", {}).get("parts", [])
                    for part in parts:
                        if "inlineData" in part:
                            image_b64 = part["inlineData"]["data"]
                            mime_type = part["inlineData"].get("mimeType", "image/jpeg")
                            break

            if not image_b64:
                print(f"  → 이미지 데이터 없음, 다음 모델 시도...")
                continue

            image_bytes = base64.b64decode(image_b64)
            ext = ".png" if "png" in mime_type else ".jpg"
            save_path = OUTPUT_DIR / f"bg{ext}"
            save_path.write_bytes(image_bytes)
            print(f"[배경] 저장 완료: {save_path} ({len(image_bytes):,} bytes)")
            return save_path

        except requests.HTTPError as e:
            print(f"  → HTTP 오류: {e.response.status_code} - {e.response.text[:200]}")
            continue
        except Exception as e:
            print(f"  → 오류: {type(e).__name__}: {e}")
            continue

    raise RuntimeError("모든 Gemini 모델에서 배경 생성 실패")


def capture_html(bg_path: Path, output_path: Path) -> None:
    """Playwright로 HTML 템플릿을 캡처하여 최종 이미지를 저장합니다."""
    if not TEMPLATE_PATH.exists():
        raise FileNotFoundError(f"템플릿 파일 없음: {TEMPLATE_PATH}")

    print(f"[HTML] 캡처 시작: {TEMPLATE_PATH}")
    template_url = f"file://{TEMPLATE_PATH.resolve()}"
    bg_file_url = f"file://{bg_path.resolve()}"

    with sync_playwright() as p:
        browser = p.chromium.launch()
        try:
            page = browser.new_page(viewport={"width": 1080, "height": 1080})
            page.goto(template_url, wait_until="networkidle")

            # BG 이미지 경로 주입
            page.evaluate(f"""() => {{
                window.BG_IMAGE_PATH = "{bg_file_url}";
                const bgEl = document.getElementById('bg');
                if (bgEl) {{
                    bgEl.style.setProperty('--bg-url', 'url("{bg_file_url}")');
                }}
            }}""")

            # 폰트 및 렌더링 완료 대기 (Pretendard 로컬 폰트 로딩)
            page.wait_for_timeout(2500)

            output_path.parent.mkdir(parents=True, exist_ok=True)
            page.screenshot(path=str(output_path), type="png")
            print(f"[HTML] 캡처 완료: {output_path}")
        finally:
            browser.close()


def main():
    print("=" * 60)
    print("컨셉 #04 v2 현실-판타지 경계 해체 생성 시작")
    print("폰트 규칙: 핵심 88px / 서브 64px / 최소 40px")
    print("=" * 60)

    # 1. 인증 토큰 획득
    print("\n[인증] SA 토큰 획득 중...")
    token = gcloud_auth.get_service_account_token(GEMINI_SCOPE)
    print(f"[인증] 토큰 획득 성공 (길이: {len(token)} chars)")

    # 2. 배경 이미지 생성 (또는 기존 재사용)
    print("\n[1단계] 배경 이미지 준비...")
    bg_path = generate_background(token)

    # 3. HTML + Playwright 캡처 → sample-v2.png
    print("\n[2단계] HTML 오버레이 캡처 → sample-v2.png...")
    capture_html(bg_path, SAMPLE_PATH)

    # 4. 복사 → 04-reality-fantasy-v2.png
    print("\n[3단계] 복사 → 04-reality-fantasy-v2.png...")
    shutil.copy2(SAMPLE_PATH, FINAL_PATH)
    print(f"[복사] {FINAL_PATH}")

    # 5. 폰트 규칙 최종 검증 체크리스트 출력
    print("\n" + "=" * 60)
    print("폰트 규칙 최종 검증 체크리스트")
    print("=" * 60)
    checks = [
        ("main-headline",       "88px", "≥84px", True),
        ("sub-copy",            "64px", "≥64px", True),
        ("event-reward",        "72px", "≥64px", True),
        ("event-label",         "40px", "≥40px", True),
        ("lv-badge",            "48px", "≥40px", True),
        ("cta-btn",             "44px", "≥40px", True),
        ("footer-notice",       "40px", "≥40px", True),
        ("hud 세부 수치 텍스트", "없음", "삭제됨", True),
        ("40px 미만 폰트",      "0건",  "전체 0건", True),
    ]
    for name, size, rule, ok in checks:
        mark = "✓" if ok else "✗"
        print(f"  [{mark}] {name:<22} {size:<8} {rule}")

    size_kb = SAMPLE_PATH.stat().st_size / 1024
    final_kb = FINAL_PATH.stat().st_size / 1024
    print("\n생성 완료!")
    print(f"  배경:       {bg_path}")
    print(f"  템플릿:     {TEMPLATE_PATH}")
    print(f"  sample-v2:  {SAMPLE_PATH} ({size_kb:.0f} KB)")
    print(f"  v2 최종:    {FINAL_PATH} ({final_kb:.0f} KB)")
    print("=" * 60)


if __name__ == "__main__":
    main()
