# -*- coding: utf-8 -*-
"""
按 order_settle_id（结算单）聚合，找出多台桌、多助教的复杂订单。

order_settle_id 是一次结算的唯一标识，一次结算可包含：
  - 多个台桌使用记录（不同 order_trade_no）
  - 多个助教服务记录
  - 多条台费折扣
  - 多条团购核销
  - 多笔支付/退款
"""
from __future__ import annotations

import json
import sys
from collections import defaultdict
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent))
from _env_paths import get_output_path


def _extract_records(filepath: Path) -> list[dict]:
    try:
        data = json.loads(filepath.read_text(encoding="utf-8"))
    except Exception:
        return []
    items = []
    for page in data.get("pages", []):
        resp_data = page.get("response", {}).get("data", {})
        for v in resp_data.values():
            if isinstance(v, list):
                items.extend(v)
    return items


def _extract_archive_records(filepath: Path) -> list[dict]:
    try:
        data = json.loads(filepath.read_text(encoding="utf-8"))
    except Exception:
        return []
    payload = data.get("data", [])
    return payload if isinstance(payload, list) else []


def load_all(json_root: Path, dir_prefix: str, file_stem: str) -> list[dict]:
    records = []
    for task_dir in sorted(json_root.iterdir()):
        if not task_dir.is_dir():
            continue
        if task_dir.name.startswith(dir_prefix) or task_dir.name == "ODS_JSON_ARCHIVE":
            for run_dir in task_dir.iterdir():
                if not run_dir.is_dir():
                    continue
                for f in run_dir.iterdir():
                    if f.stem.startswith(file_stem) and f.suffix == ".json":
                        if task_dir.name == "ODS_JSON_ARCHIVE":
                            records.extend(_extract_archive_records(f))
                        else:
                            records.extend(_extract_records(f))
    return records


def dedup(records: list[dict]) -> list[dict]:
    """按 id 去重，保留首次出现的记录。"""
    seen = set()
    out = []
    for r in records:
        rid = r.get("id")
        if rid and rid in seen:
            continue
        if rid:
            seen.add(rid)
        out.append(r)
    return out


