#!/usr/bin/env python3
"""
Overnight Orchestrator — Genesis background process
Runs every 10 minutes, stops at 4am AEST, generates morning report.
"""
import os
import sys
import json
import time
import subprocess
from pathlib import Path
from datetime import datetime, timezone, timedelta

GENESIS = Path("E:/genesis-system")
LOG_DIR = GENESIS / "data" / "overnight_logs"
LOG_DIR.mkdir(parents=True, exist_ok=True)

HEARTBEAT_PATH = LOG_DIR / "heartbeat.json"
MORNING_REPORT_SCRIPT = GENESIS / "scripts" / "morning_report.py"

AEST = timezone(timedelta(hours=10))
PYTHON = sys.executable

CYCLE_INTERVAL_SECONDS = 600  # 10 minutes


def get_4am_aest_utc():
    """Return the UTC datetime for 4am AEST tomorrow."""
    now_aest = datetime.now(AEST)
    four_am_aest = now_aest.replace(hour=4, minute=0, second=0, microsecond=0)
    if four_am_aest <= now_aest:
        four_am_aest += timedelta(days=1)
    return four_am_aest.astimezone(timezone.utc)


def check_sites():
    """Check the status of site files."""
    sites = {
        "sunaiva.com": GENESIS / "Sunaiva" / "website" / "index.html",
        "agileadapt.com": GENESIS / "AGILEADAPT" / "website" / "index.html",
        "talkingwebsite.com.au": GENESIS / "RECEPTIONISTAI" / "talkingwebsite" / "index.html",
    }
    results = {}
    for name, path in sites.items():
        if path.exists():
            size = path.stat().st_size
            results[name] = {"exists": True, "size_bytes": size, "path": str(path)}
        else:
            results[name] = {"exists": False, "path": str(path)}
    return results


def write_heartbeat(cycle_num, stop_at_utc, site_status):
    """Write heartbeat.json for monitoring."""
    now_utc = datetime.now(timezone.utc)
    now_aest = datetime.now(AEST)
    data = {
        "cycle": cycle_num,
        "timestamp_utc": now_utc.isoformat(),
        "timestamp_aest": now_aest.isoformat(),
        "stop_at_utc": stop_at_utc.isoformat(),
        "minutes_until_stop": round((stop_at_utc - now_utc).total_seconds() / 60, 1),
        "pid": os.getpid(),
        "sites": site_status,
        "status": "RUNNING",
    }
    HEARTBEAT_PATH.write_text(json.dumps(data, indent=2), encoding='utf-8')
    return data


def run_morning_report():
    """Execute the morning report script."""
    print(f"[ORCHESTRATOR] Running morning report at {datetime.now(AEST).strftime('%H:%M AEST')}")
    try:
        result = subprocess.run(
            [PYTHON, str(MORNING_REPORT_SCRIPT)],
            capture_output=True,
            text=True,
            timeout=120
        )
        print(result.stdout)
        if result.returncode != 0:
            print(f"[ORCHESTRATOR] Morning report stderr: {result.stderr}")
    except Exception as e:
        print(f"[ORCHESTRATOR] Morning report failed: {e}")


def main():
    print(f"[ORCHESTRATOR] Starting at {datetime.now(AEST).strftime('%Y-%m-%d %H:%M:%S AEST')}")
    stop_at_utc = get_4am_aest_utc()
    print(f"[ORCHESTRATOR] Will stop at {stop_at_utc.strftime('%Y-%m-%d %H:%M:%S UTC')} (4am AEST)")
    print(f"[ORCHESTRATOR] Cycle interval: {CYCLE_INTERVAL_SECONDS // 60} minutes")
    print(f"[ORCHESTRATOR] PID: {os.getpid()}")

    cycle = 0
    while True:
        cycle += 1
        now_utc = datetime.now(timezone.utc)

        # Check if it's time to stop
        if now_utc >= stop_at_utc:
            print(f"[ORCHESTRATOR] 4am AEST reached. Running morning report and shutting down.")
            run_morning_report()
            # Update heartbeat to STOPPED
            site_status = check_sites()
            data = write_heartbeat(cycle, stop_at_utc, site_status)
            data["status"] = "STOPPED"
            HEARTBEAT_PATH.write_text(json.dumps(data, indent=2), encoding='utf-8')
            print(f"[ORCHESTRATOR] Done. Exiting.")
            break

        # Normal cycle
        site_status = check_sites()
        hb = write_heartbeat(cycle, stop_at_utc, site_status)
        print(
            f"[ORCHESTRATOR] Cycle {cycle} | "
            f"{datetime.now(AEST).strftime('%H:%M AEST')} | "
            f"{hb['minutes_until_stop']:.0f}min until 4am | "
            f"Sites: {sum(1 for s in site_status.values() if s['exists'])}/{len(site_status)} found"
        )
        sys.stdout.flush()

        # Sleep in 30s chunks to stay responsive to stop time
        sleep_end = now_utc + timedelta(seconds=CYCLE_INTERVAL_SECONDS)
        while datetime.now(timezone.utc) < sleep_end:
            if datetime.now(timezone.utc) >= stop_at_utc:
                break
            time.sleep(30)


if __name__ == "__main__":
    main()
