#!/usr/bin/env python3
"""Generate audit center test cases Excel for xll-miniapp."""

from openpyxl import Workbook
from openpyxl.styles import Font, Alignment, PatternFill, Border, Side
from openpyxl.utils import get_column_letter
from datetime import date
import os

DESKTOP = os.path.expanduser("~/Desktop")
OUTPUT = os.path.join(DESKTOP, f"小羚羚-审批中心测试用例-{date.today().isoformat()}.xlsx")

HEADERS = [
    "用例编号",
    "测试模块",
    "流程类型",
    "测试场景",
    "前置条件",
    "操作步骤",
    "测试数据（Mock）",
    "预期结果",
    "优先级",
    "关联需求/标注",
]

CASES = []

def add(module, flow, scene, pre, steps, data, expect, pri, ref):
    CASES.append([module, flow, scene, pre, steps, data, expect, pri, ref])

# ========== 提车应收款 ==========
add(
    "提车应收款",
    "提车应收款",
    "列表-待办卡片展示",
    "打开审批中心；当前用户=张明辉；Tab=我的待办",
    "1. 进入 #page=audit\n2. 查看「我的待办」列表",
    "单据 TC-2026-0312；客户=上海迅杰物流有限公司",
    "卡片左上角标签「提车应收款」；加粗标题=客户全称；副标题=项目名称；元信息含发起人与实收金额；底部发起时间精确至分钟；显示「去审批」",
    "P0",
    "PRD01 §3.3/§5.3；page-audit；page-audit-pickup",
)
add(
    "提车应收款",
    "提车应收款",
    "列表-实收金额口径（不含氢费预付款）",
    "同上",
    "1. 找到 TC-2026-0312 卡片\n2. 核对实收金额",
    "3台车明细：租金+服务费+保证金−减免，不含氢费预付款",
    "列表实收金额=￥218,510.00（与车辆明细动态汇总一致，不含氢费预付款 4100）",
    "P0",
    "PRD01 §5.3；ap-2 mock",
)
add(
    "提车应收款",
    "提车应收款",
    "搜索-按客户全称",
    "审批中心列表",
    "1. 搜索框输入「上海迅杰」\n2. 观察筛选结果",
    "搜索关键词=上海迅杰",
    "仅展示加粗标题匹配的任务；TC-2026-0312 可见",
    "P1",
    "PRD01 §3.2；page-audit",
)
add(
    "提车应收款",
    "提车应收款",
    "Chip筛选",
    "审批中心",
    "1. 点击流程 Chip「提车应收款」",
    "",
    "列表仅展示 flowType=提车应收款 的任务",
    "P1",
    "PRD01 §3.2",
)
add(
    "提车应收款",
    "提车应收款",
    "详情-Hero实收金额",
    "待办 TC-2026-0312",
    "1. 点击卡片进入详情\n2. 查看 Hero 区",
    "TC-2026-0312",
    "Hero 实收款总额与列表卡片同一口径（不含氢费预付款）；展示客户/合同/项目信息",
    "P0",
    "PRD01 §5.3；page-audit-pickup",
)
add(
    "提车应收款",
    "提车应收款",
    "详情-车辆明细间距",
    "进入 TC-2026-0312 详情",
    "1. 滚动至车辆明细区块\n2. 检查标题与首卡间距",
    "",
    "区块标题行与首张车辆卡片之间保留约 12px 上间距",
    "P2",
    "PRD01 §5.2；page-audit-pickup",
)
add(
    "提车应收款",
    "提车应收款",
    "详情-氢费预付款展示",
    "进入 TC-2026-0312 详情",
    "1. 查看氢费预付款区块",
    "",
    "详情可展示氢费预付款信息，但不计入列表/Hero 实收总额",
    "P1",
    "PRD01 §5.3",
)
add(
    "提车应收款",
    "提车应收款",
    "详情-审批时间轴",
    "待办 TC-2026-0312",
    "1. 查看审批情况时间轴",
    "",
    "节点展示审批人、状态 Tag、时间；含评论气泡（如业务总负责人节点）",
    "P1",
    "PRD01 §4.4/§5.2",
)
add(
    "提车应收款",
    "提车应收款",
    "待办-审批通过弹窗",
    "待办 TC-2026-0312 详情",
    "1. 点击底部「通过」\n2. 观察弹窗",
    "",
    "手机预览框内自底部滑出半屏表单；标题「审批通过」；含通知方式、附件、抄送人、审批意见；取消/确认",
    "P0",
    "tc-btn-approve 标注；PRD01 §3.5",
)
add(
    "提车应收款",
    "提车应收款",
    "待办-驳回/终止/评论",
    "待办 TC-2026-0312 详情",
    "1. 分别点击驳回、终止、评论",
    "",
    "均为框内半屏 sheet；驳回/终止字段与通过一致（标题不同）",
    "P1",
    "PRD01 §3.5",
)
add(
    "提车应收款",
    "提车应收款",
    "已办-只读查看",
    "Tab=我的已办；用户=财务-赵敏 或切换至 ap-12",
    "1. 打开 TC-2026-0228（嘉兴某某物流）详情",
    "ap-12 已通过",
    "无底部操作栏；可浏览 Hero、车辆明细、审批时间轴",
    "P1",
    "PRD01 §3.5",
)
add(
    "提车应收款",
    "提车应收款",
    "抄送 Tab 可见性",
    "Tab=抄送我的；用户=张明辉",
    "1. 查看是否含 TC-2026-0312",
    "ccUsers 含张明辉",
    "抄送列表可见该任务；进入为查看态",
    "P2",
    "acFilterByTab cc",
)

