#!/usr/bin/env python3
"""
TS Law LinkedIn Scheduler — cron job harian.
Jalan tiap jam untuk cek slot kosong.
Post nested 3 post per slot.
Slot: 05:00, 10:00, 15:00, 20:00, 01:00, 06:00, 11:00 WIB (jeda 5 jam)
Sesekali ambil artikel ttalawfirm.id untuk FB — minimal 3 paragraf + link + hashtags.
"""
import json, urllib.request, sys, os, random, hashlib, re
from datetime import datetime, timezone, timedelta

from repliz_client import HEADERS, BASE, ACC
ACCOUNT_ID_LI = ACC.TSLAW_LINKEDIN
ACCOUNT_ID_FB = ACC.TSLAW_FB

LOG_FILE = "/home/mantapman/.openclaw/workspace-atun/tslaw_log.txt"
STATE_FILE = "/home/mantapman/.openclaw/workspace-atun/tslaw_state.json"
HISTORY_FILE = "/home/mantapman/.openclaw/workspace-atun/tslaw_history.json"
FB_POST_FILE = "/home/mantapman/.openclaw/workspace-atun/tslaw_fb_history.json"

WIB = timezone(timedelta(hours=7))

SLOTS = [
    (5, 0), (10, 0), (15, 0), (20, 0), (1, 0), (6, 0), (11, 0)
]

