"""Background scheduler for revenue forecast collection."""

from __future__ import annotations

import logging
import threading
import time
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo

from revenue_forecast_config import RevenueForecastConfig
from revenue_forecast_job import run_revenue_forecast_cycle


SHANGHAI = ZoneInfo("Asia/Shanghai")
logger = logging.getLogger("tencent_realtime_control.revenue_forecast")


def _next_wake(now: datetime, config: RevenueForecastConfig) -> datetime:
    local_time = now.timetz().replace(tzinfo=None)
    if local_time > config.stop_time:
        return datetime.combine(
            now.date() + timedelta(days=1),
            config.start_time,
            SHANGHAI,
        )
    if local_time < config.start_time:
        return datetime.combine(now.date(), config.start_time, SHANGHAI)
    seconds = int(now.timestamp())
    boundary = (
        seconds // config.poll_seconds + 1
    ) * config.poll_seconds
    return datetime.fromtimestamp(boundary, SHANGHAI)


def run_revenue_forecast_forever(config: RevenueForecastConfig) -> None:
    logger.info(
        "Revenue forecast started hours=%s-%s interval=%ss version=%s",
        config.start_time.strftime("%H:%M"),
        config.stop_time.strftime("%H:%M"),
        config.poll_seconds,
        config.forecast_version,
    )
    while True:
        try:
            payload = run_revenue_forecast_cycle(config=config)
            logger.info(
                "Revenue forecast cycle status=%s report_time=%s revenue=%s "
                "target_cost=%s miniapp_target_cost=%s",
                payload.get("status"),
                payload.get("report_time"),
                payload.get("forecast_revenue"),
                payload.get("target_daily_cost"),
                payload.get("miniapp_target_daily_cost"),
            )
        except Exception:
            logger.exception("Revenue forecast cycle failed")

        wake_at = _next_wake(datetime.now(SHANGHAI), config)
        while True:
            remaining = (wake_at - datetime.now(SHANGHAI)).total_seconds()
            if remaining <= 0:
                break
            time.sleep(min(remaining, 5))


def start_revenue_forecast_service(
    config: RevenueForecastConfig,
) -> threading.Thread:
    thread = threading.Thread(
        target=run_revenue_forecast_forever,
        args=(config,),
        name="revenue-forecast",
        daemon=True,
    )
    thread.start()
    return thread
