#!/usr/bin/env python3
"""
컨셉 #26 Hyundai-Style 프로덕션 배너 생성
- c26-1200x628.png  (landscape, Meta Ads / Google Ads)
- c26-1200x1200.png (square, Meta Ads / Google Ads)

타겟: 보험 FA 리쿠르팅 (T.O.P 사업단)
디자인: 다크 메탈릭, 현대차 프리미엄 미니멀리즘
"""

from __future__ import annotations

import base64
import sys
import time
from pathlib import Path

import requests
from playwright.sync_api import sync_playwright
from gen_config import CTA_MIN_PX, HEAD_SUB_RATIO, WORKSPACE_ROOT

# ── 디자인 토큰 ──
_SIZE_28PX = 28
_CTA_PX = CTA_MIN_PX
_SIZE_44PX = 44
_SIZE_54PX = 54
_SIZE_60PX = 60
_LH_1_2 = 1.2
_LH_1_25 = 1.25
_LH_RATIO = HEAD_SUB_RATIO
_LH_1_35 = 1.35


# ── 경로 설정 ──────────────────────────────────────────────────────────────────
BASE_DIR = Path(__file__).parent
OUTPUT_DIR = WORKSPACE_ROOT / "output/meta-ads/production-banners/26-hyundai-style"
TMP_DIR = BASE_DIR / "output" / "v4-hybrid"
BG_PATH_LANDSCAPE = TMP_DIR / "bg_c26_landscape.jpg"
BG_PATH_SQUARE    = TMP_DIR / "bg_c26_square.jpg"

GEMINI_API_BASE = "https://generativelanguage.googleapis.com/v1beta"
MODEL_PRIMARY  = "gemini-3-pro-image-preview"
MODEL_FALLBACK = "gemini-3.1-flash-image-preview"

# ── 배경 프롬프트 ──────────────────────────────────────────────────────────────
BG_PROMPT_LANDSCAPE = (
    "Dark metallic industrial interior, brushed steel surfaces, dramatic angular "
    "lighting from upper left, cool blue-gray tones with faint silver streaks, "
    "deep charcoal atmosphere, cinematic wide shot, no people, no text, no logos, "
    "photorealistic, 16:9 landscape format. "
    "Left third slightly darker and more shadowed for text overlay area. "
    "Right two-thirds shows more metallic texture and light dynamics."
)

BG_PROMPT_SQUARE = (
    "Dark metallic industrial interior, brushed steel surfaces, dramatic angular "
    "lighting streaks from upper left, cool blue-gray tones, subtle silver light "
    "reflections, deep charcoal black center with gradual metallic glow toward edges, "
    "no people, no text, no logos, photorealistic, cinematic, square 1:1 format. "
    "Ultra-premium automotive showroom aesthetic."
)


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

def get_auth_token() -> str:
    sys.path.insert(0, str(BASE_DIR))
    import gcloud_auth
    return gcloud_auth.get_access_token()


def _call_gemini(token: str, api_key: str | None, model: str, payload: dict) -> requests.Response:
    url = f"{GEMINI_API_BASE}/models/{model}:generateContent"
    headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
    resp = requests.post(url, headers=headers, json=payload, timeout=300)
    if resp.status_code == 200:
        return resp
    if api_key:
        url_k = f"{GEMINI_API_BASE}/models/{model}:generateContent?key={api_key}"
        return requests.post(url_k, headers={"Content-Type": "application/json"}, json=payload, timeout=300)
    return resp


def generate_background(prompt: str, output_path: Path, force: bool = False) -> bool:
    if output_path.exists() and output_path.stat().st_size > 50_000 and not force:
        print(f"  [배경] 기존 캐시 재사용: {output_path.name}")
        return True

    print(f"  [배경] Gemini API 호출 중... ({output_path.name})")
    token = get_auth_token()

    sys.path.insert(0, str(BASE_DIR))
    import gcloud_auth
    api_key = gcloud_auth.get_api_key("GEMINI_API_KEY")

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

    for model in [MODEL_PRIMARY, MODEL_FALLBACK]:
        try:
            resp = _call_gemini(token, api_key, model, payload)
            if resp.status_code != 200:
                print(f"  [배경] {model} HTTP {resp.status_code}, 다음 모델 시도...")
                continue
            data = resp.json()
            candidates = data.get("candidates", [])
            if not candidates:
                print(f"  [배경] {model} candidates 없음, 다음 시도...")
                continue
            parts = candidates[0].get("content", {}).get("parts", [])
            image_part = next((p for p in parts if "inlineData" in p), None)
            if image_part is None:
                print(f"  [배경] {model} 이미지 데이터 없음, 다음 시도...")
                continue
            image_bytes = base64.b64decode(image_part["inlineData"]["data"])
            output_path.parent.mkdir(parents=True, exist_ok=True)
            output_path.write_bytes(image_bytes)
            print(f"  [배경] 완료: {output_path.name} ({len(image_bytes)//1024} KB)")
            return True
        except Exception as e:
            print(f"  [배경] {model} 오류: {e}")

    print("  [배경] 모든 모델 실패 — CSS 단색 fallback 사용")
    return False