NICHES = [
    "Edukasi Hukum Bisnis",
    "Corporate & Business Law",
    "Contract & Agreement",
    "Perizinan & Legal Compliance",
    "Intellectual Property (HAKI)",
    "Employment Law",
    "FAQ & Tips Hukum",
    "Legal Update",
    "Business Mindset",
    "Personal Branding",
    "Sengketa & Penyelesaian Hukum",
    "Legal Due Diligence",
    "Legal untuk Startup Digital",
    "Hukum & Kepatuhan Pajak",
    "Hukum & Transaksi Properti",
    "Teknologi & Hukum Digital",
    "Alternatif Penyelesaian Sengketa",
    "Hukum & Aspek Pajak Bisnis"
]
LINKEDIN_SERIES = [
    # Series 0: Edukasi Hukum Bisnis
    [
        "Banyak pelaku UMKM di Indonesia yang menjalankan bisnisnya tanpa dilandasi pemahaman hukum yang memadai.",
        "Kesalahan hukum yang sering dilakukan pelaku UMKM",
        "Pertanyaan yang sering kami terima: Apakah bisnis kecil seperti UMKM perlu lawyer?"
    ],
    # Series 1: Corporate & Business Law
    [
        "Pendirian PT adalah langkah awal yang krusial bagi pengusaha yang ingin mengembangkan bisnisnya secara profesional.",
        "Perubahan anggaran dasar perusahaan sering kali diperlukan seiring perkembangan bisnis.",
        "RUPS (Rapat Umum Pemegang Saham) adalah organ tertinggi dalam perseroan terbatas."
    ],
    # Series 2: Contract & Agreement
    [
        "Kontrak adalah tulang punggung hubungan bisnis.",
        "NDA (Non-Disclosure Agreement) adalah salah satu kontrak yang paling sering digunakan.",
        "Kontrak tanpa materai - sah atau tidak?"
    ],
    # Series 3: Perizinan & Legal Compliance
    [
        "NIB (Nomor Induk Berusaha) adalah identitas usaha yang diterbitkan oleh pemerintah melalui sistem OSS.",
        "Kepatuhan terhadap peraturan perundang-undangan (legal compliance) adalah kewajiban setiap badan usaha.",
        "Perubahan KBLI sering kali diperlukan ketika perusahaan memperluas bidang usahanya."
    ],
    # Series 4: Intellectual Property (HAKI)
    [
        "Merek dagang adalah aset berharga yang sering kali luput dari perhatian para pengusaha.",
        "Hak cipta melindungi karya intelektual di bidang seni, sastra, dan ilmu pengetahuan.",
        "Sengketa merek sering terjadi di Indonesia."
    ],
    # Series 5: Employment Law
    [
        "PKWT dan PKWTT adalah dua jenis perjanjian kerja yang memiliki perbedaan mendasar.",
        "PHK adalah situasi yang tidak diinginkan baik oleh pengusaha maupun pekerja.",
        "Peraturan Perusahaan (PP) adalah dokumen yang berisi ketentuan tentang syarat kerja."
    ],
    # Series 6: FAQ & Tips Hukum
    [
        "Pertanyaan yang sering kami terima: Berapa biaya mendirikan PT?",
        "Pertanyaan klasik: Apakah CV bisa memiliki investor?",
        "Pertanyaan yang sering muncul: Apakah kontrak perjanjian melalui WhatsApp atau email memiliki kekuatan hukum?"
    ],
    # Series 7: Legal Update
    [
        "Peraturan perundang-undangan di Indonesia terus mengalami perubahan.",
        "Sistem OSS terus mengalami penyempurnaan.",
        "Perubahan UU Cipta Kerja telah membawa berbagai perubahan signifikan."
    ],
    # Series 8: Business Mindset
    [
        "Banyak pengusaha yang menganggap legal sebagai biaya yang bisa ditunda.",
        "Manajemen risiko hukum adalah aspek yang sering diabaikan oleh pelaku usaha.",
        "Good corporate governance bukan hanya untuk perusahaan besar."
    ],
    # Series 9: Personal Branding
    [
        "Tito Suprianto - pendiri TS Law Firm.",
        "Menjadi lawyer bukan sekadar profesi bagi saya.",
        "Saya sering mendapat pertanyaan: Pak Tito, sebagai pebisnis, apa yang harus saya lakukan pertama kali?"
    ],
    # Series 10: Sengketa & Penyelesaian Hukum
    [
        "Sengketa bisnis adalah hal yang hampir tidak bisa dihindari dalam perjalanan perusahaan.",
        "Gugatan perdata di pengadilan membutuhkan persiapan yang matang.",
        "Surat kuasa adalah dokumen yang memberikan wewenang kepada seseorang untuk bertindak."
    ],
    # Series 11: Legal Due Diligence
    [
        "Legal due diligence adalah proses pemeriksaan menyeluruh terhadap aspek hukum suatu perusahaan.",
        "M&A bukan hanya soal angka dan valuasi.",
        "Salah satu temuan yang sering muncul dalam legal due diligence adalah ketidaksesuaian perizinan."
    ],
    # Series 12: Legal untuk Startup Digital
    [
        "Startup digital memiliki karakteristik yang berbeda dengan bisnis konvensional.",
        "Vesting adalah mekanisme di mana hak kepemilikan saham diperoleh secara bertahap.",
        "Pendanaan (funding) adalah momen krusial dalam perjalanan startup."
    ],
    # Series 13: Hukum & Kepatuhan Pajak
    [
        "Kewajiban perpajakan adalah aspek yang tidak terpisahkan dari badan usaha.",
        "Sengketa pajak sering terjadi karena perbedaan interpretasi antara wajib pajak dan fiskus.",
        "NPWP dan PKP adalah dua hal yang berbeda dalam sistem perpajakan Indonesia."
    ],
    # Series 14: Hukum & Transaksi Properti
    [
        "Transaksi properti melibatkan nilai yang besar dan berisiko hukum tinggi jika tidak dilakukan dengan benar.",
        "Sengketa tanah adalah salah satu kasus perdata yang paling sering terjadi di Indonesia.",
        "PPAT memiliki peran krusial dalam setiap transaksi properti."
    ],
    # Series 15: Teknologi & Hukum Digital
    [
        "Revolusi digital membawa tantangan hukum baru yang belum pernah ada sebelumnya.",
        "UU Perlindungan Data Pribadi (UU PDP) adalah regulasi yang wajib dipatuhi oleh setiap perusahaan.",
        "Fintech dan pinjaman online sedang menjadi sorotan."
    ],
    # Series 16: Alternatif Penyelesaian Sengketa
    [
        "Tidak semua sengketa bisnis harus diselesaikan melalui pengadilan.",
        "Mediasi adalah proses penyelesaian sengketa yang melibatkan mediator sebagai pihak ketiga yang netral.",
        "Arbitrase adalah penyelesaian sengketa di luar pengadilan yang menghasilkan putusan yang bersifat final dan mengikat."
    ],
    # Series 17: Hukum & Aspek Pajak Bisnis
    [
        "Pajak bukan sekadar kewajiban tahunan - ia adalah aspek hukum yang melekat pada setiap transaksi bisnis.",
        "Sengketa pajak bisa muncul dari berbagai hal: pemeriksaan pajak, keberatan, banding, hingga peninjauan kembali.",
        "Pertanyaan populer: Bisakah pengusaha kena pidana pajak?"
    ]
]

def log(msg):
    ts = datetime.now(WIB).strftime("%Y-%m-%d %H:%M:%S")
    line = f"[{ts} WIB] {msg}"
    print(line)
    with open(LOG_FILE, "a") as f:
        f.write(line + "\n")


def content_hash(text):
    return hashlib.md5(text.encode()).hexdigest()


def load_state():
    try:
        with open(STATE_FILE) as f:
            return json.load(f)
    except:
        return {"last_series": -1, "posted_today": []}


