#!/usr/bin/env python3
"""Scan slot kosong akun Threads @ukyhandoko pada grid 7-slot universal (05,08,11,14,17,20,23 WIB),
Sep 6..15 2026. Slot dianggap terisi kalau ada jadwal (main/reply) di menit H:00-H:03 UTC."""
import json, sys
from datetime import datetime, timezone, timedelta

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

UKY_T = "6a334e89c5ff4ce3a3225a48"
WIB = timedelta(hours=7)
CANON = [5, 8, 11, 14, 17, 20, 23]

def parse_at(v):
    if isinstance(v, (int, float)):
        return datetime.fromtimestamp(v / 1000, tz=timezone.utc)
    try:
        return datetime.fromisoformat(str(v).replace("Z", "+00:00"))
    except Exception:
        return None

def main():
    c = get_client()
    r = c.get_schedules(page=1, limit=100)
    total = r["totalDocs"]
    pages = (total + 99) // 100
    docs = list(r["docs"])
    for p in range(2, pages + 1):
        rr = c.get_schedules(page=p, limit=100)
        docs.extend(rr["docs"])
    print(f"total {len(docs)}")

    mine = []
    for d in docs:
        acc = d.get("account") or {}
        accid = d.get("accountId") or acc.get("id") or acc.get("_id") or ""
        accname = acc.get("name") or ""
        if accid == UKY_T or "uky" in str(accname).lower():
            mine.append(d)
    print(f"uky threads: {len(mine)}")

    # status: pending/draft counts; success/error (past) ignore
    def counts_day(dt_day):
        # dt_day = datetime UTC midnight of day
        occ = {}
        for d in mine:
            st = (d.get("status") or "").lower()
            if st in ("success", "error", "cancelled", "canceled"):
                continue
            at = parse_at(d.get("scheduleAt"))
            if not at:
                continue
            if at.date() != dt_day.date():
                continue
            # map to canonical slot: find the canonical hour whose H:00<=at<=H:03 (replies at :01/:02)
            for h in CANON:
                slot_start_utc = (datetime(at.year, at.month, at.day, h, 0, tzinfo=timezone.utc) - timedelta(hours=7))
                # canonical WIB hour h → UTC h-7
                pass
            # simpler: compute WIB hour
            wib = at + WIB
            for h in CANON:
                start = datetime(wib.year, wib.month, wib.day, h, 0, tzinfo=timezone.utc) - timedelta(hours=7)
                end = start + timedelta(minutes=4)
                if start <= at <= end:
                    occ.setdefault(h, []).append(d.get("id"))
                    break
            else:
                # non-canonical time (e.g. 16:00 WIB) — ignore grid but note
                pass
        return occ

    print("\nSlot kosong (grid 7-slot) mulai Sep 6 2026 (WIB):")
    found = []
    for day in range(6, 23):
        d = datetime(2026, 9, day, tzinfo=timezone.utc)  # midnight UTC; day boundary WIB+7
        # count by WIB calendar day: wib dates from 2026-09-day 00:00 WIB = prev day 17:00 UTC
        occ = {}
        for dd in mine:
            st = (dd.get("status") or "").lower()
            if st in ("success", "error", "cancelled", "canceled"):
                continue
            at = parse_at(dd.get("scheduleAt"))
            if not at:
                continue
            wib = at + WIB
            if wib.day != day or wib.month != 9 or wib.year != 2026:
                continue
            for h in CANON:
                s = datetime(wib.year, wib.month, wib.day, h, 0, tzinfo=timezone.utc) - timedelta(hours=7)
                e = s + timedelta(minutes=4)
                if s <= at <= e:
                    occ.setdefault(h, []).append(dd.get("id"))
                    break
        line = f"Sep {day}: "
        for h in CANON:
            if h in occ:
                line += f"{h:02d}:00WIB[x{len(occ[h])}]  "
            else:
                line += f"{h:02d}:00WIB[FREE]  "
                if not found:
                    found.append((day, h))
        print(line)
    print("\nFirst free slot:", found[0] if found else None)

if __name__ == "__main__":
    main()