# ── HTML 템플릿: 1200×628 가로형 ───────────────────────────────────────────────

def build_html_landscape(bg_path: Path | None) -> str:
    if bg_path and bg_path.exists():
        bg_css = f"background-image: url('file://{bg_path.resolve()}'); background-size: cover; background-position: center right;"
    else:
        bg_css = "background: linear-gradient(135deg, #0D0F12 0%, #1A1E24 40%, #232B33 100%);"

    return f"""<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<style>
  @font-face {{
    font-family: 'Pretendard';
    src: local('Pretendard');
  }}
  * {{ margin: 0; padding: 0; box-sizing: border-box; }}
  body {{
    width: 1200px;
    height: 628px;
    overflow: hidden;
    font-family: 'Pretendard', 'Noto Sans KR', -apple-system, sans-serif;
  }}
  .container {{
    width: 1200px;
    height: 628px;
    position: relative;
    {bg_css}
  }}
  /* 왼쪽에서 오른쪽으로 그라디언트 오버레이 — 텍스트 영역 가독성 확보 */
  .overlay {{
    position: absolute;
    inset: 0;
    background: linear-gradient(
      to right,
      rgba(10, 12, 16, 0.92) 0%,
      rgba(10, 12, 16, 0.85) 30%,
      rgba(10, 12, 16, 0.60) 55%,
      rgba(10, 12, 16, 0.10) 100%
    );
  }}
  /* 텍스트 영역: 왼쪽 58% */
  .text-area {{
    position: absolute;
    left: 0;
    top: 0;
    width: 696px;
    height: 628px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 0 72px;
    gap: 0;
  }}
  .brand-badge {{
    font-size: {_CTA_PX}px;
    font-weight: 700;
    color: #4A90D9;
    letter-spacing: 1px;
    word-break: keep-all;
    margin-bottom: 24px;
    line-height: {_LH_1_2};
  }}
  .headline {{
    font-size: {_SIZE_54PX}px;
    font-weight: 800;
    color: #FFFFFF;
    line-height: {_LH_1_25};
    letter-spacing: -1.5px;
    word-break: keep-all;
    margin-bottom: 20px;
  }}
  .headline .accent {{
    color: #4A90D9;
  }}
  .sub-copy {{
    font-size: {_SIZE_44PX}px;
    font-weight: 500;
    color: #B0BAC6;
    line-height: {_LH_RATIO};
    letter-spacing: -0.5px;
    word-break: keep-all;
    margin-bottom: 40px;
  }}
  .cta-btn {{
    display: inline-flex;
    align-items: center;
    background: #4A90D9;
    color: #FFFFFF;
    font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    font-size: {_CTA_PX}px;
    font-weight: 700;
    padding: 18px 48px;
    border-radius: 50px;
    letter-spacing: -0.3px;
    word-break: keep-all;
    white-space: nowrap;
    align-self: flex-start;
  }}
  /* 오른쪽 메탈릭 강조선 */
  .accent-line {{
    position: absolute;
    right: 504px;
    top: 60px;
    bottom: 60px;
    width: 2px;
    background: linear-gradient(to bottom, transparent 0%, #4A90D9 30%, #C0C0C0 60%, transparent 100%);
    opacity: 0.5;
  }}
  /* 하단 브랜드 서브라인 */
  .brand-sub {{
    position: absolute;
    bottom: 28px;
    left: 72px;
    font-size: {_SIZE_28PX}px;
    font-weight: 400;
    color: rgba(176, 186, 198, 0.6);
    letter-spacing: 0.5px;
    word-break: keep-all;
  }}
</style>
</head>
<body>
<div class="container">
  <div class="overlay"></div>
  <div class="accent-line"></div>
  <div class="text-area">
    <div class="brand-badge">T.O.P 사업단</div>
    <div class="headline">열심히는 하는데,<br><span class="accent">월급</span>은 제자리걸음?</div>
    <div class="sub-copy">이제 변속할 시간입니다</div>
    <div class="cta-btn">무료 상담 신청 →</div>
  </div>
  <div class="brand-sub">인카금융서비스 코스닥 상장</div>
</div>
</body>
</html>"""