def save_state(state):
    with open(STATE_FILE, "w") as f:
        json.dump(state, f)


def load_history():
    try:
        with open(HISTORY_FILE) as f:
            return json.load(f)
    except:
        return {"posts": [], "content_hashes": []}


def save_history(hist):
    with open(HISTORY_FILE, "w") as f:
        json.dump(hist, f, indent=2)


def load_fb_history():
    try:
        with open(FB_POST_FILE) as f:
            return json.load(f)
    except:
        return {"posts": [], "article_urls": []}


def save_fb_history(hist):
    with open(FB_POST_FILE, "w") as f:
        json.dump(hist, f, indent=2)


def get_next_slot(now_hour, now_min):
    today = datetime.now(WIB).date()
    for h, m in SLOTS:
        slot_total = h * 60 + m
        now_total = now_hour * 60 + now_min
        if slot_total > now_total:
            return datetime(today.year, today.month, today.day, h, m, tzinfo=WIB)
    # Kalo udah lewat semua slot, ambil slot besok pagi
    tmr = today + timedelta(days=1)
    return datetime(tmr.year, tmr.month, tmr.day, SLOTS[0][0], SLOTS[0][1], tzinfo=WIB)


def get_fb_articles():
    """Ambil artikel dari ttalawfirm.id via WP REST API."""
    url = "https://ttalawfirm.id/wp-json/wp/v2/posts?per_page=5&_fields=id,title,excerpt,link,date"
    try:
        req = urllib.request.Request(url)
        with urllib.request.urlopen(req, timeout=8) as resp:
            if resp.status == 200:
                posts = json.loads(resp.read().decode())
                return posts
            else:
                log(f"⚠️ WP API returned {resp.status}")
                return []
    except Exception as e:
        log(f"⚠️ Gagal ambil artikel: {e}")
        return []


def post_to_repliz(account_id, content, schedule_time, platform="linkedin"):
    url = f"{BASE}/public/schedule"
    title_lines = content.strip().split("\n")
    title = title_lines[0][:60] if title_lines else "TS Law Firm"
    
    payload = {
        "accountId": account_id,
        "title": title,
        "description": content,
        "platform": platform,
        "type": "text",
        "medias": [],
        "topic": "TS Law",
        "scheduleAt": schedule_time.strftime("%Y-%m-%dT%H:%M:%S.000Z"),
        "timezone": "Asia/Jakarta"
    }
    data = json.dumps(payload).encode()
    req = urllib.request.Request(url, data=data, headers=HEADERS, method="POST")
    try:
        with urllib.request.urlopen(req) as resp:
            result = json.loads(resp.read().decode())
            post_id = result.get("scheduleId") or result.get("id") or result.get("data", {}).get("id")
            log(f"✅ Posted {platform} at {schedule_time.strftime('%H:%M')} → ID: {post_id}")
            return post_id
    except urllib.error.HTTPError as e:
        err_body = e.read().decode()
        log(f"❌ Repliz error: {e.code} {err_body}")
        return None
    except Exception as e:
        log(f"❌ Error: {e}")
        return None


