#!/usr/bin/env python3
"""
#15 CJK 타이포 미니멀 배너 v2 생성기
Gemini AI 배경 + Playwright HTML 오버레이 하이브리드 방식
"""

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

import requests
from playwright.sync_api import sync_playwright

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

BASE_DIR = Path(__file__).parent
OUTPUT_DIR = Path("/home/jay/workspace/output/meta-ads/concept-catalog/15-cjk-typography")
TEMP_DIR = BASE_DIR / "output" / "v4-hybrid"

BG_PATH = TEMP_DIR / "bg_15_cjk_v2.jpg"
HTML_PATH = TEMP_DIR / "overlay_15_cjk_v2.html"
FINAL_OUTPUT = OUTPUT_DIR / "sample-v2.png"
COPY_OUTPUT = OUTPUT_DIR / "15-cjk-typography-v2.png"

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

def get_gemini_api_key() -> str:
    """Gemini API 키를 .env 파일에서 로드합니다."""
    env_path = Path("/home/jay/workspace/.env")
    if env_path.exists():
        content = env_path.read_text(encoding="utf-8")
        for line in content.splitlines():
            if line.startswith("GEMINI_API_KEY="):
                return line.split("=", 1)[1].strip().strip('"')
    raise RuntimeError("GEMINI_API_KEY를 찾을 수 없습니다.")


BG_PROMPT = (
    "Pure black minimal background, very subtle dark charcoal texture, "
    "no patterns, no people, no text, deep shadows, ultra-minimal aesthetic, "
    "slightly uneven dark surface like matte paper, 1080x1080"
)


def generate_background(api_key: str, output_path: Path) -> bool:
    """Gemini AI로 배경 이미지를 생성합니다. SA 토큰 우선, API 키 폴백."""
    print("[배경 생성] Gemini API 호출 중...")

    model = "gemini-3.1-flash-image-preview"

    # SA 토큰으로 시도 (quota 공유 방지)
    try:
        sys.path.insert(0, str(BASE_DIR))
        import gcloud_auth
        token = gcloud_auth.get_service_account_token(
            "https://www.googleapis.com/auth/generative-language"
        )
        url = f"https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent"
        headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
        print("[배경 생성] SA 토큰 사용")
    except Exception:
        url = f"https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent?key={api_key}"
        headers = {"Content-Type": "application/json"}
        print("[배경 생성] API 키 사용 (fallback)")

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

    start = time.time()
    try:
        resp = requests.post(url, headers=headers, json=payload, timeout=120)
        resp.raise_for_status()
    except requests.HTTPError as e:
        print(f"[배경 생성] HTTP 오류: {e.response.status_code} - {e.response.text[:300]}")
        return False

    elapsed = time.time() - start
    data = resp.json()

    candidates = data.get("candidates", [])
    if not candidates:
        print(f"[배경 생성] candidates 없음: {json.dumps(data)[:300]}")
        return False

    parts = candidates[0].get("content", {}).get("parts", [])
    image_part = None
    for part in parts:
        if "inlineData" in part:
            image_part = part
            break

    if image_part is None:
        print(f"[배경 생성] 이미지 데이터 없음")
        return False

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

    print(f"[배경 생성] 완료: {output_path.name} ({len(image_bytes):,} bytes, {elapsed:.1f}초)")
    return True


# ─────────────────────────────────────────────────────────────────────────────
# HTML 오버레이 생성
# ─────────────────────────────────────────────────────────────────────────────

