#!/usr/bin/env python3
"""Generate business-style XMind (Zen/2020+) from playbook + behavior rules."""
from __future__ import annotations

import json
import uuid
import zipfile
from pathlib import Path
from typing import Any, Optional

OUT = Path(__file__).resolve().parents[1] / "docs" / "交易执行手册与行为准则.xmind"

# 商务配色：深蓝主调 + 灰蓝辅色 + 强调色
C_ROOT = "#0F2942"
C_L1 = "#1B4F72"
C_L2 = "#2E86AB"
C_PASS = "#1E8449"
C_FAIL = "#922B21"
C_WARN = "#B9770E"
C_MUTED = "#566573"
C_TEXT = "#FFFFFF"
C_TEXT_DARK = "#1C2833"


def tid() -> str:
    return uuid.uuid4().hex[:26]


def style(
    *,
    fill: Optional[str] = None,
    color: Optional[str] = None,
    font_size: str = "12pt",
    bold: bool = False,
    shape: str = "org.xmind.topicShape.roundedRect",
    line: Optional[str] = None,
) -> dict[str, Any]:
    props: dict[str, str] = {
        "shape-class": shape,
        "fo:font-family": "Microsoft YaHei",
        "fo:font-size": font_size,
        "fo:font-weight": "bold" if bold else "normal",
        "border-line-width": "0pt",
        "line-width": "1.5pt",
        "line-class": "org.xmind.branchConnection.roundedelbow",
    }
    if fill:
        props["svg:fill"] = fill
    if color:
        props["fo:color"] = color
    if line:
        props["line-color"] = line
    return {"id": tid(), "properties": props}


def topic(
    title: str,
    children: list | None = None,
    *,
    markers: list[str] | None = None,
    labels: list[str] | None = None,
    notes: str | None = None,
    fill: Optional[str] = None,
    color: Optional[str] = None,
    font_size: str = "12pt",
    bold: bool = False,
    line: Optional[str] = None,
) -> dict:
    node: dict[str, Any] = {
        "id": tid(),
        "class": "topic",
        "title": title,
        "style": style(
            fill=fill, color=color, font_size=font_size, bold=bold, line=line
        ),
    }
    if markers:
        node["markers"] = [{"markerId": m} for m in markers]
    if labels:
        node["labels"] = labels
    if notes:
        node["notes"] = {"plain": {"content": notes}}
    if children:
        node["children"] = {"attached": children}
    return node


def t1(title: str, children: list, markers: list[str], label: str) -> dict:
    return topic(
        title,
        children,
        markers=markers,
        labels=[label],
        fill=C_L1,
        color=C_TEXT,
        font_size="16pt",
        bold=True,
        line=C_L1,
    )


def t2(title: str, children: list | None = None, markers: list[str] | None = None) -> dict:
    return topic(
        title,
        children,
        markers=markers or ["flag-dark-blue"],
        fill=C_L2,
        color=C_TEXT,
        font_size="13pt",
        bold=True,
        line=C_L2,
    )


def leaf(
    title: str,
    *,
    markers: list[str] | None = None,
    fill: Optional[str] = None,
    color: Optional[str] = C_TEXT_DARK,
) -> dict:
    return topic(
        title,
        markers=markers or ["symbol-right"],
        fill=fill or "#EBF5FB",
        color=color,
        font_size="11pt",
        line="#AED6F1",
    )


def ok(title: str) -> dict:
    return leaf(title, markers=["other-yes", "symbol-right"], fill="#E8F8F5", color=C_PASS)


def no(title: str) -> dict:
    return leaf(title, markers=["other-no", "flag-gray"], fill="#FDEDEC", color=C_FAIL)


def warn(title: str) -> dict:
    return leaf(title, markers=["symbol-info"], fill="#FEF9E7", color=C_WARN)


