import os
import json
import yaml
import logging
from datetime import datetime
from zoneinfo import ZoneInfo

from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.triggers.cron import CronTrigger

# --- Adapters (you will fill in real API calls) ---
from adapters.instagram_meta import post_instagram
from adapters.facebook_meta import post_facebook
from adapters.x_api import post_x
from adapters.tiktok_api import post_tiktok
from adapters.weibo_api import post_weibo

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s | %(levelname)s | %(message)s"
)

ADAPTERS = {
    "instagram": post_instagram,
    "facebook": post_facebook,
    "x": post_x,
    "tiktok": post_tiktok,
    "weibo": post_weibo,
}

def load_schedule(path="schedule.yaml"):
    with open(path, "r", encoding="utf-8") as f:
        return yaml.safe_load(f)

def load_queue(path="content_queue.json"):
    with open(path, "r", encoding="utf-8") as f:
        return json.load(f)

def weekday_key(dt: datetime) -> str:
    return dt.strftime("%a").lower()[:3]  # mon,tue,wed...

def pick_next_item(queue, content_type: str):
    # Simple FIFO by type; you can make this smarter (per-region, per-platform, avoid repeats, etc.)
    for i, item in enumerate(queue):
        if item.get("type") == content_type:
            return i, item
    return None, None

def dispatch(region_name: str, region_cfg: dict, content_type: str):
    tz = ZoneInfo(region_cfg["timezone"])
    now = datetime.now(tz)

    queue = load_queue()
    idx, item = pick_next_item(queue, content_type)
    if not item:
        logging.warning(f"[{region_name}] No queued content for type={content_type}")
        return

    # Post to requested platforms
    platforms = item.get("platforms", [])
    logging.info(f"[{region_name}] Dispatching {content_type} item={item['id']} to {platforms}")

    for p in platforms:
        adapter = ADAPTERS.get(p)
        if not adapter:
            logging.warning(f"[{region_name}] No adapter for platform={p}")
            continue

        try:
            adapter(
                caption=item.get("caption", ""),
                media_path=item.get("media_path", None),
                region=region_name,
                timezone=region_cfg["timezone"],
                content_type=content_type,
            )
            logging.info(f"[{region_name}] ✅ Posted to {p}: {item['id']}")
        except Exception as e:
            logging.error(f"[{region_name}] ❌ Failed on {p}: {e}")

    # Remove the used item (FIFO)
    del queue[idx]
    with open("content_queue.json", "w", encoding="utf-8") as f:
        json.dump(queue, f, ensure_ascii=False, indent=2)

def add_jobs(sched: BlockingScheduler, schedule_data: dict):
    rules = schedule_data["rules"]
    regions = schedule_data["regions"]

    for region_name, cfg in regions.items():
        tz = cfg["timezone"]

        # POSTS: Tue–Thu @ post_time
        h, m = cfg["post_time"].split(":")
        for d in rules["posts_days"]:
            sched.add_job(
                dispatch,
                CronTrigger(day_of_week=d, hour=int(h), minute=int(m), timezone=tz),
                args=[region_name, cfg, "post"],
                id=f"{region_name}_post_{d}",
                replace_existing=True
            )

        # REELS: Tue–Thu @ reel_time
        h, m = cfg["reel_time"].split(":")
        for d in rules["reels_days"]:
            sched.add_job(
                dispatch,
                CronTrigger(day_of_week=d, hour=int(h), minute=int(m), timezone=tz),
                args=[region_name, cfg, "reel"],
                id=f"{region_name}_reel_{d}",
                replace_existing=True
            )

        # BTS: Wed/Fri/Sun @ bts_time
        h, m = cfg["bts_time"].split(":")
        for d in rules["bts_days"]:
            sched.add_job(
                dispatch,
                CronTrigger(day_of_week=d, hour=int(h), minute=int(m), timezone=tz),
                args=[region_name, cfg, "bts"],
                id=f"{region_name}_bts_{d}",
                replace_existing=True
            )

def main():
    schedule_data = load_schedule()
    sched = BlockingScheduler()
    add_jobs(sched, schedule_data)

    logging.info("Scheduler started. Jobs loaded from schedule.yaml")
    sched.start()

if __name__ == "__main__":
    main()
