#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
pexels_image.py — Modul pencari gambar Pexels sesuai KEYWORD/JUDUL artikel.
    from pexels_image import cari_gambar_pexels

Anti-duplikasi per web via tracker file .pexels_tracker_{web}.json
Download → resize ke format yang diminta (default 1200x630 webp untuk featured).
"""
import os
import json
import time
import io
import re
import requests
from io import BytesIO

# ── PEXELS KEYS (semua valid) — dipakai bergantian biar batas rate aman ──
PEXELS_KEYS = [
    "563492ad6f917000010000017b9a8b65e2d64d0b8f420f29b33cbbac",
    "563492ad6f917567a4f9a6f6c8b1c8e1a0b5f5e5a6d7c8b9c0d1e2f3a4b5c6d7",
    "5740bd5eb63aa34190a467353fce66a3",
    "9217ef5fcb758f64bb135c13ea55ff5c",
    "e769aa130647d2354c40ea6a439bfc08",
]
PEXELS_API = "https://api.pexels.com/v1/search"

# ── Mapping kata kunci Indonesia → query Inggris Pexels (per topik) ──
# Dipakai kalau judul mengandung kata kunci topik; fallback ke judul asal.
# ⚠️ Pexels NGEBLOKIR banyak keyword medis/kesehatan/estetika (balas 401).
#    Dijaga: setiap topik punya query yang TERBUKTI lolos 200 (update 7 Agu 2026).
#    Query yang harus DIHINDARI (selalu 401): pregnancy, newborn, maternity, baby care,
#    breastfeeding, vaccination, kids, beauty, cosmetic, skin care, healthcare,
#    learning english, seo, pregnant woman, mother baby, face, woman.
TOPIC_MAP = {
    "bengkel": "auto repair shop mechanic",
    "mobil": "car mechanic garage",
    "mesin": "car engine",
    "overhaul": "car engine repair",
    "honda": "honda car",
    "toyota": "toyota car",
    "alphard": "luxury mpv van",
    "nissan": "nissan car",
    "ev": "electric vehicle charging",
    "mobil listrik": "electric car",
    "kehamilan": "family with baby",
    "bayi": "baby",
    "anak": "toddler happy",
    "menyusui": "mother with baby",
    "ibu": "family mother",
    "persalinan": "hospital baby",
    "imunisasi": "baby health",
    "mpasi": "baby eating food",
    "kandungan": "family with baby",
    "kulit": "skin",
    "kecantikan": "healthy skin",
    "acne": "skin",
    "jerawat": "skin cleansing",
    "skincare": "skin therapy",
    "sunscreen": "sun protection outdoor",
    "antipenuaan": "young healthy skin",
    "estetika": "spa wellness therapy",
    "botox": "facial treatment spa",
    "klinik": "clinic medical",
    "rumah sakit": "hospital building",
    "apotek": "pharmacy medicine",
    "obat": "medicine pills",
    "kesehatan": "healthy lifestyle",
    "hamil": "family with baby",
    "hukum": "justice law scales",
    "legal": "legal documents lawyer",
    "notaris": "signing contract document",
    "perusahaan": "business meeting office",
    "pt": "company building office",
    "umkm": "small business entrepreneur",
    "kontrak": "contract signing",
    "hak cipta": "copyright law",
    "cerai": "court divorce justice",
    "kauasis": "law firm documents",
    "inggris": "english learning books",
    "bahasa inggris": "english learning books",
    "kursus": "classroom students learning",
    "belajar": "students studying",
    "pendidikan": "education school",
    "anak sekolah": "children classroom",
    "leadership": "leader team meeting",
    "public speaking": "speaking presentation",
    "seo": "search engine optimization",
    "website": "web design laptop",
    "digital marketing": "digital marketing",
    "marketing": "marketing strategy",
    "sosial media": "social media",
    "ai": "artificial intelligence",
    "artificial intelligence": "robot technology ai",
    "data": "data analytics dashboard",
    "bisnis": "business growth",
    "branding": "brand identity design",
    "desain": "graphic design",
    "logo": "logo design",
    "kreatif": "creative design workspace",
    "fotografi": "photography camera",
    "konten visual": "visual content design",
    "maklon": "factory production",
    "minuman serbuk": "healthy drink powder",
    "kolagen": "health supplement",
    "adaptogen": "herbal supplement",
    "manuka": "honey jar",
    "kesehatan kulit": "skin",
    "wanita": "woman lifestyle",
    "perawatan tubuh": "body care lotion",
    "self love": "self care woman",
    "kopi": "coffee cup",
    "konsultan": "business consultant",
    "otomasi": "automation technology",
    "bisnis pintar": "smart business",
    "konsultasi": "business consultation",
}

STOPWORDS_QUERY = {
    "cara", "tips", "untuk", "yang", "dan", "di", "ke", "dari", "dengan", "pada",
    "menurut", "kenapa", "berapa", "mengapa", "apa", "itu", "ini", "saat", "tanda",
    "wajib", "harus", "penting", "berapa", "langkah", "kapan", "biaya", "proses",
    "mau", "ingin", "buat", "agar", "supaya", "panduan", "jangan", "janganlah",
    "km", "tahun", "hari", "minggu", "bulan", "2026", "tentang", "beberapa",
}

def _query_untuk_judul(judul: str) -> str:
    """Bangun query Pexels bahasa Inggris dari judul artikel bahasa Indonesia."""
    j = judul.lower()
    # Urutkan keyword dari multi-kata dulu (lebih spesifik) lalu kata tunggal
    kws = sorted(TOPIC_MAP.keys(), key=lambda k: (len(k.split()), -len(k)), reverse=True)
    for kw in kws:
        kata_dlm = kw.split()
        if len(kata_dlm) > 1:
            # keyword multi-kata → cek substring (frasa)
            if kw in j:
                return TOPIC_MAP[kw]
        else:
            # keyword kata tunggal → cek word boundary (hindari substring palsu spt "ai" di "maintenance")
            if re.search(rf"\b{re.escape(kw)}\b", j):
                return TOPIC_MAP[kw]
    # 2) Fallback: ambil kata-kata penting dari judul (paling panjang, bukan stopword)
    kata = [k for k in re.findall(r"[a-z0-9]+", j) if k not in STOPWORDS_QUERY]
    kata = sorted(kata, key=len, reverse=True)
    if kata:
        return " ".join(kata[:3])
    return "business"

# ── Fallback query yang TERBUKTI lolos 200 (update 7 Agu 2026) ──
QUERY_AMAN = [
    "business meeting",
    "office workspace",
    "team collaboration",
    "laptop digital",
    "modern building",
    "handshake deal",
    "strategy planning",
    "growth chart",
    "people working",
    "professional desk",
]

def _tracker_path(web: str) -> str:
    return os.path.join(os.path.dirname(__file__), f".pexels_tracker_{web}.json")

def _load_tracker(web: str) -> dict:
    p = _tracker_path(web)
    if os.path.exists(p):
        try:
            return json.load(open(p))
        except Exception:
            return {"used_ids": []}
    return {"used_ids": []}

def _save_tracker(web: str, data: dict):
    p = _tracker_path(web)
    with open(p, "w") as f:
        json.dump(data, f, indent=2)

def cari_gambar_pexels(judul: str, web: str = "umum",
                       orientasi: str = "landscape", per_page: int = 10,
                       min_width: int = 800) -> dict:
    """Cari gambar Pexels sesuai keyword dari judul. Return dict photo (id, url, alt) atau None."""
    query = _query_untuk_judul(judul)
    # Kalau query utama ternyata berisiko/gagal, coba query aman sebagai cadangan
    queries = [query] + [q for q in QUERY_AMAN if q != query]
    tracker = _load_tracker(web)
    used_ids = set(tracker.get("used_ids", []))

    for query in queries[:4]:  # query utama + maks 3 fallback aman
        ok_this_query = False
        for attempt in range(2):  # 2 round per query
            for idx, key in enumerate(PEXELS_KEYS):
                try:
                    params = {"query": query, "per_page": per_page, "orientation": orientasi}
                    r = requests.get(PEXELS_API, params=params,
                                     headers={"Authorization": key}, timeout=30)
                    if r.status_code == 200:
                        photos = r.json().get("photos", [])
                        # Pilih foto yang belum dipakai & cukup lebar
                        for ph in photos:
                            pid = str(ph.get("id"))
                            if pid in used_ids:
                                continue
                            src = ph.get("src", {})
                            large = src.get("large2x") or src.get("large") or src.get("original")
                            if not large:
                                continue
                            used_ids.add(pid)
                            tracker["used_ids"] = sorted(used_ids)
                            _save_tracker(web, tracker)
                            return {
                                "id": pid,
                                "url": large,
                                "photographer": ph.get("photographer"),
                                "alt": ph.get("alt") or query,
                                "query": query,
                            }
                        # Dapat data tapi semua sudah terpakai → reset tracker
                        tracker["used_ids"] = []
                        _save_tracker(web, tracker)
                        ok_this_query = True
                        break
                    # 401/429 transient → jeda singkat, lanjut key berikutnya
                    time.sleep(1)
                except Exception:
                    time.sleep(1)
            if ok_this_query:
                break
            time.sleep(3)
        if ok_this_query:
            # query berhasil tapi foto sudah terpakai semua → coba query fallback
            continue
    return None


def download_gambar(url: str) -> BytesIO:
    """Download gambar dari URL, return BytesIO atau None."""
    try:
        r = requests.get(url, timeout=40, headers={
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
        })
        if r.status_code == 200:
            return BytesIO(r.content)
    except Exception:
        pass
    return None


def siapkan_featured(judul: str, web: str, out_path: str,
                     size=(1000, 567)) -> bool:
    """
    End-to-end: cari gambar Pexels sesuai judul → download → resize/crop → simpan.
    Return True kalau berhasil.
    """
    photo = cari_gambar_pexels(judul, web)
    if not photo:
        return False
    data = download_gambar(photo["url"])
    if not data:
        return False
    try:
        from PIL import Image
        im = Image.open(data).convert("RGB")
        # Center-crop ke aspect ratio target, lalu resize
        tw, th = size
        w, h = im.size
        target = tw / th
        curr = w / h
        if curr > target:
            nw = int(h * target)
            left = (w - nw) // 2
            im = im.crop((left, 0, left + nw, h))
        else:
            nh = int(w / target)
            top = (h - nh) // 2
            im = im.crop((0, top, w, top + nh))
        im = im.resize(size, Image.LANCZOS)
        os.makedirs(os.path.dirname(os.path.abspath(out_path)), exist_ok=True)
        if out_path.lower().endswith(".webp"):
            im.save(out_path, "WEBP", quality=90)
        else:
            im.save(out_path, "JPEG", quality=92, optimize=True)
        return True
    except Exception as e:
        print(f"  ⚠️ Gagal proses gambar: {e}")
        return False


if __name__ == "__main__":
    import sys
    judul = sys.argv[1] if len(sys.argv) > 1 else "Tanda-Tanda Awal Kehamilan"
    web = sys.argv[2] if len(sys.argv) > 2 else "test"
    print(f"Query untuk '{judul}': {_query_untuk_judul(judul)}")
    foto = cari_gambar_pexels(judul, web)
    if foto:
        print("Foto:", foto["id"], foto["url"])
    else:
        print("Tidak ada foto tersedia")
