"""Cycle Frequency Scan — hitung frekuensi cycle adaptive S/R semua coin.

Menggunakan OscillationAnalyzer.scan_cycle_frequency_sse() yang menghitung
berapa kali harga menyelesaikan cycle (support→resistance→support) per hari,
menggunakan adaptive S/R dari multi-timeframe data.

Ini adalah versi CLI dari tombol "Cycle Frequency Scan" di halaman /admin/ml.

Modes:
  - agresif  : lookback pendek, range ketat → lebih banyak cycle terdeteksi
  - moderate : balance antara sensitivity dan noise filtering
  - santai   : lookback panjang, range lebar → cycle yang lebih pasti

Usage:
    # Scan semua coin (mode agresif)
    python3 scripts/scan_cycle_frequency.py

    # Mode moderate
    python3 scripts/scan_cycle_frequency.py --mode moderate

    # Mode santai + quiet
    python3 scripts/scan_cycle_frequency.py --mode santai --quiet

Cron example:
    # Scan cycle setiap 6 jam
    0 */6 * * * cd /path && .venv/bin/python scripts/scan_cycle_frequency.py --quiet >> logs/scan_cycles.log 2>&1
"""
from __future__ import annotations

import argparse
import os
import sys
import time

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from dotenv import load_dotenv
load_dotenv()


def main():
    parser = argparse.ArgumentParser(
        description='Scan cycle frequency adaptive S/R untuk semua coin',
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    parser.add_argument('--mode', default='agresif',
                        choices=['agresif', 'moderate', 'santai'],
                        help='Cycle detection mode (default: agresif)')
    parser.add_argument('--asset-type', default='stock',
                        choices=['crypto', 'stock', 'stock_us'],
                        help='Asset type (default: stock)')
    parser.add_argument('--quiet', '-q', action='store_true',
                        help='Quiet — hanya summary')
    args = parser.parse_args()

    from app import create_app
    app = create_app()

    with app.app_context(), app.test_request_context():
        from flask import session
        session['asset_mode'] = args.asset_type
        from app.helpers.market_db import switch_market_schema
        switch_market_schema(args.asset_type)
        from app.services.oscillation import OscillationAnalyzer

        analyzer = OscillationAnalyzer()
        scored = 0
        skipped = 0
        failed = 0
        total = 0
        start_time = time.time()

        if not args.quiet:
            print(f'\n🔄  Cycle Frequency Scan — mode: {args.mode}')
            print(f'{"─" * 70}')

        for event in analyzer.scan_cycle_frequency_sse(args.mode):
            evt_type = event.get('type')

            if evt_type == 'start':
                total = event['total']
                if not args.quiet:
                    print(f'  {event["message"]}')
                    print()

            elif evt_type == 'scored':
                scored += 1
                if not args.quiet:
                    sym = event.get('symbol', '?')
                    cpd = event.get('cycles_per_day', 0)
                    pct = event['processed'] / event['total'] * 100
                    cpd_icon = '🟢' if cpd >= 1.0 else ('🟡' if cpd >= 0.3 else '⚪')
                    print(f'  {cpd_icon} [{event["processed"]}/{event["total"]}] '
                          f'{sym:<10} cycles/day={cpd:<6.2f}  ({pct:.0f}%)')

            elif evt_type == 'skip':
                skipped += 1
                if not args.quiet:
                    sym = event.get('symbol', event.get('coin_id', '?'))
                    print(f'  ⊘  [{event["processed"]}/{event["total"]}] '
                          f'{sym:<10} — {event.get("reason", "skipped")}')

            elif evt_type == 'error':
                failed += 1
                if not args.quiet:
                    sym = event.get('symbol', event.get('coin_id', '?'))
                    print(f'  ✗  [{event["processed"]}/{event["total"]}] '
                          f'{sym:<10} — {event.get("error", "error")}')

            elif evt_type == 'done':
                pass  # Summary printed below

        elapsed = time.time() - start_time
        mins = int(elapsed // 60)
        secs = int(elapsed % 60)

        print(f'\n{"═" * 70}')
        print(f'🔄  Cycle Frequency Scan Complete — {mins}m {secs}s')
        print(f'    Mode: {args.mode}  |  Updated: {scored}  |  '
              f'Skipped: {skipped}  |  Failed: {failed}  |  Total: {total}')
        print(f'{"═" * 70}')

        sys.exit(1 if failed > total * 0.5 else 0)


if __name__ == '__main__':
    main()