# ── HTML 템플릿: 1200×1200 정사각형 ──────────────────────────────────────────

def build_html_square(bg_path: Path | None) -> str:
    if bg_path and bg_path.exists():
        bg_css = f"background-image: url('file://{bg_path.resolve()}'); background-size: cover; background-position: center;"
    else:
        bg_css = "background: radial-gradient(ellipse at center, #1A1E24 0%, #0D0F12 60%, #080A0D 100%);"

    return f"""<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<style>
  @font-face {{
    font-family: 'Pretendard';
    src: local('Pretendard');
  }}
  * {{ margin: 0; padding: 0; box-sizing: border-box; }}
  body {{
    width: 1200px;
    height: 1200px;
    overflow: hidden;
    font-family: 'Pretendard', 'Noto Sans KR', -apple-system, sans-serif;
  }}
  .container {{
    width: 1200px;
    height: 1200px;
    position: relative;
    {bg_css}
  }}
  /* 다크 오버레이 — 0.58 opacity */
  .dark-overlay {{
    position: absolute;
    inset: 0;
    background: rgba(8, 10, 13, 0.58);
  }}
  /* 중앙 반투명 패널 */
  .central-panel {{
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 960px;
    background: rgba(15, 18, 24, 0.82);
    border: 1px solid rgba(74, 144, 217, 0.25);
    border-radius: 16px;
    padding: 72px 80px 80px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0;
    backdrop-filter: blur(2px);
  }}
  /* 상단 브랜드 배지 */
  .brand-badge {{
    font-size: {_CTA_PX}px;
    font-weight: 700;
    color: #4A90D9;
    letter-spacing: 2px;
    word-break: keep-all;
    margin-bottom: 8px;
    text-align: center;
    line-height: {_LH_1_2};
  }}
  /* 배지 하단 구분선 */
  .badge-divider {{
    width: 48px;
    height: 2px;
    background: linear-gradient(to right, transparent, #4A90D9, transparent);
    margin-bottom: 40px;
  }}
  .headline {{
    font-size: {_SIZE_60PX}px;
    font-weight: 800;
    color: #FFFFFF;
    line-height: {_LH_1_25};
    letter-spacing: -2px;
    word-break: keep-all;
    text-align: center;
    margin-bottom: 28px;
  }}
  .headline .accent {{
    color: #4A90D9;
  }}
  /* 헤드라인 하단 구분선 */
  .headline-divider {{
    width: 80px;
    height: 2px;
    background: #C0C0C0;
    opacity: 0.4;
    margin-bottom: 28px;
  }}
  .sub-copy {{
    font-size: {_SIZE_44PX}px;
    font-weight: 500;
    color: #B0BAC6;
    line-height: {_LH_1_35};
    letter-spacing: -0.5px;
    word-break: keep-all;
    text-align: center;
    margin-bottom: 52px;
  }}
  .cta-btn {{
    display: inline-flex;
    align-items: center;
    background: #4A90D9;
    color: #FFFFFF;
    font-family: 'Pretendard', 'Noto Sans KR', sans-serif;
    font-size: {_CTA_PX}px;
    font-weight: 700;
    padding: 22px 64px;
    border-radius: 50px;
    letter-spacing: -0.3px;
    word-break: keep-all;
    white-space: nowrap;
  }}
  /* 하단 브랜드 서브라인 */
  .brand-sub {{
    position: absolute;
    bottom: 40px;
    left: 50%;
    transform: translateX(-50%);
    font-size: {_SIZE_28PX}px;
    font-weight: 400;
    color: rgba(176, 186, 198, 0.5);
    letter-spacing: 0.5px;
    word-break: keep-all;
    white-space: nowrap;
  }}
  /* 모서리 메탈릭 액센트 라인 */
  .corner-tl {{
    position: absolute;
    top: 40px;
    left: 40px;
    width: 60px;
    height: 2px;
    background: linear-gradient(to right, #4A90D9, transparent);
  }}
  .corner-tl::after {{
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 2px;
    height: 60px;
    background: linear-gradient(to bottom, #4A90D9, transparent);
  }}
  .corner-br {{
    position: absolute;
    bottom: 40px;
    right: 40px;
    width: 60px;
    height: 2px;
    background: linear-gradient(to left, #4A90D9, transparent);
  }}
  .corner-br::after {{
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    width: 2px;
    height: 60px;
    background: linear-gradient(to top, #4A90D9, transparent);
  }}
</style>
</head>
<body>
<div class="container">
  <div class="dark-overlay"></div>
  <div class="corner-tl"></div>
  <div class="corner-br"></div>
  <div class="central-panel">
    <div class="brand-badge">T.O.P 사업단</div>
    <div class="badge-divider"></div>
    <div class="headline">열심히는 하는데,<br><span class="accent">월급</span>은 제자리걸음?</div>
    <div class="headline-divider"></div>
    <div class="sub-copy">이제 변속할 시간입니다</div>
    <div class="cta-btn">무료 상담 신청 →</div>
  </div>
  <div class="brand-sub">인카금융서비스 코스닥 상장</div>
</div>
</body>
</html>"""


