#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Featured images (1200x628) dos 5 artigos de blog do Borrello.

REV 2 (2026-09-19): SAFE ZONE de 15% laterais + 10% topo/base
  - Elementos importantes (pílula, headline, footer) 100% dentro
    de x: 180..1020 / y: 63..565
  - Fundo/foto continua sangrando até as bordas
  - Layout centralizado horizontalmente pra sobreviver ao crop
    do container do artigo no tema WP (desktop + mobile)

Fluxo:
1) Gera 5 backgrounds realistas via gpt-image-1 (1536x1024 -> crop 1200x628)
   [se já existem em _bgs/ reaproveita, não regera]
2) Compõe overlay/headline via HTML + Playwright
3) Salva JPG q=85 <300KB
4) Roda QA de acentuação (qa_criativo.py) em cada um

Padrão visual: preto + amarelo neon #F6E600, Bebas Neue headline,
pílula "FENG SHUI" topo, marca discreta rodapé.
"""

from __future__ import annotations

import base64
import io
import os
import subprocess
import sys
from dataclasses import dataclass
from pathlib import Path

from PIL import Image
from openai import OpenAI
from playwright.sync_api import sync_playwright

# -----------------------------------------------------------------------------
# Config
# -----------------------------------------------------------------------------

# Carrega OPENAI_API_KEY de /opt/mia/.env
ENV_PATH = Path("/opt/mia/.env")
if ENV_PATH.exists():
    for line in ENV_PATH.read_text().splitlines():
        line = line.strip()
        if line.startswith("OPENAI_API_KEY="):
            os.environ["OPENAI_API_KEY"] = line.split("=", 1)[1].strip().strip('"').strip("'")
            break

if not os.environ.get("OPENAI_API_KEY"):
    print("[ERRO] OPENAI_API_KEY não encontrada", file=sys.stderr)
    sys.exit(1)

client = OpenAI()

OUT_DIR = Path("/opt/mia/workspace/clientes/borrello/blog/artigos_v1_2026-09-18/featured_images")
OUT_DIR.mkdir(parents=True, exist_ok=True)

BG_DIR = OUT_DIR / "_bgs"
BG_DIR.mkdir(exist_ok=True)

W, H = 1200, 628

# SAFE ZONE (15% laterais + 10% topo/base)
SAFE_LEFT = 180     # 15% de 1200
SAFE_RIGHT = 180
SAFE_TOP = 63       # 10% de 628
SAFE_BOTTOM = 63
# Área útil: 840x502

# -----------------------------------------------------------------------------
# Artigos + prompts
# -----------------------------------------------------------------------------

@dataclass
class Artigo:
    idx: int
    slug: str
    fname: str
    headline: str
    tag: str
    bg_prompt: str
    alt: str


ARTIGOS: list[Artigo] = [
    Artigo(
        idx=1,
        slug="entrada",
        fname="featured_01_entrada.jpg",
        headline="Feng Shui na entrada da casa",
        tag="FENG SHUI",
        bg_prompt=(
            "Realistic editorial photograph of a warm welcoming entrance of a Brazilian home. "
            "Wooden front door slightly open, small entry hall with a healthy green plant beside it, "
            "a red doormat on the floor, natural warm sunlight streaming in from the side, "
            "wooden floor, neutral wall tones, cinematic composition, shallow depth of field, "
            "editorial photography, professional interior photography, no text, no logos, no watermarks."
        ),
        alt="Porta de entrada de casa com feng shui, tapete vermelho e planta ao lado",
    ),
    Artigo(
        idx=2,
        slug="quarto",
        fname="featured_02_quarto.jpg",
        headline="Feng Shui no quarto",
        tag="FENG SHUI",
        bg_prompt=(
            "Realistic editorial photograph of a serene minimal bedroom. "
            "Bed with clean white and beige linen, positioned against a solid wall (headboard visible), "
            "wooden bedside table with a warm lamp on it, small plant on the corner, "
            "soft warm morning light coming through a window, muted earthy tones, "
            "cinematic composition, shallow depth of field, editorial interior photography, "
            "no text, no logos, no watermarks."
        ),
        alt="Quarto com cama posicionada segundo o feng shui, luminária e cores harmoniosas",
    ),
    Artigo(
        idx=3,
        slug="plantas",
        fname="featured_03_plantas.jpg",
        headline="Espada-de-são-jorge afasta visitas?",
        tag="PLANTAS",
        bg_prompt=(
            "Realistic editorial photograph of a Brazilian home living room corner. "
            "A tall healthy sansevieria (espada-de-são-jorge / snake plant) in a terracotta pot in the foreground, "
            "a small white orchid on a wooden side table, natural window light from the left, "
            "cozy neutral interior, wooden floor, warm tones, "
            "cinematic composition, shallow depth of field, editorial interior photography, "
            "no text, no logos, no watermarks."
        ),
        alt="Espada-de-são-jorge e outras plantas de feng shui em ambiente doméstico",
    ),
    Artigo(
        idx=4,
        slug="animais",
        fname="featured_04_animais.jpg",
        headline="Os 5 Animais Celestiais",
        tag="FENG SHUI",
        bg_prompt=(
            "Cinematic mystical composition on a dark elegant black background with subtle gold dust particles. "
            "Five symbolic mythical creature silhouettes arranged in a circle: a green dragon, a white tiger, "
            "a red phoenix bird, a black tortoise with a serpent, and a golden central symbol. "
            "Dramatic chiaroscuro lighting, matte black atmospheric depth, ancient chinese mythology aesthetic, "
            "elegant editorial artwork, cinematic 4k, no text, no logos, no watermarks."
        ),
        alt="Os 5 animais celestiais do feng shui — dragão, tigre, fênix, tartaruga e serpente",
    ),
    Artigo(
        idx=5,
        slug="bagua",
        fname="featured_05_bagua.jpg",
        headline="Baguá: o mapa da sua casa",
        tag="FENG SHUI",
        bg_prompt=(
            "Realistic overhead editorial photograph of a home floor plan sketch on a warm wooden table. "
            "The floor plan is drawn in pencil on paper, a brass compass beside it, a wooden pen, "
            "a small potted plant in the corner of the frame, warm afternoon light from the side, "
            "top-down flat lay composition, cinematic, editorial photography, shallow depth of field, "
            "no text, no logos, no watermarks."
        ),
        alt="Baguá do feng shui — o mapa energético da casa desenhado sobre a planta baixa",
    ),
]

# -----------------------------------------------------------------------------
# 1) Geração de BG realista via gpt-image-1
# -----------------------------------------------------------------------------

def gerar_bg(a: Artigo, forcar: bool = False) -> Path:
    """Gera background 1536x1024 e faz crop para 1200x628."""
    bg_path = BG_DIR / f"bg_{a.idx:02d}_{a.slug}.png"
    if bg_path.exists() and bg_path.stat().st_size > 50_000 and not forcar:
        print(f"[skip bg] {bg_path.name} já existe")
        return bg_path

    print(f"[gpt-image-1] gerando bg do artigo {a.idx} ({a.slug})...")
    result = client.images.generate(
        model="gpt-image-1",
        prompt=a.bg_prompt,
        size="1536x1024",  # 3:2 — recorta bonito pra 1200x628
        quality="high",
        n=1,
    )
    raw = base64.b64decode(result.data[0].b64_json)

    # Crop para 1200x628 mantendo o centro
    src = Image.open(io.BytesIO(raw)).convert("RGB")
    sw, sh = src.size
    # target ratio 1200/628 = 1.9108
    target_ratio = W / H
    src_ratio = sw / sh
    if src_ratio > target_ratio:
        # source mais larga - crop lateral
        new_w = int(sh * target_ratio)
        left = (sw - new_w) // 2
        src = src.crop((left, 0, left + new_w, sh))
    else:
        new_h = int(sw / target_ratio)
        top = (sh - new_h) // 2
        src = src.crop((0, top, sw, top + new_h))
    src = src.resize((W, H), Image.LANCZOS)
    src.save(bg_path, "PNG")
    print(f"[ok bg] {bg_path}  ({bg_path.stat().st_size // 1024} KB)")
    return bg_path


# -----------------------------------------------------------------------------
# 2) HTML overlay com headline e marca — SAFE ZONE APLICADA
# -----------------------------------------------------------------------------

def montar_html(a: Artigo, bg_path: Path) -> str:
    b64 = base64.b64encode(bg_path.read_bytes()).decode("ascii")
    bg_url = f"data:image/png;base64,{b64}"

    # Ajuste dinâmico de tamanho da headline conforme comprimento do texto
    # Área útil horizontal reduzida (840px em vez de 1088px), então caps menores
    n = len(a.headline)
    if n <= 22:
        h_size = 84
    elif n <= 28:
        h_size = 76
    elif n <= 34:
        h_size = 68
    else:
        h_size = 60

    return f"""<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Bebas+Neue&family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<style>
  * {{ margin: 0; padding: 0; box-sizing: border-box; }}
  html, body {{
    width: {W}px; height: {H}px; margin: 0; overflow: hidden;
    font-family: 'Inter', sans-serif; background: #000;
  }}
  .canvas {{ position: relative; width: {W}px; height: {H}px; overflow: hidden; }}

  .bg {{
    position: absolute; inset: 0;
    background: url('{bg_url}') center/cover no-repeat;
  }}

  /* overlay preto degradê pra legibilidade da headline centralizada */
  .overlay {{
    position: absolute; inset: 0;
    background:
      radial-gradient(
        ellipse 65% 75% at 50% 55%,
        rgba(0,0,0,0.72) 0%,
        rgba(0,0,0,0.55) 45%,
        rgba(0,0,0,0.25) 80%,
        rgba(0,0,0,0.10) 100%
      ),
      linear-gradient(
        180deg,
        rgba(0,0,0,0.30) 0%,
        rgba(0,0,0,0.20) 40%,
        rgba(0,0,0,0.55) 100%
      );
  }}

  /* Área SAFE ZONE: 180px laterais, 63px topo/base
     Todo conteúdo textual mora aqui dentro — sobrevive a qualquer crop de tema WP */
  .safe {{
    position: absolute;
    left: {SAFE_LEFT}px;
    right: {SAFE_RIGHT}px;
    top: {SAFE_TOP}px;
    bottom: {SAFE_BOTTOM}px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
    text-align: center;
  }}

  .top-block {{
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 24px;
    padding-top: 8px;
  }}

  .bottom-block {{
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 18px;
    padding-bottom: 8px;
  }}

  .pill {{
    display: inline-flex;
    align-items: center;
    background: #F6E600;
    color: #111;
    padding: 10px 26px;
    border-radius: 100px;
    font-family: 'Inter', sans-serif;
    font-weight: 800;
    font-size: 22px;
    letter-spacing: 4px;
    text-transform: uppercase;
    box-shadow: 0 4px 18px rgba(0,0,0,0.35);
  }}

  .headline {{
    font-family: 'Bebas Neue', 'Anton', 'Oswald', sans-serif;
    font-weight: 400;
    font-size: {h_size}px;
    line-height: 1.02;
    color: #FFF;
    letter-spacing: 0.5px;
    text-shadow: 0 4px 24px rgba(0,0,0,0.85), 0 2px 6px rgba(0,0,0,0.7);
    max-width: 100%;
    padding: 0 6px;
  }}

  .accent {{
    width: 78px; height: 4px;
    background: #F6E600;
    border-radius: 4px;
    box-shadow: 0 0 20px rgba(246,230,0,0.55);
  }}

  .footer {{
    font-family: 'Inter', sans-serif;
    font-weight: 500;
    font-size: 20px;
    color: rgba(255,255,255,0.85);
    letter-spacing: 2px;
    text-transform: lowercase;
    text-shadow: 0 2px 8px rgba(0,0,0,0.7);
  }}