# ========== 还车应结款主流程 ==========
add(
    "还车应结款主流程",
    "还车应结款",
    "场景A-主流程待办展示",
    "Tab=我的待办；用户=张明辉",
    "1. 点击 Chip「还车应结款」\n2. 找到粤B58888F 主流程卡片",
    "HC-2026-0418 / ap-14；四部门已通过且 mainFlowInitiated=true",
    "卡片标签「还车应结款」；加粗标题=粤B58888F；展示应退还总额；状态=审批中·财务审核",
    "P0",
    "PRD01 §4.1 场景A；page-audit-return",
)
add(
    "还车应结款主流程",
    "还车应结款",
    "场景C-主流程不出现在列表",
    "Tab=我的待办/全部",
    "1. Chip「还车应结款」\n2. 搜索苏E12345F",
    "HC-2026-0610 / ap-26；四部门已通过但 mainFlowInitiated=false",
    "主流程「还车应结款」任务不在审批列表；四部门子流程可在已办/历史中出现",
    "P0",
    "PRD01 §4.1 场景C",
)
add(
    "还车应结款主流程",
    "还车应结款",
    "Chip 匹配主流程+子流程",
    "审批中心",
    "1. 点击「还车应结款」Chip",
    "",
    "列表同时包含主流程与四部门子流程任务",
    "P1",
    "PRD01 §3.2",
)
add(
    "还车应结款主流程",
    "还车应结款",
    "搜索-按车牌",
    "审批中心",
    "1. 搜索「粤B58888F」",
    "",
    "匹配主流程及同车牌的四部门子流程（标题均为车牌）",
    "P1",
    "PRD01 §3.2；列表标题规则（当前实现）",
)
add(
    "还车应结款主流程",
    "还车应结款",
    "详情-Hero应退应补",
    "待办 ap-14 主流程详情",
    "1. 进入粤B58888F 主流程\n2. 查看 Hero",
    "deposit=5000；pendingSettle=927.50；refundTotal=4072.50",
    "Hero 展示应退还总额 ￥4,072.50；含保证金、待结算总额、车辆实际租金；有「结算明细」入口",
    "P0",
    "PRD01 §4.2",
)
add(
    "还车应结款主流程",
    "还车应结款",
    "详情-四部门分组卡片",
    "主流程 ap-14 详情",
    "1. 查看四张部门费用卡片",
    "",
    "业务管理组/能源服务组/运维组/安全部分组展示；右上角均为「已提交」（绿色）",
    "P0",
    "hc-settle-group-status 标注；PRD01 §4.3",
)
add(
    "还车应结款主流程",
    "还车应结款",
    "详情-运维组无忧包减免列",
    "主流程 ap-14 详情",
    "1. 展开运维组费用表",
    "",
    "表格含序号/费用项/金额/无忧包减免；应结算=金额−减免",
    "P1",
    "PRD01 §4.3",
)
add(
    "还车应结款主流程",
    "还车应结款",
    "详情-安全部三行费项",
    "主流程 ap-14 详情",
    "1. 查看安全部分组",
    "",
    "固定三行：违章处理违约金、保险上浮、其他违规费用；含违章统计区",
    "P1",
    "PRD01 §4.3",
)
add(
    "还车应结款主流程",
    "还车应结款",
    "详情-业务管理组不含安全费项",
    "主流程 ap-14 详情",
    "1. 查看业务管理组分组",
    "",
    "仅 ETC、停车费等；不含违章违约金、保险上浮",
    "P1",
    "PRD01 §4.3",
)
add(
    "还车应结款主流程",
    "还车应结款",
    "详情-部门子流程进度",
    "主流程 ap-14 详情",
    "1. 查看 Hero 或进度区",
    "",
    "展示四部门子流程通过状态/进度",
    "P1",
    "PRD01 §4.2",
)
add(
    "还车应结款主流程",
    "还车应结款",
    "待办-审批通过",
    "待办 ap-14 详情",
    "1. 点击「通过」并确认",
    "",
    "框内半屏审批通过表单；确认后 toast 提示（原型）",
    "P1",
    "tc-btn-approve",
)
add(
    "还车应结款主流程",
    "还车应结款",
    "已完结主流程-已办",
    "Tab=我的已办",
    "1. 打开沪A03561F HC-2026-0520（ap-4）",
    "status=已通过",
    "可查看详情；Hero 展示历史应退信息；无操作栏",
    "P2",
    "ap-4 mock",
)

