from __future__ import annotations

import json
from pathlib import Path

import openpyxl


ROOT = Path(__file__).resolve().parents[1]
CASE_XLSX = ROOT / "SaaS_E2E测试用例_单Sheet用例测试列表.xlsx"
FLOW_XLSX = ROOT / "订单状态流转_链路流程线整理.xlsx"
JSON_FILES = [
    ROOT / "scripts" / "order_status_flow_cases.json",
    ROOT / "runtime" / "order_status_flow_cases_for_sheet.json",
    ROOT / "runtime" / "order_status_flow_cases_for_excel.json",
]

CASE_017_UPDATES = {
    "预期结果": (
        "1. 丸掌柜拒绝/取消撤销后，当前子单不进入取消订单或撤销结束终态，也不再残留撤销中。\n"
        "2. 按平台实际显示，订单详情顶部主单状态为代练中，子单状态为代练中。\n"
        "3. 子单列表中目标子单订单状态为异常中，子状态描述为发单方取消撤销。\n"
        "4. 页面同时展示【继续发单】入口和目标异常中子单行内【发起售后】入口；后续可按业务分支选择继续发单或对异常中子单发起售后。\n"
        "5. 丸友集侧不应继续展示撤销中。"
    ),
    "跨端/状态断言": (
        "1. 拒绝撤销后不能残留撤销中作为当前状态。\n"
        "2. 丸掌柜顶部主单状态、子单汇总状态与子单列表行状态需要分开回读：顶部为代练中/代练中，子单列表目标行为异常中/发单方取消撤销。\n"
        "3. FLOW-009 到 S-FLOW-017 即完成拒绝撤销实际状态验证；S-FLOW-034 是该状态下可选的异常中子单售后后续分支，不是 FLOW-009 的必然终点。\n"
        "4. 拒绝原因在丸掌柜和丸友集侧一致。"
    ),
    "备注": "2026-06-24按实测更新：拒绝撤销后顶部主单/子单状态为代练中，子单列表目标行为异常中/发单方取消撤销；页面仍展示继续发单和发起售后入口。",
}


def headers(sheet) -> dict[str, int]:
    return {str(sheet.cell(1, column).value): column for column in range(1, sheet.max_column + 1)}


def find_row(sheet, key_col: int, value: str) -> int | None:
    for row in range(2, sheet.max_row + 1):
        if sheet.cell(row, key_col).value == value:
            return row
    return None


def update_case_workbook() -> None:
    workbook = openpyxl.load_workbook(CASE_XLSX)
    sheet = workbook["订单状态流转"]
    h = headers(sheet)
    row = find_row(sheet, h["用例编号"], "S-FLOW-017")
    if row:
        for field, value in CASE_017_UPDATES.items():
            if field in h:
                sheet.cell(row, h[field], value)
    workbook.save(CASE_XLSX)


def update_json_files() -> None:
    for path in JSON_FILES:
        if not path.exists():
            continue
        data = json.loads(path.read_text(encoding="utf-8"))
        for case in data:
            if case.get("用例编号") == "S-FLOW-017":
                case.update(CASE_017_UPDATES)
        path.write_text(json.dumps(data, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")


def update_flow_workbook() -> None:
    workbook = openpyxl.load_workbook(FLOW_XLSX)

    flow_sheet = workbook["链路流程线"]
    h = headers(flow_sheet)
    row = find_row(flow_sheet, h["链路编号"], "FLOW-009")
    if row:
        flow_sheet.cell(row, h["链路名称"], "丸友集已接单未发打手-申请撤销-丸掌柜拒绝撤销-实际状态回读")
        flow_sheet.cell(row, h["链路类型"], "丸友集撤销逆向状态验证")
        flow_sheet.cell(row, h["终点状态"], "顶部主单代练中/子单代练中；子单列表目标行异常中/发单方取消撤销；可继续发单或发起售后")
        flow_sheet.cell(row, h["用例编号序列"], "S-FLOW-007 -> S-FLOW-014 -> S-FLOW-015 -> S-FLOW-017")
        flow_sheet.cell(
            row,
            h["适用场景"],
            "验证丸友集接单未发打手阶段申请撤销后，丸掌柜拒绝撤销的实际状态落点和可用后续入口。",
        )
        flow_sheet.cell(
            row,
            h["数据复用建议"],
            "S-FLOW-017 后同一主单可继续选择【继续发单】，也可对异常中子单行内【发起售后】进入 S-FLOW-034；两者是并列后续分支。",
        )
        flow_sheet.cell(
            row,
            h["注意事项/缺口"],
            "2026-06-24实测：拒绝撤销后并非不可继续发单；页面顶部主单/子单状态为代练中，子单列表目标行为异常中/发单方取消撤销，同时展示继续发单和发起售后入口。",
        )

    detail = workbook["链路步骤明细"]
    dh = headers(detail)
    for row in range(2, detail.max_row + 1):
        if detail.cell(row, dh["链路编号"]).value == "FLOW-009" and detail.cell(row, dh["用例编号"]).value == "S-FLOW-017":
            detail.cell(row, dh["预期结果"], CASE_017_UPDATES["预期结果"])
            break

    coverage = workbook["用例覆盖索引"]
    ch = headers(coverage)
    row = find_row(coverage, ch["用例编号"], "S-FLOW-017")
    if row:
        coverage.cell(row, ch["备注"], CASE_017_UPDATES["备注"])

    raw = workbook["原始用例索引"]
    rh = headers(raw)
    row = find_row(raw, rh["用例编号"], "S-FLOW-017")
    if row:
        for field, value in CASE_017_UPDATES.items():
            if field in rh:
                raw.cell(row, rh[field], value)

    workbook.save(FLOW_XLSX)


def main() -> None:
    update_case_workbook()
    update_json_files()
    update_flow_workbook()
    print("FLOW-009 actual expected status updated")


if __name__ == "__main__":
    main()
