#!/usr/bin/env python3
"""컨셉 #19 타겟 페르소나 카드 v2 생성 스크립트
Gemini AI 배경 + HTML 오버레이 하이브리드 방식
"""

from __future__ import annotations

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

import requests
from playwright.sync_api import sync_playwright

sys.path.insert(0, str(Path(__file__).parent))
import gcloud_auth

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

OUTPUT_DIR = Path("/home/jay/workspace/output/meta-ads/concept-catalog/19-persona-card")
BG_PATH = OUTPUT_DIR / "bg_v2.jpg"
HTML_PATH = OUTPUT_DIR / "overlay_v2.html"
SAMPLE_V2_PATH = OUTPUT_DIR / "sample-v2.png"
PERSONA_CARD_V2_PATH = OUTPUT_DIR / "19-persona-card-v2.png"

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

BG_PROMPT = (
    "Three diverse Korean business professionals standing together in a row, "
    "young woman in her 20s on left wearing light blue blouse, "
    "confident man in his 30s in middle wearing navy blazer, "
    "professional woman in her 40s on right wearing beige jacket, "
    "all smiling warmly, bright warm studio background, team portrait, "
    "friendly corporate atmosphere, waist-up shot, 1080x1080, "
    "no text, no watermark, clean professional photo"
)

HTML_TEMPLATE = """<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
  @import url('https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css');

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

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

  .container {
    position: relative;
    width: 1080px;
    height: 1080px;
    overflow: hidden;
  }

  /* 배경 이미지 */
  .bg-image {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
  }

  /* 상단 오버레이 그라디언트 (상위 38%) */
  .top-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 38%;
    background: linear-gradient(
      to bottom,
      rgba(244, 246, 250, 0.97) 0%,
      rgba(244, 246, 250, 0.90) 55%,
      rgba(244, 246, 250, 0.0) 100%
    );
  }

  /* 하단 오버레이 그라디언트 (하위 38%) */
  .bottom-overlay {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 38%;
    background: linear-gradient(
      to top,
      rgba(244, 246, 250, 0.97) 0%,
      rgba(244, 246, 250, 0.90) 55%,
      rgba(244, 246, 250, 0.0) 100%
    );
  }

  /* 상단 텍스트 영역 */
  .top-content {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    padding: 48px 64px 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
  }

  .label-text {
    font-size: 40px;
    font-weight: 600;
    color: #3B82F6;
    letter-spacing: -0.5px;
    line-height: 1.2;
  }

  .headline-text {
    font-size: 84px;
    font-weight: 800;
    color: #0F1F4B;
    letter-spacing: -2px;
    line-height: 1.1;
  }

  /* 하단 텍스트 영역 */
  .bottom-content {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    padding: 0 64px 48px;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }

  .sub-headline {
    font-size: 64px;
    font-weight: 700;
    color: #0F1F4B;
    letter-spacing: -1.5px;
    line-height: 1.15;
  }

  .benefit-text {
    font-size: 48px;
    font-weight: 700;
    color: #0F1F4B;
    letter-spacing: -1px;
    line-height: 1.2;
  }

  .urgent-text {
    font-size: 40px;
    font-weight: 500;
    color: #DC2626;
    letter-spacing: -0.5px;
    line-height: 1.2;
  }

  /* CTA 버튼 */
  .cta-button {
    display: inline-block;
    font-size: 40px;
    font-weight: 800;
    color: #ffffff;
    background: #FF6B35;
    padding: 16px 48px;
    border-radius: 50px;
    letter-spacing: -0.5px;
    line-height: 1.2;
    margin-top: 6px;
  }

  .brand-text {
    font-size: 40px;
    font-weight: 400;
    color: #9CA3AF;
    letter-spacing: -0.3px;
    line-height: 1.2;
    margin-top: 2px;
  }
</style>
</head>
<body>
<div class="container">
  <!-- 배경 이미지 -->
  <img class="bg-image" src="__BG_PATH__" alt="background" />

  <!-- 그라디언트 오버레이 -->
  <div class="top-overlay"></div>
  <div class="bottom-overlay"></div>

  <!-- 상단 텍스트 -->
  <div class="top-content">
    <div class="label-text">T.O.P 사업단 리크루팅</div>
    <div class="headline-text">소득이 제자리걸음?</div>
  </div>

  <!-- 하단 텍스트 -->
  <div class="bottom-content">
    <div class="sub-headline">신입 · 경력직 · 전직</div>
    <div class="benefit-text">정착지원금 최대 1,000만원</div>
    <div class="urgent-text">2026년 7월 조건 변경 예정</div>
    <div class="cta-button">지금 상담 신청하기 →</div>
    <div class="brand-text">T.O.P 사업단 | 인카금융서비스</div>
  </div>
</div>
</body>
</html>
"""