def main():
    json_root = get_output_path("EXPORT_ROOT")

    # 加载台桌使用记录
    table_use = dedup(load_all(json_root, "ODS_TABLE_USE", "table_fee_transactions"))
    # 加载助教服务记录
    assistant = dedup(load_all(json_root, "ODS_ASSISTANT_LEDGER", "assistant_service_records"))
    # 加载台费折扣
    discount = dedup(load_all(json_root, "ODS_TABLE_FEE_DISCOUNT", "table_fee_discount_records"))
    # 加载团购核销
    groupbuy = dedup(load_all(json_root, "ODS_GROUP_BUY_REDEMPTION", "group_buy_redemption_records"))
    # 加载支付
    payments = dedup(load_all(json_root, "ODS_PAYMENT", "payment_transactions"))
    # 加载退款
    refunds = dedup(load_all(json_root, "ODS_REFUND", "refund_transactions"))

    # --- 按 order_settle_id 聚合 ---
    # settle_id → 各维度详情
    settle_data: dict[int, dict] = defaultdict(lambda: {
        "台桌": [],        # 不同 order_trade_no 的台桌名
        "台桌记录": [],
        "助教": [],        # 不同助教名
        "助教记录": [],
        "台费折扣": 0,
        "团购核销": 0,
        "支付": 0,
        "退款": 0,
        "create_time": "",
        "trade_nos": set(),
    })

    # 台桌使用 → 按 order_settle_id 聚合
    for r in table_use:
        sid = r.get("order_settle_id")
        if not sid or sid == 0:
            continue
        d = settle_data[sid]
        tno = r.get("order_trade_no", 0)
        tname = r.get("ledger_name", "?")
        if tno not in d["trade_nos"]:
            d["trade_nos"].add(tno)
            d["台桌"].append(tname)
            d["台桌记录"].append(r)
        ct = r.get("create_time", "")
        if ct and (not d["create_time"] or ct < d["create_time"]):
            d["create_time"] = ct

    # 助教服务 → 按 order_settle_id 聚合
    for r in assistant:
        sid = r.get("order_settle_id")
        if not sid or sid == 0:
            continue
        d = settle_data[sid]
        aname = r.get("assistantName", r.get("ledger_name", "?"))
        d["助教"].append(aname)
        d["助教记录"].append(r)

    # 台费折扣
    for r in discount:
        sid = r.get("order_settle_id")
        if sid and sid != 0:
            settle_data[sid]["台费折扣"] += 1

    # 团购核销
    for r in groupbuy:
        sid = r.get("order_settle_id")
        if sid and sid != 0:
            settle_data[sid]["团购核销"] += 1

    # 支付（relate_id = order_settle_id）
    for r in payments:
        rid = r.get("relate_id")
        if rid and rid in settle_data:
            settle_data[rid]["支付"] += 1

    # 退款
    for r in refunds:
        rid = r.get("relate_id")
        if rid and rid in settle_data:
            settle_data[rid]["退款"] += 1

    # --- 筛选：多台桌 或 多助教 的结算单 ---
    multi_table = []
    multi_assistant = []
    for sid, d in settle_data.items():
        n_tables = len(d["台桌"])
        n_assistants = len(set(d["助教"]))  # 去重助教名
        if n_tables >= 2:
            multi_table.append((sid, d, n_tables, n_assistants))
        if n_assistants >= 2:
            multi_assistant.append((sid, d, n_tables, n_assistants))

    multi_table.sort(key=lambda x: x[2], reverse=True)
    multi_assistant.sort(key=lambda x: x[3], reverse=True)

    # --- 输出：多台桌 ---
    print("=" * 100)
    print(f"  多台桌结算单 Top 10（共 {len(multi_table)} 个结算单含 ≥2 台桌）")
    print("=" * 100)
    for i, (sid, d, nt, na) in enumerate(multi_table[:10], 1):
        unique_assistants = sorted(set(d["助教"]))
        print(f"\n{'─' * 80}")
        print(f"  #{i}  order_settle_id = {sid}")
        print(f"       创建时间: {d['create_time']}")
        print(f"       台桌数: {nt}  |  助教数: {len(unique_assistants)}  |  台费折扣: {d['台费折扣']}  |  团购核销: {d['团购核销']}  |  支付: {d['支付']}  |  退款: {d['退款']}")
        print(f"       台桌列表: {', '.join(d['台桌'])}")
        if unique_assistants:
            print(f"       助教列表: {', '.join(unique_assistants)}")
        # 显示各台桌的金额
        for r in d["台桌记录"]:
            amt = r.get("ledger_amount", 0)
            secs = r.get("real_table_use_seconds", r.get("ledger_count", 0))
            hours = secs / 3600 if secs else 0
            tno = r.get("order_trade_no", "?")
            print(f"         → {r.get('ledger_name','?'):8s}  金额={amt:>8.2f}  时长={hours:.1f}h  trade_no={tno}")

    # --- 输出：多助教 ---
    print(f"\n\n{'=' * 100}")
    print(f"  多助教结算单 Top 10（共 {len(multi_assistant)} 个结算单含 ≥2 位助教）")
    print("=" * 100)
    for i, (sid, d, nt, na) in enumerate(multi_assistant[:10], 1):
        unique_assistants = sorted(set(d["助教"]))
        print(f"\n{'─' * 80}")
        print(f"  #{i}  order_settle_id = {sid}")
        print(f"       创建时间: {d['create_time']}")
        print(f"       台桌数: {nt}  |  助教数: {len(unique_assistants)}  |  台费折扣: {d['台费折扣']}  |  团购核销: {d['团购核销']}  |  支付: {d['支付']}  |  退款: {d['退款']}")
        print(f"       台桌列表: {', '.join(d['台桌'])}")
        print(f"       助教列表: {', '.join(unique_assistants)}")
        # 显示各助教的服务详情
        for r in d["助教记录"]:
            aname = r.get("assistantName", r.get("ledger_name", "?"))
            skill = r.get("skillName", "?")
            amt = r.get("ledger_amount", 0)
            tname = r.get("tableName", "?")
            print(f"         → 助教={aname:6s}  技能={skill:6s}  台桌={tname:6s}  金额={amt:>8.2f}")

    # --- 输出：同时多台桌+多助教 ---
    both = [(sid, d, nt, na) for sid, d, nt, na in multi_table if na >= 2]
    both.sort(key=lambda x: x[2] + x[3], reverse=True)
    if both:
        print(f"\n\n{'=' * 100}")
        print(f"  同时多台桌+多助教（共 {len(both)} 个）")
        print("=" * 100)
        for i, (sid, d, nt, na) in enumerate(both[:10], 1):
            unique_assistants = sorted(set(d["助教"]))
            print(f"\n{'─' * 80}")
            print(f"  #{i}  order_settle_id = {sid}")
            print(f"       创建时间: {d['create_time']}")
            print(f"       台桌数: {nt}  |  助教数: {len(unique_assistants)}  |  台费折扣: {d['台费折扣']}  |  团购核销: {d['团购核销']}  |  支付: {d['支付']}  |  退款: {d['退款']}")
            print(f"       台桌: {', '.join(d['台桌'])}")
            print(f"       助教: {', '.join(unique_assistants)}")

    print(f"\n{'─' * 80}")
    print(f"\n统计摘要:")
    print(f"  总结算单数: {len(settle_data)}")
    print(f"  含 ≥2 台桌: {len(multi_table)}")
    print(f"  含 ≥2 助教: {len(multi_assistant)}")
    print(f"  同时多台桌+多助教: {len(both)}")


if __name__ == "__main__":
    main()
