import asyncio
import logging
from apscheduler.schedulers.asyncio import AsyncIOScheduler

from .agents import AGENT_REGISTRY
from .db import delete_old_logs
from . import node_monitor

scheduler = AsyncIOScheduler(timezone="Asia/Seoul")

async def _run_stock_schedule():
    agent = AGENT_REGISTRY.get("stock")
    if agent:
        await agent.on_schedule()

async def _run_stock_screener():
    agent = AGENT_REGISTRY.get("stock")
    if agent:
        await agent.on_screener_schedule()

async def _run_stock_ai_news():
    agent = AGENT_REGISTRY.get("stock")
    if agent:
        await agent.on_ai_news_schedule()

async def _run_stock_holdings_eod():
    agent = AGENT_REGISTRY.get("stock")
    if agent:
        await agent.run_holdings_eod()

async def _run_stock_holdings_brief():
    agent = AGENT_REGISTRY.get("stock")
    if agent:
        await agent.run_holdings_brief()

async def _run_insta_schedule():
    agent = AGENT_REGISTRY.get("insta")
    if agent:
        await agent.on_schedule()


async def _run_insta_trends_collect():
    agent = AGENT_REGISTRY.get("insta")
    if agent:
        await agent.on_command("collect_trends", {})

async def _run_lotto_schedule():
    agent = AGENT_REGISTRY.get("lotto")
    if agent:
        await agent.on_schedule()

async def _run_lotto_light_check():
    agent = AGENT_REGISTRY.get("lotto")
    if agent:
        await agent.run_signal_check(source="light")

async def _run_lotto_sim_check():
    agent = AGENT_REGISTRY.get("lotto")
    if agent:
        await agent.run_signal_check(source="sim")

async def _run_lotto_deep_check():
    agent = AGENT_REGISTRY.get("lotto")
    if agent:
        await agent.run_signal_check(source="deep")

async def _run_lotto_daily_digest():
    agent = AGENT_REGISTRY.get("lotto")
    if agent:
        await agent.run_daily_digest()

async def _run_lotto_weekly_evolution_report():
    agent = AGENT_REGISTRY.get("lotto")
    if agent:
        await agent.run_weekly_evolution_report()

async def _run_lotto_sync_evolver_activity():
    agent = AGENT_REGISTRY.get("lotto")
    if agent:
        await agent.sync_evolver_activity()

async def _run_lotto_sunday_review():
    agent = AGENT_REGISTRY.get("lotto")
    if agent:
        await agent.run_sunday_review()

async def _run_youtube_research():
    agent = AGENT_REGISTRY.get("youtube")
    if agent:
        await agent.on_schedule()

async def _send_youtube_weekly_report():
    agent = AGENT_REGISTRY.get("youtube")
    if agent:
        await agent.send_weekly_report()

async def _poll_pipelines():
    agent = AGENT_REGISTRY.get("youtube_publisher")
    if agent:
        await agent.poll_state_changes()

async def _run_node_health_check():
    await node_monitor.check_and_alert()

def _cleanup_old_logs():
    n = delete_old_logs(days=90)
    if n:
        logging.getLogger(__name__).info("delete_old_logs: %d rows removed", n)

def init_scheduler():
    scheduler.add_job(_run_stock_schedule, "cron", hour=7, minute=30, id="stock_news")
    scheduler.add_job(
        _run_stock_screener,
        "cron",
        day_of_week="mon-fri",
        hour=16,
        minute=30,
        id="stock_screener",
    )
    scheduler.add_job(
        _run_stock_ai_news,
        "cron",
        day_of_week="mon-fri",
        hour=8,
        minute=0,
        id="stock_ai_news_sentiment",
    )
    scheduler.add_job(_run_stock_holdings_eod,   "cron", day_of_week="mon-fri", hour=16, minute=50, id="stock_holdings_eod")  # 16:50: 스크리너 snapshot(16:30) 완료 후 — 부분 일봉 읽기 방지
    scheduler.add_job(_run_stock_holdings_brief, "cron", day_of_week="mon-fri", hour=8,  minute=30, id="stock_holdings_brief")
    scheduler.add_job(_run_insta_schedule, "cron", hour=9, minute=30, id="insta_pipeline")
    # 외부 트렌드 수집은 장 마감 후 16:40 — 9시 주식 활발 시간대 NAS 자원 회피.
    # screener(16:30)와 10분 스태거: Celeron 2C/2.0GHz 동시 실행 시 CPU 폭주 방지 (CHECK_POINT FU-A)
    scheduler.add_job(_run_insta_trends_collect, "cron", hour=16, minute=40, id="insta_trends_collect")
    scheduler.add_job(_run_lotto_schedule,       "cron", day_of_week="mon", hour=9, minute=5, id="lotto_curate")
    scheduler.add_job(_run_lotto_light_check,   "cron", hour=9, minute=15, id="lotto_light_check")
    scheduler.add_job(_run_lotto_sim_check,     "cron", minute=15, hour="0,4,8,12,16,20", id="lotto_sim_check")
    scheduler.add_job(_run_lotto_deep_check,    "cron", day_of_week="sun,wed", hour=21, minute=15, id="lotto_deep_check")
    scheduler.add_job(_run_lotto_daily_digest,  "cron", hour=9, minute=25, id="lotto_digest")
    scheduler.add_job(_run_lotto_weekly_evolution_report, "cron", day_of_week="sat", hour=22, minute=15, id="lotto_evolution_weekly")
    scheduler.add_job(_run_lotto_sunday_review, "cron", day_of_week="sun", hour=9, minute=0, id="lotto_sunday_review")
    scheduler.add_job(
        _run_lotto_sync_evolver_activity,
        "cron", hour=9, minute=30,
        id="lotto_evolver_activity_sync",
    )
    scheduler.add_job(_run_youtube_research,     "cron", hour=9, minute=10, id="youtube_research")
    scheduler.add_job(_send_youtube_weekly_report, "cron", day_of_week="mon", hour=8, minute=0, id="youtube_weekly_report")
    scheduler.add_job(_poll_pipelines, "interval", seconds=30, id="pipeline_poll")
    scheduler.add_job(_run_node_health_check, "interval", seconds=60, id="node_health_check", replace_existing=True)
    scheduler.add_job(_cleanup_old_logs, "cron", hour=3, minute=0, id="cleanup_old_logs", replace_existing=True)
    scheduler.start()
