"""
Periodic Saxo-priced Watchlist refresh + wavelet recompute — mirrors services/saxo_scheduler.py's
pattern (own thread, own config-driven interval, `while not stop.wait(0)` so the first pass runs
immediately on startup). Independent of services/auto_cycle.py's once-a-day cycle, which also runs
this same computation as one of its steps but only at cycle cadence — this lets the Dashboard's
Wavelets Signal card and Instrument Analysis's cached Wavelet tab (services.wavelet_signals.
scan_watchlist_wavelet_signals writes both) stay current without waiting for, or manually
triggering, a full cycle.
"""
from __future__ import annotations

import logging
import threading
import uuid

logger = logging.getLogger(__name__)

_thread: threading.Thread | None = None
_stop = threading.Event()

DEFAULT_REFRESH_MINUTES = 15


def get_settings() -> dict:
    from .database import get_config
    enabled = (get_config("wavelet_refresh_enabled") or "true").lower() == "true"
    try:
        minutes = float(get_config("wavelet_refresh_minutes") or str(DEFAULT_REFRESH_MINUTES))
    except (TypeError, ValueError):
        minutes = DEFAULT_REFRESH_MINUTES
    return {"enabled": enabled, "refresh_minutes": minutes}


def set_settings(enabled: bool, refresh_minutes: float) -> None:
    from .database import set_config
    set_config("wavelet_refresh_enabled", "true" if enabled else "false")
    set_config("wavelet_refresh_minutes", str(max(1.0, refresh_minutes)))


def run_refresh_pass() -> int:
    """One pass over the whole Watchlist: Saxo-first price fetch + wavelet recompute (see
    services.wavelet_signals.scan_watchlist_wavelet_signals), then Curve Regime
    classification per instrument (services.curve_regime.refresh_watchlist_curve_regimes,
    reusing that same wavelet cache) — the same work the daily cycle's own wavelet step
    does, just callable on its own cadence. Shared by the periodic loop and the manual
    'refresh now' button. Returns the number of signal rows written."""
    import asyncio
    from .wavelet_signals import compute_and_save_wavelet_signals
    from .curve_regime import refresh_watchlist_curve_regimes
    run_id = f"refresh-{uuid.uuid4().hex[:10]}"
    try:
        results = compute_and_save_wavelet_signals(run_id)
        logger.info(f"[Wavelet Scheduler] Refresh pass complete: {len(results)} signal rows ({run_id})")
    except Exception as e:
        logger.warning(f"[Wavelet Scheduler] Wavelet refresh failed: {e}")
        results = []
    try:
        n_regimes = asyncio.run(refresh_watchlist_curve_regimes())
        logger.info(f"[Wavelet Scheduler] Curve Regime refresh complete: {n_regimes} instruments")
    except Exception as e:
        logger.warning(f"[Wavelet Scheduler] Curve Regime refresh failed: {e}")
    return len(results)


def _loop(stop: threading.Event):
    while not stop.wait(0):
        settings = get_settings()
        if not settings["enabled"]:
            stop.wait(timeout=300)  # re-check periodically in case it gets enabled without a restart
            continue
        run_refresh_pass()
        stop.wait(timeout=settings["refresh_minutes"] * 60)


def start_wavelet_scheduler():
    global _thread
    _stop.clear()
    if not (_thread and _thread.is_alive()):
        _thread = threading.Thread(target=_loop, args=(_stop,), name="wavelet-refresh", daemon=True)
        _thread.start()
    logger.info("[Wavelet Scheduler] Started")


def stop_wavelet_scheduler():
    _stop.set()