# ========== 还车应结款四部门子流程 ==========
depts = [
    ("还车应结款-业务管理组", "业务管理组", "ETC/停车费", "ap-22", "浙F06901F", "HC-2026-0625-BS"),
    ("还车应结款-能源服务组", "能源服务组", "氢量差补缴/预付款退费", "ap-23", "浙F06901F", "HC-2026-0625-EN"),
    ("还车应结款-运维组", "运维组", "清洗/保养/维修/无忧包减免", "ap-24", "浙F06901F", "HC-2026-0625-OP"),
    ("还车应结款-安全部", "安全部", "违章违约金/保险上浮/其他违规", "ap-25", "浙F06901F", "HC-2026-0625-SF"),
]

add(
    "还车应结款子流程",
    "四部门合计",
    "场景B-四部门均在待办",
    "Tab=我的待办；用户=张明辉",
    "1. Chip「还车应结款」\n2. 筛选浙F06901F",
    "场景B / ap-22~25 均为审批中",
    "同车牌四条子流程均出现在待办；主流程 HC-2026-0625 不在列表",
    "P0",
    "PRD01 §4.1 场景B；page-audit-return",
)

for flow, dept, fee_hint, ap_id, plate, biz in depts:
    add(
        "还车应结款子流程",
        flow,
        f"列表-待办卡片展示（{dept}）",
        "Tab=我的待办；场景B",
        f"1. 找到 {flow} 卡片",
        f"{ap_id}；车牌={plate}；单据={biz}",
        f"左上角标签={flow}；加粗标题={plate}（车牌重点）；副标题客户+项目；元信息仅发起人（不展示汇总应退/应补）",
        "P0",
        "page-audit；批注：子流程列表车牌重点",
    )
    add(
        "还车应结款子流程",
        flow,
        f"详情-Hero（{dept}）",
        f"待办 {ap_id}",
        "1. 进入详情\n2. 查看 Hero",
        plate,
        f"Hero 标题「{flow}」+ 车牌胶囊重点样式；不展示保证金/应退应补汇总金额",
        "P0",
        "PRD01 §4.2",
    )
    add(
        "还车应结款子流程",
        flow,
        f"详情-本部门费用（{dept}）",
        f"待办 {ap_id}",
        "1. 查看费用明细区块",
        fee_hint,
        f"仅展示{dept}相关费项；底部本部门应结算总额",
        "P1",
        "PRD01 §4.3",
    )
    add(
        "还车应结款子流程",
        flow,
        f"详情-状态标签审批中（{dept}）",
        f"待办 {ap_id}；status=审批中",
        "1. 查看分组卡片右上角（若详情含）",
        "",
        "子流程详情按实际状态展示；列表卡片状态含当前节点审批人",
        "P1",
        "hc-settle-group-status",
    )
    add(
        "还车应结款子流程",
        flow,
        f"待办-审批操作（{dept}）",
        f"待办 {ap_id}",
        "1. 点击通过/驳回/终止/评论",
        "",
        "底部操作栏可用；弹窗限定手机框内",
        "P1",
        "tc-btn-approve",
    )

add(
    "还车应结款子流程",
    "四部门合计",
    "场景A-子流程均已通过",
    "Tab=我的已办或全部",
    "1. 搜索粤B58888F\n2. 查看四部门子流程",
    "ap-15/18/19/20 status=已通过",
    "四条子流程状态已通过；不在待办（currentAssignee 为空）",
    "P1",
    "场景A",
)
add(
    "还车应结款子流程",
    "四部门合计",
    "场景C-子流程已通过主流程未发起",
    "Tab=全部/已办",
    "1. 搜索苏E12345F",
    "ap-27~30 已通过；ap-26 待发起",
    "四部门子流程可见且已通过；主流程 ap-26 不出现在列表",
    "P0",
    "场景C",
)
add(
    "还车应结款子流程",
    "还车应结款-业务管理组",
    "搜索-按流程类型名称",
    "审批中心",
    "1. 搜索「业务管理组」",
    "",
    "可匹配 flowType 含业务管理组的任务（含浙F06901F 等待办）",
    "P2",
    "搜索增强：标题+flowType",
)