def build_content() -> list:
    root = topic(
        "交易执行体系\n手册 v2 · 开单三检",
        [
            t1(
                "① 设计理念",
                [
                    t2(
                        "核心主张",
                        [
                            leaf("少而精，珍惜机会，样本干净", markers=["star-dark-blue"]),
                            leaf("不保证收益；过程可控，结果随缘", markers=["symbol-info"]),
                            leaf("过滤比频率重要；日更不是目标", markers=["symbol-info"]),
                            leaf("看不懂不做；不为开单找理由", markers=["symbol-info"]),
                            warn("丢掉对冲：无「有保护就能多做」幻觉"),
                        ],
                        markers=["other-lightbulb"],
                    ),
                    t2(
                        "工具边界",
                        [
                            leaf("OKX 期权：方向单（虚值等）", markers=["flag-blue"]),
                            leaf("Gate 合约：结构清楚时的波段", markers=["flag-dark-blue"]),
                            leaf("同一时段尽量只让一边说话", markers=["symbol-equality"]),
                            no("不做期期对冲 / 偏置壳"),
                        ],
                        markers=["symbol-info"],
                    ),
                    t2(
                        "文档分工",
                        [
                            leaf("行为准则：能不能动手（防火墙）", markers=["other-lock"]),
                            leaf("执行手册：怎么做单（玩法/仓位/离场）", markers=["other-note"]),
                        ],
                        markers=["other-businesscard"],
                    ),
                ],
                markers=["priority-1", "other-lightbulb"],
                label="理念",
            ),
            t1(
                "② 资金要求",
                [
                    t2(
                        "总盘约 800U",
                        [
                            leaf("单笔约 1.25% 量级", markers=["symbol-info"]),
                            leaf("全错一天约 2.5% 量级——防守优先", markers=["symbol-info"]),
                        ],
                        markers=["other-businesscard"],
                    ),
                    t2(
                        "单笔期权",
                        [
                            leaf("约 10U 权利金预算", markers=["priority-1"]),
                            leaf("一次只持有一个期权仓位", markers=["symbol-info"]),
                            leaf("打满 = min(余额, 单笔预算)", markers=["symbol-equality"]),
                        ],
                        markers=["flag-blue"],
                    ),
                    t2(
                        "Gate 合约",
                        [
                            leaf("日内保证金约 50U · 约 10 倍", markers=["symbol-info"]),
                            leaf("止损一般约 5U", markers=["symbol-info"]),
                            leaf("单笔最大亏损不超过约 10U", markers=["flag-gray"]),
                            leaf("有单才用保证金，无单为 0", markers=["task-done"]),
                        ],
                        markers=["flag-dark-blue"],
                    ),
                    t2(
                        "日损失心理框",
                        [
                            warn("都错：合计大约 ≤20U"),
                            ok("都对：期望可到 40U+（理想，非每日目标）"),
                            no("不为「好像有保护」放大仓位"),
                            warn("尽量少同向双开；双开按合计最坏约 20U"),
                        ],
                        markers=["symbol-info"],
                    ),
                ],
                markers=["priority-2", "other-businesscard"],
                label="资金",
            ),
            t1(
                "③ 操盘思路",
                [
                    t2(
                        "行为准则 · 开单三检",
                        [
                            topic(
                                "一句话防火墙",
                                [
                                    leaf("信号够不够清晰？", markers=["symbol-question"]),
                                    leaf("流程有没有跑通？", markers=["symbol-question"]),
                                    leaf("情绪是不是在证明自己？", markers=["symbol-question"]),
                                    no("三检不过 → 不开"),
                                ],
                                markers=["other-lock", "priority-1"],
                                fill="#154360",
                                color=C_TEXT,
                                font_size="12pt",
                                bold=True,
                                labels=["防火墙"],
                            ),
                            topic(
                                "总循环",
                                [
                                    leaf("信号判断 → 流程确认 → 情绪自检", markers=["arrow-right"]),
                                    leaf("全部通过 → 开仓", markers=["other-yes"]),
                                    leaf("等待系统结果（止盈/止损/到期）", markers=["other-clock"]),
                                    leaf("复盘整环 → 等待下一信号", markers=["arrow-refresh"]),
                                    no("任一步否决 → 空仓离开"),
                                ],
                                markers=["arrow-right"],
                                fill="#1A5276",
                                color=C_TEXT,
                                font_size="12pt",
                                bold=True,
                            ),
                            topic(
                                "开单前三秒停顿",
                                [
                                    leaf("核心信号是什么？", markers=["symbol-info"]),
                                    leaf("安全流程跑通了吗？", markers=["task-start"]),
                                    leaf("冷静执行，还是怕踏空/回本/证明自己？", markers=["symbol-info"]),
                                ],
                                markers=["other-clock"],
                                fill="#1A5276",
                                color=C_TEXT,
                                font_size="12pt",
                                bold=True,
                            ),
                            topic(
                                "检1 · 信号判断",
                                [
                                    ok("一句话说清唯一核心确认"),
                                    ok("点位/结构本身已够清楚"),
                                    no("说不清、靠宏观故事自圆"),
                                    no("「好像有戏」但确认模糊"),
                                    leaf("对照：1H→空间→结构→定损盈→工具", markers=["arrow-right"]),
                                ],
                                markers=["priority-1", "symbol-info"],
                                fill="#1A5276",
                                color=C_TEXT,
                                font_size="12pt",
                                bold=True,
                                labels=["Signal"],
                            ),
                            topic(
                                "检2 · 流程确认",
                                [
                                    ok("资金与当日额度符合"),
                                    ok("单笔/组合敞口在预算内"),
                                    no("资金或次数已触限"),
                                    no("单笔或日最坏超限 → 暂停"),
                                    no("「先开了再说」跳步"),
                                ],
                                markers=["priority-2", "task-start"],
                                fill="#1A5276",
                                color=C_TEXT,
                                font_size="12pt",
                                bold=True,
                                labels=["Process"],
                            ),
                            topic(
                                "检3 · 情绪自检",
                                [
                                    ok("符合系统 + 账户没问题 → 开"),
                                    ok("可接受空仓，旁观者视角"),
                                    no("怕踏空"),
                                    no("上回亏了要回本"),
                                    no("必须证明我是对的"),
                                    warn("红灯亮了，信号再好看也不开"),
                                ],
                                markers=["priority-3", "smiley-smile"],
                                fill="#1A5276",
                                color=C_TEXT,
                                font_size="12pt",
                                bold=True,
                                labels=["Emotion"],
                            ),
                            topic(
                                "复盘只记什么",
                                [
                                    leaf("信号：是否做了？核心写了什么？", markers=["other-note"]),
                                    leaf("流程：资金/敞口是否过关？有无跳步？", markers=["other-note"]),
                                    leaf("情绪：当时是哪一类心态？", markers=["other-note"]),
                                    warn("结果不推翻「三检是否完成」评分"),
                                ],
                                markers=["other-note"],
                                fill="#1A5276",
                                color=C_TEXT,
                                font_size="12pt",
                                bold=True,
                            ),
                        ],
                        markers=["other-lock", "flag-purple"],
                    ),
                    t2(
                        "开仓逻辑",
                        [
                            topic(
                                "主链条（强制）",
                                [
                                    leaf("1H 方向：明显 N 字；跟 1H 波段", markers=["priority-1"]),
                                    leaf("空间：空看支撑、多看阻力；≥约 2%", markers=["priority-2"]),
                                    leaf("结构：15m/5m；量级约 8h+（约 48×15m）", markers=["priority-3"]),
                                    leaf("定损盈：外沿/针尖；RR 须接受", markers=["priority-4"]),
                                    leaf("选工具：期权 或 合约（不对冲）", markers=["priority-5"]),
                                    no("任一步不过 → 空仓等待"),
                                ],
                                markers=["arrow-right", "symbol-info"],
                                fill="#154360",
                                color=C_TEXT,
                                font_size="12pt",
                                bold=True,
                                labels=["主链"],
                            ),
                            topic(
                                "结构形态参考",
                                [
                                    leaf("收敛", markers=["flag-blue"]),
                                    leaf("两段式回调", markers=["flag-dark-blue"]),
                                    leaf("箱体", markers=["flag-gray"]),
                                    leaf("假突破", markers=["flag-orange"]),
                                ],
                                markers=["symbol-image"],
                                fill="#1A5276",
                                color=C_TEXT,
                                font_size="12pt",
                                bold=True,
                            ),
                            topic(
                                "期权入场",
                                [
                                    ok("主链条全过；结构突破/假突破成立"),
                                    leaf("一天期方向单；空间够优先虚值", markers=["star-blue"]),
                                    leaf("默认先只开期权，不上合约", markers=["symbol-info"]),
                                    leaf("尽量 16:00 后开次日到期", markers=["other-clock"]),
                                    no("不做：期期对冲、偏置壳、为开而开"),
                                ],
                                markers=["flag-blue", "symbol-plus"],
                                fill="#1A5276",
                                color=C_TEXT,
                                font_size="12pt",
                                bold=True,
                                labels=["期权"],
                            ),
                            topic(
                                "合约入场（Gate）",
                                [
                                    ok("主链条过关；位置极明确"),
                                    leaf("想清进场：假突破 / 结构突破", markers=["symbol-info"]),
                                    leaf("止损挂模型位（外沿/针尖）", markers=["symbol-info"]),
                                    warn("独立假突破：只做合约或空仓"),
                                    no("勿与「突破期权后再加仓」混仓"),
                                ],
                                markers=["flag-dark-blue", "symbol-plus"],
                                fill="#1A5276",
                                color=C_TEXT,
                                font_size="12pt",
                                bold=True,
                                labels=["合约"],
                            ),
                        ],
                        markers=["symbol-plus", "arrow-up-right"],
                    ),
                    t2(
                        "平仓逻辑",
                        [
                            topic(
                                "期权离场",
                                [
                                    ok("只认：系统/规则止盈"),
                                    ok("只认：到期"),
                                    no("开仓后中间不手动平仓"),
                                    warn("紧急手平 → 标记非策略样本"),
                                ],
                                markers=["flag-green", "symbol-minus"],
                                fill="#145A32",
                                color=C_TEXT,
                                font_size="12pt",
                                bold=True,
                                labels=["期权"],
                            ),
                            topic(
                                "合约离场",
                                [
                                    ok("结构止盈为准"),
                                    ok("结构止损为准（约 5U 量级）"),
                                    leaf("等待系统/挂单结果，不情绪手平", markers=["other-clock"]),
                                ],
                                markers=["flag-dark-green", "symbol-minus"],
                                fill="#145A32",
                                color=C_TEXT,
                                font_size="12pt",
                                bold=True,
                                labels=["合约"],
                            ),
                            topic(
                                "持仓期盯什么",
                                [
                                    leaf("程序与纪律是否正常", markers=["task-done"]),
                                    no("不是浮盈浮亏数字本身"),
                                    leaf("无信号空档：空跑三检也是训练", markers=["other-lightbulb"]),
                                ],
                                markers=["symbol-info"],
                                fill="#1A5276",
                                color=C_TEXT,
                                font_size="12pt",
                                bold=True,
                            ),
                        ],
                        markers=["symbol-minus", "flag-green"],
                    ),
                ],
                markers=["priority-3", "arrow-right"],
                label="操盘",
            ),
            t1(
                "④ 纪律执行",
                [
                    t2(
                        "Gate 日纪律",
                        [
                            leaf("只做很明确的位置", markers=["symbol-info"]),
                            leaf("同一位置最多两次机会（突破/假突破）", markers=["priority-2"]),
                            no("两次都错 → 当日不再做单"),
                            ok("离场以结构止盈/止损为准"),
                        ],
                        markers=["flag-dark-blue", "task-done"],
                    ),
                    t2(
                        "期权日纪律",
                        [
                            no("不手平；等规则止盈或到期"),
                            leaf("一次一仓；约 10U 权利金", markers=["symbol-info"]),
                            no("不对冲；不做每天默认开期权"),
                            leaf("损位跟模型：外沿/针尖", markers=["symbol-info"]),
                        ],
                        markers=["flag-blue", "task-done"],
                    ),
                    t2(
                        "开仓前自检清单",
                        [
                            leaf("今日只动期权/合约？未开对冲？", markers=["task-start"]),
                            leaf("1H 方向清楚（含 N 字）？", markers=["task-start"]),
                            leaf("空间足够？结构量级够？", markers=["task-start"]),
                            leaf("止损/止盈与 RR 定好？", markers=["task-start"]),
                            leaf("工具选期权还是合约？理由写清？", markers=["task-start"]),
                            leaf("合约：本位置第几次？今日两次用完？", markers=["task-start"]),
                        ],
                        markers=["other-yes", "task-start"],
                    ),
                    t2(
                        "一句话版本",
                        [
                            leaf("1H→空间→结构→定损盈→期权/合约", markers=["arrow-right"]),
                            leaf("不对冲；期权不手平", markers=["flag-gray"]),
                            leaf("一位置两次，错完收工", markers=["priority-2"]),
                            leaf("珍惜机会，日更不是目标", markers=["star-dark-blue"]),
                        ],
                        markers=["star-dark-blue", "symbol-right"],
                    ),
                ],
                markers=["priority-4", "task-done"],
                label="纪律",
            ),
        ],
        # 中心主题保持干净：不加图标/标签/备注，避免绿人、黄便签等杂乱标识
        markers=None,
        labels=None,
        fill=C_ROOT,
        color=C_TEXT,
        font_size="20pt",
        bold=True,
        line=C_ROOT,
    )
    root["structureClass"] = "org.xmind.ui.logic.right"

    # XMind Zen 内置主题名；客户端可识别 business
    sheet = {
        "id": tid(),
        "class": "sheet",
        "title": "执行手册与行为准则 · 商务版",
        "rootTopic": root,
        "theme": {
            "id": tid(),
            "title": "business",
            "centralTopic": {
                "id": "centralTopic",
                "properties": {
                    "svg:fill": C_ROOT,
                    "fo:color": C_TEXT,
                    "fo:font-family": "Microsoft YaHei",
                    "fo:font-size": "20pt",
                    "fo:font-weight": "bold",
                    "shape-class": "org.xmind.topicShape.roundedRect",
                    "line-color": C_L1,
                    "line-width": "2pt",
                    "line-class": "org.xmind.branchConnection.roundedelbow",
                },
            },
            "mainTopic": {
                "id": "mainTopic",
                "properties": {
                    "svg:fill": C_L1,
                    "fo:color": C_TEXT,
                    "fo:font-family": "Microsoft YaHei",
                    "fo:font-size": "15pt",
                    "fo:font-weight": "bold",
                    "shape-class": "org.xmind.topicShape.roundedRect",
                    "line-color": C_L2,
                    "line-width": "1.5pt",
                },
            },
            "subTopic": {
                "id": "subTopic",
                "properties": {
                    "svg:fill": C_L2,
                    "fo:color": C_TEXT,
                    "fo:font-family": "Microsoft YaHei",
                    "fo:font-size": "12pt",
                    "shape-class": "org.xmind.topicShape.roundedRect",
                    "line-color": "#85C1E9",
                },
            },
            "floatingTopic": {
                "id": "floatingTopic",
                "properties": {
                    "svg:fill": C_MUTED,
                    "fo:color": C_TEXT,
                    "fo:font-family": "Microsoft YaHei",
                },
            },
            "importantTopic": {
                "id": "importantTopic",
                "properties": {
                    "svg:fill": C_WARN,
                    "fo:color": C_TEXT,
                },
            },
            "minorTopic": {
                "id": "minorTopic",
                "properties": {
                    "svg:fill": "#EBF5FB",
                    "fo:color": C_TEXT_DARK,
                },
            },
            "expiredTopic": {
                "id": "expiredTopic",
                "properties": {
                    "svg:fill": "#D5D8DC",
                    "fo:color": C_MUTED,
                },
            },
            "calloutTopic": {
                "id": "calloutTopic",
                "properties": {
                    "svg:fill": "#FEF9E7",
                    "fo:color": C_WARN,
                },
            },
            "summaryTopic": {
                "id": "summaryTopic",
                "properties": {
                    "svg:fill": "#145A32",
                    "fo:color": C_TEXT,
                },
            },
            "boundary": {
                "id": "boundary",
                "properties": {
                    "svg:fill": "#D6EAF8",
                    "fo:color": C_L1,
                    "line-color": C_L2,
                },
            },
            "summary": {
                "id": "summary",
                "properties": {
                    "line-color": C_L1,
                    "line-width": "2pt",
                },
            },
            "relationship": {
                "id": "relationship",
                "properties": {
                    "line-color": C_MUTED,
                    "line-pattern": "dash",
                },
            },
            "map": {
                "id": "map",
                "properties": {
                    "svg:fill": "#F4F6F7",
                    "color-list": f"{C_L1} {C_L2} #2874A6 #1ABC9C #B9770E",
                    "line-tapered": "none",
                },
            },
        },
    }
    return [sheet]


def main() -> None:
    content = build_content()
    metadata = {
        "creator": {"name": "crypto_monitor", "version": "1.1"},
        "activeSheetId": content[0]["id"],
    }
    manifest = {
        "file-entries": {
            "content.json": {},
            "metadata.json": {},
            "manifest.json": {},
        }
    }
    OUT.parent.mkdir(parents=True, exist_ok=True)
    if OUT.exists():
        OUT.unlink()
    with zipfile.ZipFile(OUT, "w", compression=zipfile.ZIP_DEFLATED) as zf:
        zf.writestr("content.json", json.dumps(content, ensure_ascii=False, indent=2))
        zf.writestr("metadata.json", json.dumps(metadata, ensure_ascii=False, indent=2))
        zf.writestr("manifest.json", json.dumps(manifest, ensure_ascii=False, indent=2))
    print(f"wrote {OUT}")


if __name__ == "__main__":
    main()
