#!/usr/bin/env python3
import json
import os
import time
from datetime import datetime, timezone
from pathlib import Path

import requests

ROOT = Path("/data/video-pipeline/GacMaiAudio/project/gacmai_20260713_050144")
BASE = os.environ["POSTIZ_BASE_URL"].rstrip("/")
HEADERS = {"Authorization": os.environ["POSTIZ_API_KEY"]}
YOUTUBE = "cmriltjyk0013j7c8l7dp3o5i"
FACEBOOK = "cmrilrryn0011j7c8kfzgx9zq"
TITLE = "Những Con Dấu Dưới Mái Kính"
YT_TITLE = f"{TITLE} |Truyện Audio Full"
DESCRIPTION = """Lâm Vãn Ninh bị gài chữ ký vào một hồ sơ nghiệm thu nguy hiểm và buộc phải mang tiếng để bảo toàn chuỗi chứng cứ. Khi công việc, mái nhà và sự an toàn của những người bên cạnh lần lượt bị đe dọa, cô lựa chọn phản công bằng sự thật trong một phiên điều trần công khai.

🎧 Tên truyện: Những Con Dấu Dưới Mái Kính
🎙 Giọng đọc: Gác Mái Audio
📚 Thể loại: Đô thị, đấu trí, vả mặt, nữ cường

Mời bạn theo dõi trọn bộ câu chuyện và đồng hành cùng Gác Mái Audio.

Tất cả nhân vật, địa danh, tổ chức, pháp luật và sự kiện trong truyện đều là hư cấu. Mọi sự trùng hợp chỉ là ngẫu nhiên.

#GacMaiAudio #TruyenAudio #TruyenAudioFull #NuCuong #DauTri #VaMat"""
RECEIPT = ROOT / "artifacts/postiz_calendar.json"


def request(method, path, **kwargs):
    for attempt in range(4):
        response = requests.request(method, BASE + path, headers=HEADERS, timeout=300, **kwargs)
        if response.status_code < 400:
            return response
        if response.status_code == 429 or response.status_code >= 500:
            time.sleep(2 ** attempt * 5)
            continue
        raise RuntimeError(f"{method} {path}: HTTP {response.status_code}: {response.text[:1000]}")
    raise RuntimeError(f"{method} {path}: retries exhausted")


def load_receipt():
    if RECEIPT.exists():
        return json.loads(RECEIPT.read_text())
    return {"title": TITLE, "channels": {}, "uploads": {}}


def save(data):
    data["updated_at"] = datetime.now(timezone.utc).isoformat()
    RECEIPT.write_text(json.dumps(data, ensure_ascii=False, indent=2))


def upload(path, receipt, key):
    existing = receipt["uploads"].get(key)
    if existing and existing.get("id") and existing.get("path"):
        return existing
    with open(path, "rb") as stream:
        response = request("POST", "/upload", files={"file": (Path(path).name, stream)})
    body = response.json()
    item = body.get("output", body.get("data", body))
    if isinstance(item, list):
        item = item[0]
    if not item.get("id") or not item.get("path"):
        raise RuntimeError(f"Upload response missing id/path: {body}")
    receipt["uploads"][key] = {"id": item["id"], "path": item["path"]}
    save(receipt)
    return receipt["uploads"][key]


def integration_map():
    body = request("GET", "/integrations").json()
    items = body if isinstance(body, list) else body.get("integrations", body.get("data", []))
    return {x["id"]: x for x in items}


def find_slot():
    body = request("GET", f"/find-slot/{YOUTUBE}").json()
    value = body.get("date", body.get("output", body.get("data", body)))
    if isinstance(value, dict):
        value = value.get("date", value.get("slot"))
    if not isinstance(value, str):
        raise RuntimeError(f"Cannot resolve slot: {body}")
    return value


def create_post(channel, payload, receipt):
    if receipt["channels"].get(channel, {}).get("post_id"):
        return
    body = request("POST", "/posts", json=payload).json()
    if isinstance(body, list):
        output = body
    else:
        output = body.get("output", body.get("data", body))
    post_id = None
    group_id = None
    if isinstance(output, dict):
        post_id = output.get("id") or output.get("postId")
        group_id = output.get("group") or output.get("groupId")
    elif isinstance(output, list) and output:
        first = output[0]
        if isinstance(first, dict):
            post_id = first.get("id") or first.get("postId")
            group_id = first.get("group") or first.get("groupId")
    if not (post_id or group_id):
        raise RuntimeError(f"Post response missing identifier: {body}")
    receipt["channels"].setdefault(channel, {}).update({"post_id": post_id, "group_id": group_id, "response": body})
    save(receipt)


def main():
    receipt = load_receipt()
    integrations = integration_map()
    assert integrations[YOUTUBE]["identifier"] == "youtube" and not integrations[YOUTUBE].get("disabled")
    assert integrations[FACEBOOK]["identifier"] == "facebook" and not integrations[FACEBOOK].get("disabled")
    video = upload(ROOT / "render/final.mp4", receipt, "video")
    thumbnail = upload(ROOT / "render/thumbnail.png", receipt, "thumbnail")
    slot = receipt.get("canonical_slot") or find_slot()
    receipt["canonical_slot"] = slot
    for channel in [YOUTUBE, FACEBOOK]:
        integration = integrations[channel]
        receipt["channels"].setdefault(channel, {}).update({
            "name": integration.get("name"), "provider": integration.get("identifier"),
            "profile": integration.get("profile"), "scheduled_date": slot,
        })
    save(receipt)

    youtube_payload = {
        "type": "schedule", "date": slot, "shortLink": False, "tags": [],
        "posts": [{
            "integration": {"id": YOUTUBE},
            "value": [{"content": DESCRIPTION, "image": [video]}],
            "settings": {"__type": "youtube", "title": YT_TITLE, "type": "public",
                         "selfDeclaredMadeForKids": "no", "thumbnail": thumbnail,
                         "tags": [{"value": x, "label": x} for x in
                                  ["truyện audio", "truyện audio full", "Gác Mái Audio", "nữ cường", "đấu trí"]]},
        }],
    }
    facebook_payload = {
        "type": "schedule", "date": slot, "shortLink": False, "tags": [],
        "posts": [{
            "integration": {"id": FACEBOOK},
            "value": [{"content": DESCRIPTION, "image": [video]}],
            "settings": {"__type": "facebook", "post_type": "post"},
        }],
    }
    create_post(YOUTUBE, youtube_payload, receipt)
    create_post(FACEBOOK, facebook_payload, receipt)
    receipt["creation_complete"] = True
    save(receipt)
    print(json.dumps({"slot": slot, "channels": receipt["channels"]}, ensure_ascii=False))


if __name__ == "__main__":
    main()