# ========== 审批中心通用 ==========
COMMON = [
    (
        "审批中心通用",
        "全部",
        "四 Tab 切换",
        "进入审批中心",
        "1. 依次切换我发起的/待办/已办/抄送",
        "用户=张明辉",
        "各 Tab 列表数量与 mock 过滤规则一致",
        "P1",
        "PRD01 §3.1",
    ),
    (
        "审批中心通用",
        "全部",
        "更多筛选-框内 sheet",
        "审批中心",
        "1. 点击搜索框右侧筛选按钮",
        "",
        "更多筛选从手机预览框底部滑出，不铺满浏览器",
        "P1",
        "PRD01 §3.6；page-audit",
    ),
    (
        "审批中心通用",
        "全部",
        "更多筛选-发起人滚轮",
        "打开更多筛选 sheet",
        "1. 点击发起人「请选择 ›」\n2. 滚轮选择并确定",
        "",
        "框内滚轮选择器；首项「不限」",
        "P1",
        "PRD01 §3.6",
    ),
    (
        "审批中心通用",
        "全部",
        "更多筛选-发起日期滚轮",
        "打开更多筛选 sheet",
        "1. 点击开始/结束日期\n2. 年/月/日滚轮选择",
        "",
        "日期滚轮叠在筛选 sheet 之上；高亮条不遮挡文字",
        "P1",
        "PRD01 §3.6",
    ),
    (
        "审批中心通用",
        "全部",
        "更多类型 sheet",
        "审批中心",
        "1. 点击「更多类型」Chip",
        "",
        "框内 sheet 展示全部流程类型；选择后关闭并筛选",
        "P2",
        "page-audit",
    ),
    (
        "审批中心通用",
        "全部",
        "Toast 框内反馈",
        "任意触发 toast 的操作",
        "1. 如筛选确定、审批确认",
        "",
        "提示出现在手机预览框顶部，非浏览器全局 message",
        "P2",
        "UI Review P2 修复",
    ),
]
for c in COMMON:
    add(*c)

# Renumber
for i, row in enumerate(CASES, 1):
    module = row[0]
    prefix = {"提车应收款": "TC", "还车应结款主流程": "RS-M", "还车应结款子流程": "RS-S", "审批中心通用": "AC"}.get(module, "AC")
    row.insert(0, f"{prefix}-{i:03d}")

wb = Workbook()
meta = wb.active
meta.title = "说明"
meta["A1"] = "小羚羚小程序 · 审批中心测试用例"
meta["A1"].font = Font(bold=True, size=14)
meta["A2"] = f"生成日期：{date.today().isoformat()}"
meta["A3"] = "范围：提车应收款、还车应结款主流程、还车应结款四部门子流程"
meta["A4"] = "默认测试用户：张明辉（MOCK_USER）"
meta["A5"] = "预览入口：http://localhost:51721/prototypes/xll-miniapp#page=audit"
meta["A6"] = "数据来源：annotation-source.json + PRD01 V1.4 + index.tsx mock"
meta.column_dimensions["A"].width = 80

for title, rows in [
    ("提车应收款", [r for r in CASES if r[1] == "提车应收款"]),
    ("还车应结款-主流程", [r for r in CASES if r[1] == "还车应结款主流程"]),
    ("还车应结款-子流程", [r for r in CASES if r[1] == "还车应结款子流程"]),
    ("审批中心通用", [r for r in CASES if r[1] == "审批中心通用"]),
    ("全部用例", CASES),
]:
    ws = wb.create_sheet(title[:31])
    header_fill = PatternFill("solid", fgColor="7AB929")
    header_font = Font(bold=True, color="FFFFFF")
    thin = Side(style="thin", color="E5E6EB")
    border = Border(left=thin, right=thin, top=thin, bottom=thin)
    ws.append(HEADERS)
    for col in range(1, len(HEADERS) + 1):
        cell = ws.cell(row=1, column=col)
        cell.fill = header_fill
        cell.font = header_font
        cell.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)
        cell.border = border
    for row in rows:
        ws.append(row)
    widths = [12, 14, 22, 24, 28, 36, 28, 40, 8, 24]
    for i, w in enumerate(widths, 1):
        ws.column_dimensions[get_column_letter(i)].width = w
    for r in range(2, ws.max_row + 1):
        for c in range(1, len(HEADERS) + 1):
            ws.cell(row=r, column=c).alignment = Alignment(vertical="top", wrap_text=True)
            ws.cell(row=r, column=c).border = border
    ws.freeze_panes = "A2"

wb.save(OUTPUT)
print(OUTPUT)
print(f"cases={len(CASES)}")
