#!/usr/bin/env python3
"""Meta 캐러셀 광고 이미지 자동 생성 PoC"""

import argparse
import base64
import json
import os
import sys
from pathlib import Path

# OpenAI API for background generation (Approach C)
from openai import OpenAI

# Playwright for HTML -> PNG capture
from playwright.sync_api import sync_playwright

BASE_DIR = Path(__file__).parent
TEMPLATE_DIR = BASE_DIR / "templates"
DATA_DIR = BASE_DIR / "data"
BG_CACHE_DIR = BASE_DIR / "backgrounds"


def load_env_keys():
    """Load API keys from .env.keys file"""
    env_path = Path("/home/jay/workspace/.env.keys")
    if env_path.exists():
        for line in env_path.read_text().splitlines():
            line = line.strip()
            if line and not line.startswith("#") and "=" in line:
                # Handle 'export VAR=VALUE' format
                if line.startswith("export "):
                    line = line[7:]
                key, _, value = line.partition("=")
                # Remove quotes
                value = value.strip().strip('"').strip("'")
                os.environ.setdefault(key.strip(), value)


def load_slide_data(set_name: str) -> dict:
    """Load slide data from JSON"""
    # Map set names to file names
    set_map = {"상시A": "set_a.json"}
    filename = set_map.get(set_name)
    if not filename:
        raise ValueError(f"Unknown set: {set_name}")

    data_path = DATA_DIR / filename
    with open(data_path, "r", encoding="utf-8") as f:
        return json.load(f)


def generate_ai_background(prompt: str, slide_number: int) -> Path:
    """Generate background image using OpenAI GPT Image 1"""
    cache_path = BG_CACHE_DIR / f"bg_slide_{slide_number}.png"

    # Use cached if exists
    if cache_path.exists():
        print(f"  [캐시] 배경 이미지 사용: {cache_path}")
        return cache_path

    print(f"  [AI] 배경 이미지 생성 중... (gpt-image-1)")
    client = OpenAI()

    result = client.images.generate(
        model="gpt-image-1",
        prompt=prompt,
        n=1,
        size="1024x1024",
        quality="low",
    )

    # gpt-image-1 returns base64 by default
    if not result.data:
        raise RuntimeError(f"AI 배경 생성 실패: 응답 데이터 없음 (slide {slide_number})")
    image_base64 = result.data[0].b64_json
    if not image_base64:
        raise RuntimeError(f"AI 배경 생성 실패: b64_json이 비어있음 (slide {slide_number})")
    image_bytes = base64.b64decode(image_base64)

    BG_CACHE_DIR.mkdir(parents=True, exist_ok=True)
    cache_path.write_bytes(image_bytes)
    print(f"  [AI] 배경 이미지 저장: {cache_path}")

    return cache_path


def capture_slide(page, template_path: str, slide_data: dict, output_path: Path, bg_path: Path | None = None):
    """Render HTML template with data and capture as PNG"""

    # Build the SLIDE_DATA object for JavaScript injection
    js_data = dict(slide_data)

    if bg_path:
        # Convert to file:// URL for the browser
        js_data["backgroundImage"] = f"file://{bg_path.resolve()}"

    # Navigate to template
    template_url = f"file://{Path(template_path).resolve()}"
    page.goto(template_url, wait_until="networkidle")

    # Inject data and call render() directly (both templates define global render())
    page.evaluate(f"""() => {{
        window.SLIDE_DATA = {json.dumps(js_data, ensure_ascii=False)};
        if (typeof render === 'function') {{
            render(window.SLIDE_DATA);
        }}
    }}""")

    # Wait for fonts + rendering to complete
    page.wait_for_timeout(1500)

    # Capture screenshot
    page.screenshot(path=str(output_path), type="png")
    print(f"  [캡처] {output_path}")


def main():
    parser = argparse.ArgumentParser(description="Meta 캐러셀 광고 이미지 생성기")
    parser.add_argument("--set", required=True, help='카피 세트명 (예: "상시A")')
    parser.add_argument("--output", default="./output/", help="출력 디렉토리")
    parser.add_argument(
        "--skip-ai", action="store_true", help="AI 배경 생성 스킵 (기존 캐시 또는 그라디언트 fallback 사용)"
    )
    args = parser.parse_args()

    # Load env
    load_env_keys()

    # Load data
    data = load_slide_data(args.set)
    slides = data["slides"]

    # Output dir
    output_dir = Path(args.output)
    output_dir.mkdir(parents=True, exist_ok=True)

    print(f"=== Meta 캐러셀 이미지 생성 시작 ===")
    print(f"세트: {data['setName']}")
    print(f"슬라이드 수: {len(slides)}")
    print(f"출력 경로: {output_dir.resolve()}")
    print()

    # Template paths
    infographic_template = str(TEMPLATE_DIR / "infographic.html")
    emotional_template = str(TEMPLATE_DIR / "emotional.html")

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

        for slide in slides:
            num = slide["slideNumber"]
            approach = slide["approach"]
            title = slide["title"]

            print(f"[슬라이드 {num}] {title} (접근법 {approach})")

            output_path = output_dir / f"slide_{num}_{title}.png"

            if approach == "B":
                # Approach B: HTML only
                capture_slide(page, infographic_template, slide, output_path)

            elif approach == "C":
                # Approach C: AI background + HTML overlay
                bg_path = None
                bg_prompt = slide.get("bgPrompt", "")

                if not args.skip_ai and bg_prompt:
                    bg_path = generate_ai_background(bg_prompt, num)
                elif (BG_CACHE_DIR / f"bg_slide_{num}.png").exists():
                    bg_path = BG_CACHE_DIR / f"bg_slide_{num}.png"
                    print(f"  [캐시] 기존 배경 사용: {bg_path}")
                else:
                    print(f"  [경고] AI 배경 없음 — 그라디언트 fallback 사용")

                capture_slide(page, emotional_template, slide, output_path, bg_path)

        browser.close()

    print()
    print(f"=== 완료: {len(slides)}장 이미지 생성 ===")

    # List generated files
    for f in sorted(output_dir.glob("slide_*.png")):
        size_kb = f.stat().st_size / 1024
        print(f"  {f.name} ({size_kb:.0f} KB)")


if __name__ == "__main__":
    main()