def main():
    now = datetime.now(WIB)
    today_str = now.strftime("%Y-%m-%d")
    now_hour, now_min = now.hour, now.minute
    now_total = now_hour * 60 + now_min
    
    log(f"🔄 TS Law Check — {today_str} {now_hour:02d}:{now_min:02d} WIB")
    
    state = load_state()
    hist = load_history()
    used_hashes = set(hist.get("content_hashes", []))
    
    # Reset kalo hari baru
    if state.get("date") != today_str:
        state = {"date": today_str, "last_series": state.get("last_series", -1), "posted_today": []}
        save_state(state)
    
    # Cari slot berikutnya yang belum terisi
    next_slot = None
    for h, m in SLOTS:
        slot_total = h * 60 + m
        if slot_total > now_total and slot_total not in state.get("posted_today", []):
            next_slot = (h, m)
            break
    
    if next_slot is None:
        log("⏭️ Semua slot sudah terisi atau tidak ada slot tersisa hari ini.")
        return
    
    # Pilih seri konten berikutnya
    last_series = state.get("last_series", -1)
    next_series = (last_series + 1) % len(LINKEDIN_SERIES)
    series = LINKEDIN_SERIES[next_series]
    
    # Cek duplikasi hash
    series_hashes = [content_hash(c) for c in series]
    if any(h in used_hashes for h in series_hashes):
        log(f"⚠️ Series {next_series+1} sudah pernah diposting. Cari seri lain...")
        for offset in range(1, len(LINKEDIN_SERIES)):
            candidate = (next_series + offset) % len(LINKEDIN_SERIES)
            candidate_hashes = [content_hash(c) for c in LINKEDIN_SERIES[candidate]]
            if not any(h in used_hashes for h in candidate_hashes):
                next_series = candidate
                series = LINKEDIN_SERIES[next_series]
                series_hashes = candidate_hashes
                log(f"✅ Beralih ke Series {next_series+1}")
                break
        else:
            log("❌ Semua seri konten sudah habis. Butuh konten baru!")
            return
    
    schedule_time = datetime(now.year, now.month, now.day, next_slot[0], next_slot[1], tzinfo=WIB)
    
    # Post di LinkedIn
    post_ids = []
    for i, content in enumerate(series):
        if i == 0:
            pid = post_to_repliz(ACCOUNT_ID_LI, content, schedule_time, "linkedin")
        else:
            reply_time = schedule_time + timedelta(minutes=2 * i)
            pid = post_to_repliz(ACCOUNT_ID_LI, content, reply_time, "linkedin")
        if pid:
            post_ids.append(pid)
    
    # Sesekali ambil artikel dari website untuk LinkedIn & FB
    li_post_count = state.get("li_article_posts", 0)
    fb_post_count = state.get("fb_posts", 0)
    should_post_article = (li_post_count % 3 == 0) or random.random() < 0.33
    
    li_article_id = None
    fb_post_id = None
    if should_post_article:
        articles = get_fb_articles()
        fb_hist = load_fb_history()
        used_article_urls = set(fb_hist.get("article_urls", []))
        
        # Cari artikel yang belum dipakai
        fresh_articles = [a for a in articles if a.get("link") not in used_article_urls]
        if not fresh_articles:
            fresh_articles = articles[:1]  # reset kalo abis
        
        if fresh_articles:
            art = fresh_articles[0]
            art_title = art.get("title", {}).get("rendered", "Artikel TS Law")
            art_link = art.get("link", "")
            art_excerpt = art.get("excerpt", {}).get("rendered", "")
            art_excerpt = re.sub(r'<[^>]+>', '', art_excerpt).strip()
            art_excerpt = art_excerpt[:200] + "..."
            
            # LinkedIn — share artikel
            li_article_content = (
                f"{art_title}\n\n"
                f"{art_excerpt}\n\n"
                f"Baca selengkapnya: {art_link}\n\n"
                f"#TSLawFirm #TitoSuprianto #HukumBisnis #UMKM #Startup #LegalPartner #EdukasiHukum"
            )
            li_article_time = schedule_time + timedelta(minutes=10)
            li_article_id = post_to_repliz(ACCOUNT_ID_LI, li_article_content, li_article_time, "linkedin")
            
            # Facebook — share artikel juga
            fb_content = (
                f"{art_title}\n\n"
                f"{art_excerpt}\n\n"
                f"Baca selengkapnya di artikel berikut:\n{art_link}\n\n"
                f"#TSLawFirm #TitoSuprianto #HukumBisnis #UMKM #Startup #LegalPartner #KonsultasiHukum #EdukasiHukum #BisnisAman #HukumIndonesia"
            )
            fb_time = schedule_time + timedelta(minutes=14)
            fb_post_id = post_to_repliz(ACCOUNT_ID_FB, fb_content, fb_time, "facebook")
            
            if li_article_id or fb_post_id:
                entry = {
                    "date": today_str,
                    "article_url": art_link,
                    "article_title": art_title,
                }
                if li_article_id:
                    entry["li_post_id"] = li_article_id
                if fb_post_id:
                    entry["fb_post_id"] = fb_post_id
                fb_hist["posts"].append(entry)
                fb_hist["article_urls"].append(art_link)
                save_fb_history(fb_hist)
    
    # Update state
    if post_ids:
        state["last_series"] = next_series
        posted = state.get("posted_today", [])
        posted.append(next_slot[0] * 60 + next_slot[1])
        if should_post_article:
            state["li_article_posts"] = state.get("li_article_posts", 0) + 1
            state["fb_posts"] = state.get("fb_posts", 0) + 1
        save_state(state)
        
        hist["posts"].append({
            "date": today_str,
            "time": f"{next_slot[0]:02d}:{next_slot[1]:02d}",
            "series": next_series,
            "niche": NICHES[next_series],
            "post_ids": post_ids
        })
        hist["content_hashes"].extend(series_hashes)
        save_history(hist)
        
        log(f"📦 Series {next_series+1} ({NICHES[next_series]}) — {len(post_ids)}/3 posted di slot {next_slot[0]:02d}:{next_slot[1]:02d} WIB")
        if fb_post_id:
            log(f"📰 FB artikel juga diposting")
    else:
        log("⚠️ Gagal posting. Coba lagi nanti.")


if __name__ == "__main__":
    main()

