"""数据集业务时间提取

从本地 Parquet 文件中提取 data_time（最新业务日期），
供 action 209（REPORT_DATASET_STATUS）上报使用。

snapshot_history 类型：从 trade_date 列取 max()
realtime_quotes 类型：取当日日期
"""

from datetime import date
from pathlib import Path

import polars as pl

from ldnode import logger
from .files import (
    CB_DATA, CB_QUOTATION,
    ETF_DATA, ETF_QUOTATION,
    FINANCE_DATA,
    INDEX_DATA,
    STK_DATA, STK_QUOTATION,
)
from .schemas.models import File

# 数据集元信息：(dataset_name, category, File)
# 仅上报影响回测上限或告警的数据集，维度表（TRADE_DAYS）和盘前数据不上报
DATASET_REGISTRY: list[tuple[str, str, File]] = [
    ("STK_DATA",       "snapshot_history", STK_DATA),
    ("CB_DATA",        "snapshot_history", CB_DATA),
    ("ETF_DATA",       "snapshot_history", ETF_DATA),
    ("INDEX_DATA",     "snapshot_history", INDEX_DATA),
    ("STK_QUOTATION",  "realtime_quotes",  STK_QUOTATION),
    ("CB_QUOTATION",   "realtime_quotes",  CB_QUOTATION),
    ("ETF_QUOTATION",  "realtime_quotes",  ETF_QUOTATION),
    ("FINANCE",        "snapshot_history", FINANCE_DATA),
]


def extract_data_time(file: File, data_dir: Path) -> str | None:
    """从本地 Parquet 文件提取最新业务日期

    Args:
        file: 数据集文件定义
        data_dir: 本地数据根目录

    Returns:
        YYYY-MM-DD 格式字符串，文件不存在或提取失败返回 None
    """
    local_path = file.get_local_path(data_dir)
    if not local_path.exists():
        return None
    try:
        result = (
            pl.scan_parquet(local_path)
            .select(pl.col("trade_date").max())
            .collect()
            .item()
        )
        if result is None:
            return None
        # trade_date 可能是 date 对象或字符串
        if isinstance(result, date):
            return result.strftime("%Y-%m-%d")
        return str(result)[:10]  # 取 YYYY-MM-DD 部分
    except Exception as e:
        logger.loader.warning(f"提取 data_time 失败 ({file.key}): {e}")
        return None


def extract_realtime_data_time(file: File, data_dir: Path) -> str | None:
    """从实时行情 Parquet 提取精确到秒的 data_time

    组合 trade_date(或 date) + time 列的最大值，格式 YYYY-MM-DDTHH:MM:SS。
    文件不存在或提取失败返回 None（触发 sync_timeout 预警）。
    """
    local_path = file.get_local_path(data_dir)
    if not local_path.exists():
        return None
    try:
        # stk/etf: trade_date(Date) + time(Time)
        # cb: date(Datetime) + time(String)
        lf = pl.scan_parquet(local_path)
        cols = lf.collect_schema().names()
        if "trade_date" in cols and "time" in cols:
            row = (
                lf.select(
                    pl.col("trade_date").max().alias("d"),
                    pl.col("time").max().alias("t"),
                ).collect()
            )
            d = row["d"].item()
            t = row["t"].item()
            if d is None:
                return None
            if t is None:
                return d.strftime("%Y-%m-%dT00:00:00")
            # time 可能是 datetime.time 或 str
            if isinstance(t, str):
                return f"{d.strftime('%Y-%m-%d')}T{t}"
            return f"{d.strftime('%Y-%m-%d')}T{t.strftime('%H:%M:%S')}"
        elif "date" in cols and "time" in cols:
            row = (
                lf.select(
                    pl.col("date").max().alias("d"),
                    pl.col("time").max().alias("t"),
                ).collect()
            )
            d = row["d"].item()
            t = row["t"].item()
            if d is None:
                return None
            d_str = d.strftime("%Y-%m-%d") if hasattr(d, "strftime") else str(d)[:10]
            t_str = t if isinstance(t, str) else (t.strftime("%H:%M:%S") if t else "00:00:00")
            return f"{d_str}T{t_str}"
        else:
            return None
    except Exception as e:
        logger.loader.warning(f"提取 realtime data_time 失败 ({file.key}): {e}")
        return None


def is_snapshot_history(category: str) -> bool:
    """判断是否为历史截面类型"""
    return category == "snapshot_history"