def create_overlay_html(bg_path: Path, html_output: Path) -> None:
    """CJK 타이포 미니멀 배너 HTML을 생성합니다."""

    bg_url = f"file://{bg_path.resolve()}"

    html_content = f"""<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=1080" />
  <title>CJK 타이포 미니멀 배너 v2</title>
  <style>
    @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;700;900&display=swap');

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

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

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

    /* 배경 레이어 */
    #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;
    }}

    /* 어두운 오버레이 (텍스트 가독성 강화) */
    #overlay {{
      position: absolute;
      inset: 0;
      z-index: 1;
      background: rgba(0, 0, 0, 0.45);
    }}

    /* 메인 콘텐츠 레이어 */
    #content {{
      position: absolute;
      inset: 0;
      z-index: 10;
      width: 1080px;
      height: 1080px;
    }}

    /* ─── 상단 라벨 (우측 상단) ─── */
    .top-label {{
      position: absolute;
      top: 60px;
      right: 72px;
      font-size: 44px;
      font-weight: 400;
      color: #AAAAAA;
      letter-spacing: 0.02em;
      font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    }}

    /* ─── 초대형 키워드 ─── */
    .keyword {{
      position: absolute;
      top: 240px;
      left: 72px;
      font-size: 120px;
      font-weight: 900;
      color: #FFFFFF;
      letter-spacing: -4px;
      line-height: 1.0;
      word-break: keep-all;
      font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    }}

    /* ─── 골드 구분선 ─── */
    .divider {{
      position: absolute;
      top: 424px; /* 240 + 120*1.0 + 32margin ≈ 392 → adjusted */
      left: 72px;
      width: 120px;
      height: 3px;
      background: #F5C518;
      border-radius: 2px;
    }}

    /* ─── 헤드라인 ─── */
    .headline {{
      position: absolute;
      top: 499px; /* divider_top(424) + 3 + 40margin + some buffer */
      left: 72px;
      font-size: 84px;
      font-weight: 700;
      color: #F5C518;
      line-height: 1.1;
      word-break: keep-all;
      font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    }}

    /* ─── 서브카피 ─── */
    .subcopy {{
      position: absolute;
      top: 605px; /* headline_top(499) + 84*1.1 + 16margin ≈ 607 */
      left: 72px;
      font-size: 64px;
      font-weight: 400;
      color: #E0E0E0;
      line-height: 1.2;
      word-break: keep-all;
      font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    }}

    /* ─── CTA 버튼 ─── */
    .cta-wrap {{
      position: absolute;
      bottom: 72px;
      left: 72px;
    }}

    .cta {{
      display: inline-block;
      background: #F5C518;
      color: #0F0F0F;
      font-size: 44px;
      font-weight: 700;
      padding: 18px 52px;
      border-radius: 50px;
      letter-spacing: -0.01em;
      line-height: 1.2;
      word-break: keep-all;
      font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    }}
  </style>
</head>
<body>
  <!-- 배경 -->
  <div id="bg-layer"></div>
  <!-- 오버레이 -->
  <div id="overlay"></div>

  <!-- 콘텐츠 -->
  <div id="content">

    <!-- 상단 라벨: 우측 상단 -->
    <div class="top-label">T.O.P 사업단</div>

    <!-- 초대형 키워드 -->
    <div class="keyword">제자리걸음?</div>

    <!-- 골드 구분선 -->
    <div class="divider"></div>

    <!-- 헤드라인 -->
    <div class="headline">신입 최대 1,000만원</div>

    <!-- 서브카피 -->
    <div class="subcopy">경력직 직전연봉 50%</div>

    <!-- CTA -->
    <div class="cta-wrap">
      <div class="cta">지금 상담 신청하기 →</div>
    </div>

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

    html_output.write_text(html_content, encoding="utf-8")
    print(f"[HTML] 오버레이 생성 완료: {html_output.name}")


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

def capture_screenshot(html_path: Path, output_path: Path) -> None:
    """Playwright로 HTML을 1080x1080 PNG로 캡처합니다."""
    print("[캡처] Playwright 스크린샷 시작...")

    # 폰트 로드를 위해 로컬 폰트 사용 (오프라인 환경 대비)
    pretendard_dir = Path("/home/jay/.local/share/fonts/Pretendard")

    with sync_playwright() as p:
        browser = p.chromium.launch(
            args=["--font-render-hinting=none", "--disable-font-subpixel-positioning"]
        )
        try:
            context = browser.new_context(viewport={"width": 1080, "height": 1080})

            # 로컬 폰트 경로 추가 스타일 주입
            page = context.new_page()

            # HTML 파일 로드
            file_url = f"file://{html_path.resolve()}"
            page.goto(file_url, wait_until="networkidle", timeout=30000)

            # 웹폰트 로딩 대기
            page.wait_for_timeout(2500)

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


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

def main() -> None:
    print("=" * 60)
    print("#15 CJK 타이포 미니멀 배너 v2 생성 시작")
    print("=" * 60)

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

    # Step 1: Gemini 배경 이미지 생성
    if BG_PATH.exists():
        print(f"[배경] 기존 파일 재사용: {BG_PATH.name}")
    else:
        try:
            api_key = get_gemini_api_key()
        except RuntimeError as e:
            print(f"[오류] {e}")
            sys.exit(1)

        success = generate_background(api_key, BG_PATH)
        if not success:
            print("[배경 생성 실패] 폴백: 순수 검정 배경으로 진행합니다")
            # 폴백: 검정 배경 (PIL 없이 처리)
            # HTML에서 배경 없이 순수 CSS 배경 사용
            BG_PATH.touch()  # 빈 파일 생성 (HTML에서 fallback CSS 사용)

    # Step 2: HTML 오버레이 생성
    create_overlay_html(BG_PATH, HTML_PATH)

    # Step 3: Playwright 캡처
    capture_screenshot(HTML_PATH, FINAL_OUTPUT)

    # Step 4: 복사본 저장
    shutil.copy2(FINAL_OUTPUT, COPY_OUTPUT)
    print(f"[복사] {COPY_OUTPUT}")

    # 결과 확인
    if FINAL_OUTPUT.exists():
        size_kb = FINAL_OUTPUT.stat().st_size / 1024
        print("\n" + "=" * 60)
        print("생성 완료!")
        print(f"  1. {FINAL_OUTPUT} ({size_kb:.0f} KB)")
        print(f"  2. {COPY_OUTPUT}")
        print("=" * 60)
    else:
        print("[오류] 최종 파일이 생성되지 않았습니다.")
        sys.exit(1)


if __name__ == "__main__":
    main()