def generate_background(token: str) -> Path:
    """Gemini API로 배경 이미지 생성"""
    print("[1/3] 배경 이미지 생성 중...")

    for model_id in ["gemini-2.5-flash-image", "gemini-3.1-flash-image-preview", "gemini-3-pro-image-preview"]:
        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()
            data = resp.json()

            # 응답에서 이미지 추출
            image_b64 = None
            mime_type = "image/jpeg"

            if "candidates" in data:
                for part in data["candidates"][0]["content"]["parts"]:
                    if "inlineData" in part:
                        image_b64 = part["inlineData"]["data"]
                        mime_type = part["inlineData"].get("mimeType", "image/jpeg")
                        break

            if image_b64:
                ext = ".png" if "png" in mime_type else ".jpg"
                out_path = BG_PATH.with_suffix(ext)
                out_path.write_bytes(base64.b64decode(image_b64))
                print(f"  배경 이미지 저장: {out_path} ({out_path.stat().st_size:,} bytes)")
                return out_path

            print(f"  이미지 데이터 없음. 응답 키: {list(data.keys())}")

        except Exception as e:
            print(f"  오류: {type(e).__name__}: {e}")
            if hasattr(e, 'response') and hasattr(e.response, 'text'):
                print(f"  응답: {e.response.text[:300]}")
            continue

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


def build_html(bg_path: Path) -> Path:
    """HTML 오버레이 파일 생성 (배경 이미지 경로 주입)"""
    print("[2/3] HTML 오버레이 생성 중...")
    html_content = HTML_TEMPLATE.replace("__BG_PATH__", f"file://{bg_path.resolve()}")
    HTML_PATH.write_text(html_content, encoding="utf-8")
    print(f"  HTML 저장: {HTML_PATH}")
    return HTML_PATH


def capture_screenshot(html_path: Path, output_path: Path) -> None:
    """Playwright로 HTML → PNG 캡처"""
    print("[3/3] 스크린샷 캡처 중...")
    with sync_playwright() as p:
        browser = p.chromium.launch()
        try:
            page = browser.new_page(viewport={"width": 1080, "height": 1080})
            page.goto(f"file://{html_path.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")
            print(f"  캡처 완료: {output_path} ({output_path.stat().st_size:,} bytes)")
        finally:
            browser.close()


def main() -> None:
    start_time = time.time()
    print("=" * 60)
    print("컨셉 #19 타겟 페르소나 카드 v2 생성")
    print("방식: Gemini AI 배경 + HTML 오버레이 하이브리드")
    print("=" * 60)

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

    # 2. 배경 이미지 생성
    bg_path = generate_background(token)

    # 3. HTML 빌드
    html_path = build_html(bg_path)

    # 4. 스크린샷 캡처
    capture_screenshot(html_path, SAMPLE_V2_PATH)

    # 5. 복사본 저장
    shutil.copy2(SAMPLE_V2_PATH, PERSONA_CARD_V2_PATH)
    print(f"\n  복사본 저장: {PERSONA_CARD_V2_PATH}")

    elapsed = time.time() - start_time
    print(f"\n{'=' * 60}")
    print(f"완료! 총 소요 시간: {elapsed:.1f}초")
    print(f"  sample-v2.png       : {SAMPLE_V2_PATH}")
    print(f"  19-persona-card-v2.png: {PERSONA_CARD_V2_PATH}")
    print("=" * 60)


if __name__ == "__main__":
    main()
