#!/usr/bin/env python3
"""多周期缓存刷新脚本 — 在开盘前预填充K线数据

为所有持仓+自选股预先拉取日/周/月K线，写入 multi_tf_cache.json，
这样收盘后全量重评(regenerate_all)运行时K线数据已有缓存，无需逐个拉取。

运行时间：每天9:00（开盘前），no_agent模式。
无输出 = 成功（避免每天收到无意义消息）。
"""

import sys
import os
import json
from datetime import datetime

# 确保能找到 web-dashboard 模块
sys.path.insert(0, "/home/hmo/web-dashboard")

# 控制台UTC日志
def log(msg):
    ts = datetime.utcnow().strftime("%H:%M:%S")
    print(f"[{ts}] {msg}", file=sys.stderr)

def main():
    from mofin_db import get_conn

    # 收集所有股票代码
    codes = []
    seen = set()

    conn = get_conn()
    try:
        rows = conn.execute("SELECT code FROM holdings WHERE is_active=1").fetchall()
        for r in rows:
            code = r["code"]
            if code:
                codes.append(("portfolio", code))
                seen.add(code)

        rows = conn.execute("SELECT code FROM watchlist_stocks WHERE is_active=1").fetchall()
        for r in rows:
            code = r["code"]
            if code and code not in seen:
                codes.append(("watchlist", code))
                seen.add(code)
    finally:
        conn.close()
    
    # 加入指数代码（用于多周期趋势研判）
    INDEXES = {
        "sh000001": "上证指数", "sz399001": "深证成指",
        "sz399006": "创业板指", "sh000688": "科创50",
        "hkHSI": "恒生指数", "hkHSTECH": "恒生科技",
    }
    for idx_code in INDEXES:
        if idx_code not in seen:
            codes.append(("index", idx_code))
            seen.add(idx_code)

    log(f"Pre-populating multi-timeframe cache for {len(codes)} stocks...")

    # 从 DB 读取现有缓存（替代 multi_tf_cache.json）
    from multi_timeframe import _load_mtf_cache, _save_mtf_cache
    existing = _load_mtf_cache()

    import time
    from multi_timeframe import full_multi_tf_analysis

    cached = 0
    fetched = 0
    errors = 0

    for source, code in codes:
        cached_entry = existing.get(code, {})
        updated_at = cached_entry.get("updated_at", 0)
        now = time.time()

        # 检查缓存是否新鲜：日K 1小时内，周/月K 1天内
        has_daily = bool(cached_entry.get("daily"))
        has_weekly = bool(cached_entry.get("weekly"))
        has_monthly = bool(cached_entry.get("monthly"))
        cache_fresh = (updated_at > 0 and (now - updated_at) < 3600)

        if has_daily and has_weekly and has_monthly and cache_fresh:
            cached += 1
            continue

        try:
            r = full_multi_tf_analysis(code)
            if any(k in r for k in ["daily", "weekly", "monthly"]):
                fetched += 1
                log(f"  OK {code} ({source})")
            else:
                errors += 1
                log(f"  EMPTY {code} ({source})")
        except Exception as e:
            errors += 1
            log(f"  FAIL {code} ({source}): {e}")

    log(f"Done: {cached} cached, {fetched} fetched, {errors} errors")

if __name__ == "__main__":
    main()