</style>
</head>
<body>
  <div class="canvas">
    <div class="bg"></div>
    <div class="overlay"></div>
    <div class="safe">
      <div class="top-block">
        <div class="pill">{a.tag}</div>
      </div>
      <div class="bottom-block">
        <div class="headline">{a.headline}</div>
        <div class="accent"></div>
        <div class="footer">franciscoborrello.com.br</div>
      </div>
    </div>
  </div>
</body>
</html>
"""


# -----------------------------------------------------------------------------
# 3) Render HTML -> PNG -> JPG q=85
# -----------------------------------------------------------------------------

def render_um(a: Artigo, bg_path: Path) -> Path:
    html = montar_html(a, bg_path)
    tmp_png = OUT_DIR / f"_tmp_{a.slug}.png"
    dest_jpg = OUT_DIR / a.fname

    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page(viewport={"width": W, "height": H}, device_scale_factor=1)
        page.set_content(html, wait_until="networkidle")
        page.wait_for_timeout(700)
        page.screenshot(path=str(tmp_png), clip={"x": 0, "y": 0, "width": W, "height": H})
        browser.close()

    # PNG -> JPG q=85, garantindo <300KB
    img = Image.open(tmp_png).convert("RGB")
    q = 88
    while True:
        img.save(dest_jpg, "JPEG", quality=q, optimize=True, progressive=True)
        size_kb = dest_jpg.stat().st_size // 1024
        if size_kb <= 300 or q <= 65:
            break
        q -= 5

    tmp_png.unlink(missing_ok=True)
    print(f"[ok jpg] {dest_jpg}  ({dest_jpg.stat().st_size // 1024} KB, q={q})")
    return dest_jpg


# -----------------------------------------------------------------------------
# 4) QA acentuação
# -----------------------------------------------------------------------------

def rodar_qa(jpg_path: Path) -> tuple[int, str]:
    """Retorna (exit_code, saida)."""
    r = subprocess.run(
        ["python3", "/opt/mia/scripts/qa_criativo.py", str(jpg_path)],
        capture_output=True, text=True,
    )
    return r.returncode, (r.stdout + r.stderr).strip()


# -----------------------------------------------------------------------------
# Main
# -----------------------------------------------------------------------------

def main():
    resultados = []
    for a in ARTIGOS:
        bg = gerar_bg(a)
        jpg = render_um(a, bg)
        code, out = rodar_qa(jpg)
        resultados.append({
            "artigo": a.idx,
            "slug": a.slug,
            "arquivo": str(jpg),
            "size_kb": jpg.stat().st_size // 1024,
            "qa_exit": code,
            "qa_output": out,
            "alt": a.alt,
        })

    print("\n========== RESUMO ==========")
    for r in resultados:
        status = "OK" if r["qa_exit"] == 0 else "FALHOU"
        print(f"[{status}] artigo {r['artigo']:02d} ({r['slug']}) — {r['arquivo']} — {r['size_kb']}KB — qa_exit={r['qa_exit']}")
        if r["qa_exit"] != 0:
            print("  QA output:")
            for line in r["qa_output"].splitlines():
                print(f"    {line}")

    fails = [r for r in resultados if r["qa_exit"] != 0]
    if fails:
        print(f"\n[AVISO] {len(fails)} arquivo(s) falharam no QA")
        sys.exit(1)
    print("\n[OK] Todos os 5 passaram no QA")


if __name__ == "__main__":
    main()