# ── HTML → PNG 캡처 ────────────────────────────────────────────────────────────

def capture_html_to_png(html_content: str, output_path: Path, width: int, height: int) -> bool:
    html_temp = output_path.parent / f"_temp_{output_path.stem}.html"
    html_temp.write_text(html_content, encoding="utf-8")
    try:
        with sync_playwright() as p:
            browser = p.chromium.launch()
            try:
                page = browser.new_page(viewport={"width": width, "height": height})
                page.goto(f"file://{html_temp.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")
                size_kb = output_path.stat().st_size / 1024
                print(f"  [캡처] 완료: {output_path.name} ({size_kb:.0f} KB)")
                return True
            finally:
                browser.close()
    except Exception as e:
        print(f"  [캡처] 오류: {e}")
        return False
    finally:
        if html_temp.exists():
            html_temp.unlink()


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

def main():
    OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
    TMP_DIR.mkdir(parents=True, exist_ok=True)

    results = {}

    # ── 1. 1200×628 가로형 ──────────────────────────────────────────────────────
    print("\n" + "="*60)
    print("[1/2] c26-1200x628 (Landscape) 생성 시작")
    print("="*60)
    t0 = time.time()

    bg_ok_ls = generate_background(BG_PROMPT_LANDSCAPE, BG_PATH_LANDSCAPE)
    html_ls = build_html_landscape(BG_PATH_LANDSCAPE if bg_ok_ls else None)

    # HTML 파일 저장
    html_path_ls = OUTPUT_DIR / "c26-1200x628.html"
    html_path_ls.write_text(html_ls, encoding="utf-8")
    print(f"  [HTML] 저장: {html_path_ls}")

    png_path_ls = OUTPUT_DIR / "c26-1200x628.png"
    ok_ls = capture_html_to_png(html_ls, png_path_ls, 1200, 628)
    results["landscape"] = {"ok": ok_ls, "path": png_path_ls, "elapsed": time.time() - t0}

    # ── 2. 1200×1200 정사각형 ───────────────────────────────────────────────────
    print("\n" + "="*60)
    print("[2/2] c26-1200x1200 (Square) 생성 시작")
    print("="*60)
    t0 = time.time()

    bg_ok_sq = generate_background(BG_PROMPT_SQUARE, BG_PATH_SQUARE)
    html_sq = build_html_square(BG_PATH_SQUARE if bg_ok_sq else None)

    # HTML 파일 저장
    html_path_sq = OUTPUT_DIR / "c26-1200x1200.html"
    html_path_sq.write_text(html_sq, encoding="utf-8")
    print(f"  [HTML] 저장: {html_path_sq}")

    png_path_sq = OUTPUT_DIR / "c26-1200x1200.png"
    ok_sq = capture_html_to_png(html_sq, png_path_sq, 1200, 1200)
    results["square"] = {"ok": ok_sq, "path": png_path_sq, "elapsed": time.time() - t0}

    # ── 결과 출력 ────────────────────────────────────────────────────────────────
    print("\n" + "="*60)
    print("생성 결과")
    print("="*60)
    all_ok = True
    for key, r in results.items():
        status = "성공" if r["ok"] else "실패"
        print(f"  {key}: {status} ({r['elapsed']:.1f}초) → {r['path']}")
        if not r["ok"]:
            all_ok = False

    print(f"\n최종: {'전체 성공' if all_ok else '일부 실패'}")
    return 0 if all_ok else 1


if __name__ == "__main__":
    sys.exit(main())
