#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""RSIA: ganti featured image post 4348 (7-tips-melatih-bayi-tengkurap) dengan
Pexels innocent-newborn-face (15511324). Jalur wp-admin Playwright (Classic Editor).
Verifikasi: tidak ada 'not analyzed by Yoast', indikator hijau, lalu Save/Update."""
import sys, os, time, json
from playwright.sync_api import sync_playwright

BASE = "https://rsia.kendangsari.com"
USER = "bambangbot"
PW   = "C00l_man&314554"
IMG  = "/tmp/pexels_15511324.jpg"
POST_ID = 4348
FILENAME = "innocent-newborn-face-15511324.jpg"
STATE = "/tmp/rsiak_state.json"
LOG = "/tmp/rsiak_setfeat_v2.log"

def log(*a):
    line = " ".join(str(x) for x in a)
    print(line, flush=True)
    with open(LOG, "a") as f:
        f.write(line + "\n")

def goto_light(pg, url, w=90):
    try:
        pg.goto(url, timeout=w*1000, wait_until="commit")
        return True
    except Exception as e:
        log("  goto warn:", str(e)[:50]); return False

def ensure_login(ctx, pg):
    goto_light(pg, f"{BASE}/wp-admin/", 90)
    for _ in range(25):
        if "wp-login" not in pg.url and "wp-admin" in pg.url:
            log("  LOGIN_OK (sudah login)"); return True
        if pg.locator("#user_login").count() > 0:
            break
        pg.wait_for_timeout(2000)
    goto_light(pg, f"{BASE}/wp-login.php", 90)
    for _ in range(25):
        if pg.locator("#user_login").count() > 0:
            break
        pg.wait_for_timeout(2000)
    if pg.locator("#user_login").count() == 0:
        log("  LOGIN_NOT_READY:", pg.url); return False
    pg.fill("#user_login", USER)
    pg.fill("#user_pass", PW)
    pg.click("#wp-submit", no_wait_after=True)
    for _ in range(60):
        pg.wait_for_timeout(3000)
        if "wp-login" not in pg.url and "wp-admin" in pg.url:
            ctx.storage_state(path=STATE)
            log("  LOGIN_OK (fresh login)"); return True
        if pg.locator("#login_error").count() > 0:
            log("  LOGIN_ERROR:", pg.locator("#login_error").inner_text(timeout=2000)[:150]); return False
    log("  LOGIN_TIMEOUT:", pg.url); return False

def upload_and_get_id(pg):
    """Upload gambar via Media -> Add New, kembalikan media id."""
    log("=== Upload media ===")
    goto_light(pg, f"{BASE}/wp-admin/media-new.php", 120)
    inp = None
    for _ in range(40):
        pg.wait_for_timeout(3000)
        if pg.locator("input[type='file']").count() > 0:
            inp = pg.locator("input[type='file']").first
            break
        # maybe tab needed
        try:
            if pg.locator("a:has-text('Upload Files')").count() > 0:
                pg.locator("a:has-text('Upload Files')").first.click(no_wait_after=True)
        except Exception:
            pass
    if inp is None:
        # fallback: drag-drop area might exist; try a selector
        for _ in range(20):
            pg.wait_for_timeout(3000)
            if pg.locator("input[type='file']").count() > 0:
                inp = pg.locator("input[type='file']").first; break
    if inp is None:
        log("  FILE_INPUT_NOT_FOUND"); return None
    inp.set_input_files(IMG)
    log("  file set, menunggu upload selesai...")
    # tunggu thumbnail + data-id
    mid = None
    for _ in range(60):
        pg.wait_for_timeout(3000)
        att = pg.locator("[data-id]")
        if att.count() > 0:
            try:
                mid = att.first.get_attribute("data-id")
                if mid:
                    log("  media id =", mid); break
            except Exception:
                pass
        # cek di halaman library kalau redirect ke upload.php
        if "upload.php" in pg.url and pg.locator(".attachments li.attachment").count() > 0:
            # ambil id dari attachment terakhir (data-id di url)
            try:
                href = pg.locator(".attachments li.attachment").first.get_attribute("data-id")
                mid = href
                log("  media id (library) =", mid); break
            except Exception:
                pass
    return mid

def set_featured(pg, media_id):
    log("=== Set featured image post", POST_ID, "===")
    goto_light(pg, f"{BASE}/wp-admin/post.php?post={POST_ID}&action=edit", 120)
    # tunggu Classic Editor sidebar (postimagediv) atau #publish
    for _ in range(40):
        pg.wait_for_timeout(3000)
        if pg.locator("#postimagediv").count() > 0 or pg.locator("#publish").count() > 0:
            break
    # jika recent already set, remove dulu? Kita pilih baru via frame
    open_frame = False
    try:
        # buka popup featured image: klik tautan "Set featured image" / "Remove"
        setlink = pg.locator("#postimagediv").first.locator("a:has-text('Set featured image'), a:has-text('Remove featured image')").first
        if setlink.count() > 0:
            setlink.click(no_wait_after=True); open_frame = True
        else:
            # fallback: klik .inside a
            setlink = pg.locator("#postimagediv .inside a").first
            if setlink.count() > 0:
                setlink.click(no_wait_after=True); open_frame = True
    except Exception as e:
        log("  open frame err:", str(e)[:60])
    if not open_frame:
        log("  ! gagal membuka media frame"); return False
    pg.wait_for_timeout(4000)
    # pilih Media Library tab
    try:
        if pg.locator("#menu-item-library").count() > 0:
            pg.locator("#menu-item-library").click(no_wait_after=True)
        elif pg.locator("a:has-text('Media Library')").first.count() > 0:
            pg.locator("a:has-text('Media Library')").first.click(no_wait_after=True)
    except Exception:
        pass
    pg.wait_for_timeout(4000)
    # cari attachment kita (filename) lalu pilih
    picked = False
    for _ in range(30):
        pg.wait_for_timeout(3000)
        items = pg.locator(".attachments li.attachment, .media-frame-content li.attachment")
        if items.count() > 0:
            target = None
            for i in range(min(items.count(), 60)):
                try:
                    if FILENAME in (items.nth(i).get_attribute("aria-label") or ""):
                        target = items.nth(i); break
                except Exception:
                    pass
            if target is None:
                target = items.first
            try:
                target.click(no_wait_after=True)
            except Exception:
                pass
            pg.wait_for_timeout(2000); picked = True; break
    log("  picked attachment:", picked)
    # klik tombol "Set featured image"
    used = False
    for sel in ["button:has-text('Set featured image')", ".button:has-text('Set featured image')",
                "#__wp-uploader-id-0-submit", "input#set-post-thumbnail"]:
        b = pg.locator(sel)
        if b.count() > 0:
            try:
                b.first.click(no_wait_after=True); used = True
                log("  klik set-featured:", sel); break
            except Exception as e:
                log("  set click err", str(e)[:50])
    if not used:
        log("  ! set-featured button tidak ditemukan / gagal diklik")
    pg.wait_for_timeout(5000)
    return used

def check_yoast_and_save(pg):
    log("=== Verifikasi Yoast + Save post", POST_ID, "===")
    # pastikan sudah di halaman editor
    if "#postdivrich" not in pg.url and "post.php" not in pg.url:
        goto_light(pg, f"{BASE}/wp-admin/post.php?post={POST_ID}&action=edit", 120)
        for _ in range(30):
            pg.wait_for_timeout(3000)
            if pg.locator("#publish").count() > 0 or pg.locator("#postdivrich").count() > 0:
                break
    # buka panel Yoast (metabox bawah) - klik tab Yoast SEO
    opened = False
    try:
        tabs = pg.locator("#wpseo_meta .wpseo-meta-section, #wpseo_meta .nav-tab, a.nav-tab")
        for i in range(tabs.count()):
            try:
                t = tabs.nth(i)
                if "Yoast" in (t.inner_text(timeout=2000) or ""):
                    t.click(no_wait_after=True); opened = True; break
            except Exception:
                pass
    except Exception:
        pass
    if not opened:
        try:
            # toggle WPSEO metabox jika collapsed
            if pg.locator("#wpseo_meta.postbox.hide-if-js").count() > 0 or \
               (pg.locator("#wpseo_meta").count() > 0 and pg.locator("#wpseo_meta .handlediv").count() > 0):
                pg.locator("#wpseo_meta .handlediv").first.click(no_wait_after=True)
                pg.wait_for_timeout(1000)
        except Exception:
            pass
        try:
            yt = pg.locator("#wpseo_meta a.nav-tab").first
            if yt.count() > 0:
                yt.click(no_wait_after=True); opened = True
        except Exception:
            pass
    log("  yoast panel dibuka:", opened)

    # deteksi 'not analyzed' / 'Not analyzed' dan flag status
    for _ in range(8):
        pg.wait_for_timeout(2000)
        body = pg.locator("body").inner_text(timeout=5000)
        has_not_analyzed = any(s in body for s in ["not analyzed", "Not analyzed", "Not analyzed by Yoast"])
        log("  not-analyzed terdeteksi:", has_not_analyzed)
        # kalau ada, klik tombol 'Analyze' di Yoast (biasanya under SEO tab)
        if has_not_analyzed:
            tackled = False
            for sel in ["button:has-text('Analyze')", "a:has-text('Analyze')",
                        ".yoast-mark-as-cornerstone", "#yoast-analysis"]:
                b = pg.locator(sel)
                if b.count() > 0:
                    try:
                        b.first.click(no_wait_after=True); tackled = True; break
                    except Exception:
                        pass
            log("  trigger analyze:", tackled)
    # cek indikator hijau secara umum (README: hijau = OK). Kami log potongan Yoast results
    try:
        content = pg.locator("#wpseo_meta").inner_text(timeout=6000) if pg.locator("#wpseo_meta").count() > 0 else ""
        if content:
            log("  --- Yoast panel snippet ---")
            # ambil baris yang mengandung kata kunci status
            for ln in content.splitlines():
                s = ln.strip()
                if any(w in s.lower() for w in ["keyphrase", "good", "ok", "problem", "analy", "seo", "readab"]):
                    log("   ", s[:120])
    except Exception:
        pass

    # Save/Update
    sb = pg.locator("#publish")
    if sb.count() > 0:
        try:
            log("  tombol:", sb.first.inner_text(timeout=3000).strip()[:30])
        except Exception:
            pass
        sb.first.click(no_wait_after=True)
        pg.wait_for_timeout(6000)
        # cek muncul notifikasi sukses
        note = ""
        for _ in range(6):
            pg.wait_for_timeout(2000)
            if pg.locator("#message").count() > 0:
                note = pg.locator("#message").inner_text(timeout=2000).strip()[:200]; break
        log("  after save:", note or "no message")
        return True
    log("  ! tombol #publish tidak ditemukan"); return False

def main():
    if os.path.exists(LOG):
        os.remove(LOG)
    log("START set featured post", POST_ID)
    if not os.path.exists(IMG):
        log("  ! gambar tidak ada:", IMG); return 1
    with sync_playwright() as p:
        b = p.chromium.launch(headless=True, args=["--no-sandbox", "--disable-dev-shm-usage"])
        ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36"
        ctx = b.new_context(storage_state=STATE if os.path.exists(STATE) else None, user_agent=ua)
        pg = ctx.new_page()
        if not ensure_login(ctx, pg):
            b.close(); return 1
        mid = upload_and_get_id(pg)
        if mid is None:
            log("  UPLOAD GAGAL - lanjut coba set tetap (reload editor)"); mid = None
        ok = set_featured(pg, mid)
        check_yoast_and_save(pg)
        b.close()
    log("DONE ok=", ok)
    return 0

sys.exit(main())
