"""Background scheduler for automated tasks.

Uses APScheduler to run periodic jobs:
1. Outcome evaluation — check past signals against actual prices
2. OHLCV data sync — keep price data up-to-date
3. Signal auto-scan — optionally re-scan signals on schedule

Scheduler runs inside the Flask app process (BackgroundScheduler)
so it has full access to the app context and database.
"""
from __future__ import annotations

import logging
import os

logger = logging.getLogger(__name__)

_scheduler = None


def init_scheduler(app):
    """Initialize and start the background scheduler.

    Only starts in production (or when SCHEDULER_ENABLED=1).
    Skips in debug/reloader child process to avoid duplicate jobs.
    """
    # Don't start scheduler in dev reloader child or when disabled
    if app.debug and os.environ.get('WERKZEUG_RUN_MAIN') != 'true':
        return
    if os.getenv('SCHEDULER_ENABLED', '0') != '1' and not app.config.get('SCHEDULER_ENABLED'):
        logger.info('Scheduler disabled (set SCHEDULER_ENABLED=1 to enable)')
        return

    try:
        from apscheduler.schedulers.background import BackgroundScheduler
        from apscheduler.triggers.cron import CronTrigger
        from apscheduler.triggers.interval import IntervalTrigger
    except ImportError:
        logger.warning('APScheduler not installed — scheduler disabled. Run: pip install apscheduler')
        return

    global _scheduler
    _scheduler = BackgroundScheduler(daemon=True)

    # ──────────────────────────────────────────────────────────
    # Job 1: Outcome evaluation — every 6 hours
    # ──────────────────────────────────────────────────────────
    @_scheduler.scheduled_job(IntervalTrigger(hours=6), id='outcome_eval', replace_existing=True)
    def job_outcome_eval():
        with app.app_context():
            try:
                from app.services.outcome_tracker import OutcomeTracker
                tracker = OutcomeTracker()
                results = tracker.update_all_pending(limit=500)
                if results['evaluated'] > 0:
                    logger.info(
                        f"[scheduler] Outcome eval: {results['evaluated']} "
                        f"(W:{results['win']} L:{results['loss']} BE:{results['breakeven']})"
                    )
            except Exception as e:
                logger.error(f'[scheduler] Outcome eval error: {e}')

    # ──────────────────────────────────────────────────────────
    # Job 2: OHLCV data sync — every 4 hours (configurable)
    # ──────────────────────────────────────────────────────────
    sync_interval = int(os.getenv('SYNC_INTERVAL_HOURS', '4'))

    @_scheduler.scheduled_job(IntervalTrigger(hours=sync_interval), id='ohlcv_sync', replace_existing=True)
    def job_ohlcv_sync():
        with app.app_context():
            try:
                from app.services.data_sync.sync_manager import SyncManager
                sm = SyncManager()
                # Sync default timeframes for current asset mode
                result = sm.sync_all()
                logger.info(f'[scheduler] OHLCV sync complete: {result}')
            except Exception as e:
                logger.error(f'[scheduler] OHLCV sync error: {e}')

    # ──────────────────────────────────────────────────────────
    # Job 3: Signal auto-scan — daily at 07:00 WIB (00:00 UTC)
    # ──────────────────────────────────────────────────────────
    if os.getenv('AUTO_SIGNAL_SCAN', '0') == '1':
        @_scheduler.scheduled_job(CronTrigger(hour=0, minute=0), id='signal_scan', replace_existing=True)
        def job_signal_scan():
            with app.app_context():
                try:
                    from app.services.scorer import ScoringService
                    scorer = ScoringService()
                    for event in scorer.scan_signals_sse('1D'):
                        if event.get('type') == 'done':
                            logger.info(f"[scheduler] Signal scan: {event.get('message', 'done')}")
                except Exception as e:
                    logger.error(f'[scheduler] Signal scan error: {e}')

        logger.info('[scheduler] Auto signal scan enabled (daily 07:00 WIB)')

    _scheduler.start()
    logger.info(f'[scheduler] Started — {len(_scheduler.get_jobs())} jobs registered')


def get_scheduler_status() -> dict:
    """Return scheduler status and job info for the admin dashboard."""
    if _scheduler is None:
        return {'enabled': False, 'jobs': []}

    jobs = []
    for job in _scheduler.get_jobs():
        jobs.append({
            'id': job.id,
            'name': job.name or job.id,
            'next_run': job.next_run_time.isoformat() if job.next_run_time else None,
            'trigger': str(job.trigger),
        })

    return {
        'enabled': True,
        'running': _scheduler.running,
        'jobs': jobs,
    }
