#!/usr/bin/env python3
"""
Migrasi image jadwal pending Repliz dari studiosoft.id (SSL expired) → server mantapserver.
HANYA file yang direferensikan jadwal Repliz. File diverifikasi sama (hash & magic bytes).
"""
import sys, os, json, ssl, hashlib, urllib.request, urllib.error

sys.path.insert(0, "/home/mantapman/.hermes/profiles/atun/workspace")
from repliz_client import HEADERS, BASE

DUMP = "/home/mantapman/.hermes/profiles/atun/workspace/repliz_audit_dump.json"
IMG_DIR = "/home/mantapman/.hermes/profiles/atun/workspace/openclaw-img"
NEW_BASE = "https://mantapserver.tail3947bb.ts.net/openclaw-img/"

# SSL context bypass (studiosoft.id cert expired — file masih ada, cuma HTTPS rusak)
CTX = ssl.create_default_context()
CTX.check_hostname = False
CTX.verify_mode = ssl.CERT_NONE

def fetch_dump():
    import importlib.util
    spec = importlib.util.spec_from_file_location("audit", "/home/mantapman/.hermes/profiles/atun/workspace/audit_pending_schedules.py")
    # pakai dump yang sudah ada
    with open(DUMP) as f:
        return json.load(f)

def get_pending_with_ss(docs):
    """Semua jadwal pending yang media-nya dari studiosoft.id."""
    out = {}
    for d in docs:
        if (d.get("status") or "").lower() != "pending":
            continue
        for m in (d.get("medias") or []):
            u = m.get("url") or ""
            if "studiosoft.id" in u:
                out.setdefault(d["id"], {"doc": d, "medias": [m]})
                # jangan dobel
    return out

def download(url, dest):
    req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
    with urllib.request.urlopen(req, timeout=60, context=CTX) as r:
        data = r.read()
    if len(data) < 5000:
        return None, f"terlalu kecil ({len(data)} bytes) — kemungkinan bukan gambar"
    # magic bytes: JPEG FFD8FF | PNG 89504E47
    if data[:3] == b"\xff\xd8\xff":
        pass
    elif data[:4] == b"\x89PNG":
        pass
    else:
        return None, f"bukan JPEG/PNG (magic: {data[:8].hex()})"
    with open(dest, "wb") as f:
        f.write(data)
    return data, None

def sha(data):
    return hashlib.sha256(data).hexdigest()[:16]

def put_schedule(sid, s, medias):
    payload = {
        "accountId": s.get("accountId"),
        "title": s.get("title", ""),
        "description": s.get("description", ""),
        "topic": s.get("topic", ""),
        "type": s.get("type", ""),
        "medias": medias,
        "scheduleAt": s.get("scheduleAt"),
        "replies": s.get("replies") or [],
    }
    req = urllib.request.Request(f"{BASE}/public/schedule/{sid}",
                                 data=json.dumps(payload).encode(),
                                 headers={**HEADERS, "Content-Type": "application/json"},
                                 method="PUT")
    with urllib.request.urlopen(req, timeout=30) as r:
        return r.status

def main():
    docs = fetch_dump()
    print(f"📂 total jadwal: {len(docs)}")

    # kumpulkan jadwal pending dgn media studiosoft.id
    targets = {}
    for d in docs:
        if (d.get("status") or "").lower() != "pending":
            continue
        for m in (d.get("medias") or []):
            u = (m.get("url") or "")
            if "studiosoft.id" in u and "wp-content" in u:
                targets.setdefault(u, []).append(d)
    print(f"🎯 URL studiosoft.id unik di jadwal pending: {len(targets)}")
    sched_count = sum(len(v) for v in targets.values())
    print(f"🎯 jadwal kena: {sched_count}")

    # 1) Download semua file unik → openclaw-img
    ok_files, fail_files = [], []
    for url, docs_ in sorted(targets.items()):
        fn = url.split("/")[-1].split("?")[0]
        if not fn:
            fail_files.append((url, "nama file kosong"))
            continue
        dest = os.path.join(IMG_DIR, fn)
        if os.path.exists(dest):
            with open(dest, "rb") as f:
                existing = f.read()
            # file sudah ada — verifikasi bisa diakses & sama? kita redownload & bandingkan
            data, err = download(url, dest)
            if err:
                fail_files.append((url, f"redownload gagal: {err}"))
                continue
            if sha(data) != sha(existing):
                # konten beda — simpan versi baru (jadwal pakai versi WP)
                print(f"  ⚠️ {fn}: isi berbeda dari yg ada — pakai versi dari WP (jadwal)")
        else:
            data, err = download(url, dest)
            if err:
                fail_files.append((url, err))
                continue
        ok_files.append((url, fn, dest))
        print(f"  ✅ {fn} ({len(data)//1024} KB, sha {sha(data)})")

    print(f"\n📦 download sukses: {len(ok_files)} | gagal: {len(fail_files)}")
    for url, err in fail_files:
        print(f"  ❌ {err}: {url[:100]}")

    # 2) Update jadwal → URL baru (hanya yg berhasil di-download)
    fixed, failed = 0, []
    for url, fn, dest in ok_files:
        new_url = NEW_BASE + fn
        for d in targets[url]:
            sid = d["id"]
            medias = d.get("medias") or []
            for m in medias:
                if (m.get("url") or "") == url:
                    m["url"] = new_url
            try:
                st = put_schedule(sid, d, medias)
                fixed += 1
                print(f"  🔄 {sid} → {new_url} (HTTP {st})")
            except Exception as e:
                failed.append((sid, str(e)))
                print(f"  ❌ PUT {sid}: {e}")

    print(f"\n✅ jadwal di-update: {fixed} | gagal: {len(failed)}")
    if failed:
        for sid, e in failed:
            print(f"   {sid}: {e}")

    # 3) Simpan laporan
    report = {
        "url_asal": [u for u, _, _ in ok_files],
        "file": [fn for _, fn, _ in ok_files],
        "gagal_download": fail_files,
        "gagal_update": failed,
        "jadwal_updated": fixed,
    }
    with open("/home/mantapman/.hermes/profiles/atun/workspace/repliz_migrate_ss_report.json", "w") as f:
        json.dump(report, f, indent=1, ensure_ascii=False)

if __name__ == "__main__":
    main()
