# -*- coding: utf-8 -*-
"""重新提交上次执行中失败的 31 个任务。

先用 refresh_token 刷新 access_token，再提交执行并轮询等待完成。
"""
from __future__ import annotations

import json
import sys
import time
from pathlib import Path

import requests

TOKEN_FILE = Path(__file__).parent / ".monitor_token"
BASE = "http://localhost:8000"

# refresh_token（7 天有效）
REFRESH_TOKEN = (
    "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
    "eyJzdWIiOiIxIiwic2l0ZV9pZCI6Mjc5MDY4NTQxNTQ0MzI2OSwidHlwZSI6InJlZnJlc2giLCJleHAiOjE3NzIyNjM0NjN9."
    "XYoda5lfxNtTSAGWoLlYhS9cA-hTK9iqK0SqUyn2KV4"
)


def refresh_access_token() -> str:
    """用 refresh_token 换取新的 access_token。"""
    resp = requests.post(
        f"{BASE}/api/auth/refresh",
        json={"refresh_token": REFRESH_TOKEN},
        timeout=10,
    )
    if resp.status_code != 200:
        print(f"❌ 刷新 token 失败: {resp.status_code} {resp.text}")
        sys.exit(1)
    data = resp.json()
    token = data["access_token"]
    # 缓存到文件
    TOKEN_FILE.write_text(token, encoding="utf-8")
    print(f"✅ access_token 已刷新并缓存")
    return token


# ── 刷新 token ──
TOKEN = refresh_access_token()
HEADERS = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}

# 上次失败的 31 个任务
FAILED_TASKS = [
    "DWS_ASSISTANT_DAILY",
    "DWS_ASSISTANT_MONTHLY",
    "DWS_ASSISTANT_CUSTOMER",
    "DWS_ASSISTANT_SALARY",
    "DWS_ASSISTANT_FINANCE",
    "ODS_SETTLEMENT_RECORDS",
    "ODS_PAYMENT",
    "ODS_REFUND",
    "DWS_BUILD_ORDER_SUMMARY",
    "DWS_MEMBER_CONSUMPTION",
    "DWS_MEMBER_VISIT",
    "ODS_GOODS_CATEGORY",
    "ODS_STORE_GOODS",
    "ODS_STORE_GOODS_SALES",
    "ODS_TENANT_GOODS",
    "ODS_PLATFORM_COUPON",
    "ODS_GROUP_PACKAGE",
    "ODS_GROUP_BUY_REDEMPTION",
    "ODS_INVENTORY_STOCK",
    "ODS_INVENTORY_CHANGE",
    "DWS_GOODS_STOCK_DAILY",
    "DWS_GOODS_STOCK_WEEKLY",
    "DWS_GOODS_STOCK_MONTHLY",
    "DWS_FINANCE_DAILY",
    "DWS_FINANCE_RECHARGE",
    "DWS_FINANCE_INCOME_STRUCTURE",
    "DWS_FINANCE_DISCOUNT_DETAIL",
    "DWS_WINBACK_INDEX",
    "DWS_NEWCONV_INDEX",
    "DWS_RELATION_INDEX",
    "DWD_LOAD_FROM_ODS",
]

config = {
    "tasks": FAILED_TASKS,
    "flow": "api_full",
    "processing_mode": "full_window",
    "window_mode": "custom",
    "window_start": "2025-11-01",
    "window_end": "2026-02-20",
    "window_split": "month",
    "window_split_days": 30,
    "force_full": True,
    "dry_run": False,
    "lookback_hours": 24,
    "overlap_seconds": 600,
}

print(f"📤 提交 {len(FAILED_TASKS)} 个失败任务重新执行...")
print(f"   flow=api_full, mode=full_window, 2025-11-01~2026-02-20, 30天切分, force-full")

resp = requests.post(f"{BASE}/api/execution/run", headers=HEADERS, json=config, timeout=30)
if resp.status_code != 200:
    print(f"❌ 提交失败: {resp.status_code} {resp.text}")
    sys.exit(1)

data = resp.json()
execution_id = data["execution_id"]
print(f"✅ 已提交，execution_id={execution_id}")
print(f"   轮询等待完成...")

poll_interval = 20
max_wait = 1800
elapsed = 0

while elapsed < max_wait:
    time.sleep(poll_interval)
    elapsed += poll_interval
    mm, ss = divmod(elapsed, 60)

    try:
        hist_resp = requests.get(
            f"{BASE}/api/execution/history?limit=5",
            headers=HEADERS,
            timeout=15,
        )
        if hist_resp.status_code == 401:
            print(f"   [{mm}m{ss}s] token 过期，刷新中...")
            TOKEN = refresh_access_token()
            HEADERS["Authorization"] = f"Bearer {TOKEN}"
            continue
        if hist_resp.status_code != 200:
            print(f"   [{mm}m{ss}s] 查询历史失败: {hist_resp.status_code}")
            continue

        history = hist_resp.json()
        target = next((h for h in history if h["id"] == execution_id), None)
        if target is None:
            print(f"   [{mm}m{ss}s] 执行记录尚未出现...")
            continue

        status = target.get("status", "unknown")
        duration_ms = target.get("duration_ms")
        duration_str = f"{duration_ms / 1000:.1f}s" if duration_ms else "—"

        if status in ("success", "failed", "cancelled"):
            print(f"\n🏁 执行完成: status={status}, 耗时={duration_str}, exit_code={target.get('exit_code')}")

            # 获取日志摘要
            log_resp = requests.get(
                f"{BASE}/api/execution/{execution_id}/logs",
                headers=HEADERS,
                timeout=30,
            )
            if log_resp.status_code == 200:
                log_data = log_resp.json()
                output = log_data.get("output_log", "") or ""
                lines = output.strip().split("\n")
                print(f"\n--- 日志末尾 60 行 ---")
                for line in lines[-60:]:
                    print(line)
            break
        else:
            print(f"   [{mm}m{ss}s] status={status}")

    except Exception as e:
        print(f"   [{mm}m{ss}s] 轮询异常: {e}")

else:
    print(f"\n⏰ 超时（{max_wait}s），请手动检查 execution_id={execution_id}")
