from __future__ import annotations

import json
from pathlib import Path

import openpyxl


ROOT = Path(__file__).resolve().parents[1]

CASE_035 = {
    "用例标题": "【丸友集】子单售后中状态-同意/处理子单售后",
    "前置条件": "已执行任一子单发起售后用例，目标子单售后进入售后中或页面对应待处理售后状态；丸友集订单列表中目标订单可按来源单号/上游单号查询到，并存在【主单售后】或页面对应售后处理入口。",
    "执行步骤": "1. 登录丸友集主账号或客服账号。\n2. 进入工作室履约应用-订单列表。\n3. 按来源单号或上游单号查询目标订单。\n4. 确认目标订单处于售后中或页面对应待处理售后状态。\n5. 点击操作列【主单售后】或页面对应售后处理入口。\n6. 在售后处理弹窗中核对售后金额、售后原因和凭证。\n7. 按页面要求选择售后客服或记录客服下拉实际情况。\n8. 点击【同意】或页面对应处理通过入口并提交。\n9. 回到丸友集订单列表，按来源单号回读订单状态。\n10. 登录丸掌柜账号，进入订单详情回读主单、子单、子单列表和售后结果。",
    "预期结果": "1. 丸友集侧目标订单同意/处理售后后进入售后结束、售后处理完成或页面实际售后完成终态。\n2. 丸掌柜订单详情中目标子单不再处于售后中，子单售后记录展示处理完成、退款金额和处理结果。\n3. 售后金额、售后原因、处理结果在丸掌柜和丸友集侧一致。\n4. 该子单售后处理完成后，不能再按售后中状态重复处理。",
    "跨端/状态断言": "1. 本用例是所有子单售后中状态的通用同意/处理用例。\n2. 不管子单售后来自异常中子单、已接单未发打手子单或其他子单行内售后入口，只要当前处理对象是子单售后中，统一引用本用例。\n3. 本用例不处理主单售后；主单售后确认统一引用 S-FLOW-003。\n4. S-FLOW-059 等重复子单售后处理用例已收束到本用例。",
    "可组合/被引用关系": "承接任一子单发起售后用例；作为子单售后中 -> 售后结束/售后处理完成的通用处理用例；FLOW-031 等链路引用本用例。",
}

CASE_036 = {
    "用例标题": "【丸友集】子单售后中状态-拒绝/取消子单售后",
    "前置条件": "已执行任一子单发起售后用例，目标子单售后进入售后中且未处理完成；丸友集订单列表中目标订单可按来源单号/上游单号查询到，并存在【主单售后】或页面对应售后处理入口。",
    "执行步骤": "1. 登录丸友集主账号或客服账号。\n2. 进入工作室履约应用-订单列表。\n3. 按来源单号或上游单号查询目标订单。\n4. 确认目标订单处于售后中或页面对应待处理售后状态。\n5. 点击操作列【主单售后】或页面对应售后处理入口。\n6. 在售后处理弹窗中核对售后金额、售后原因和凭证。\n7. 点击【拒绝】、【取消售后】或页面对应拒绝/取消入口。\n8. 填写拒绝/取消原因并确认。\n9. 回到丸友集订单列表，按来源单号回读订单状态。\n10. 登录丸掌柜账号，进入订单详情回读主单、子单、子单列表和售后记录。",
    "预期结果": "1. 子单售后拒绝/取消提交成功，拒绝/取消原因可追溯。\n2. 目标子单不应错误进入已售后终态。\n3. 丸掌柜和丸友集侧按实际平台回读展示拒绝后仍售后中、恢复售后前状态或页面对应异常待处理状态。\n4. 本用例以实际平台回读为准，不再按不同前置阶段拆多条重复用例。",
    "跨端/状态断言": "1. 本用例是所有子单售后中状态的通用拒绝/取消用例。\n2. 不管子单售后来自异常中子单、已接单未发打手子单或其他子单行内售后入口，只要当前处理对象是子单售后中，统一引用本用例。\n3. 本用例不处理主单售后取消；主单售后取消仍按对应主单售后取消用例执行。\n4. S-FLOW-060 等重复子单售后取消用例已收束到本用例。",
    "可组合/被引用关系": "承接任一子单发起售后用例；作为子单售后中拒绝/取消的通用用例；FLOW-032 等链路引用本用例。",
}

CONSOLIDATED_059 = {
    "用例标题": "【已收束】已接单未发打手子单售后中-处理售后（引用S-FLOW-035）",
    "前置条件": "已执行 S-FLOW-058，目标子单进入售后中；子单售后同意/处理动作统一引用 S-FLOW-035。",
    "执行步骤": "调用 S-FLOW-035【丸友集】子单售后中状态-同意/处理子单售后。",
    "预期结果": "同 S-FLOW-035：目标子单售后处理完成，售后金额、原因和处理结果在丸掌柜与丸友集侧一致。",
    "跨端/状态断言": "不再单独维护已接单未发打手阶段子单售后处理断言，统一以 S-FLOW-035 为准。",
    "可组合/被引用关系": "已收束到 S-FLOW-035；历史编号仅保留追溯。",
}

CONSOLIDATED_060 = {
    "用例标题": "【已收束】已接单未发打手子单售后中-拒绝/取消售后（引用S-FLOW-036）",
    "前置条件": "已执行 S-FLOW-058，目标子单进入售后中；子单售后拒绝/取消动作统一引用 S-FLOW-036。",
    "执行步骤": "调用 S-FLOW-036【丸友集】子单售后中状态-拒绝/取消子单售后。",
    "预期结果": "同 S-FLOW-036：目标子单售后拒绝/取消成功，拒绝/取消原因可追溯，状态以实际平台回读为准。",
    "跨端/状态断言": "不再单独维护已接单未发打手阶段子单售后取消断言，统一以 S-FLOW-036 为准。",
    "可组合/被引用关系": "已收束到 S-FLOW-036；历史编号仅保留追溯。",
}

CASE_058_RELATION = "与 S-FLOW-034 并列：二者都是子单行内发起售后；后续子单售后中处理统一承接 S-FLOW-035，拒绝/取消统一承接 S-FLOW-036。"

FLOW_031 = {
    "用例编号序列": "S-FLOW-007 -> S-FLOW-014 -> S-FLOW-058 -> S-FLOW-035",
    "用例链路（编号+标题）": "S-FLOW-007(【丸掌柜】主单待接单状态/子单待接单-已推单状态-创建主单已推单) -> S-FLOW-014(丸友集抢单大厅待接单阶段-丸友集确认接单) -> S-FLOW-058(丸友集已接单/未发单到打手抢单大厅阶段-丸掌柜子单发起售后) -> S-FLOW-035(【丸友集】子单售后中状态-同意/处理子单售后)",
    "注意事项/缺口": "处理对象必须是 S-FLOW-058 生成的子单售后，不是主单售后；子单售后中处理动作已收束到 S-FLOW-035；FLOW-031 到子单售后处理完成即收尾。",
}

FLOW_032 = {
    "用例编号序列": "S-FLOW-007 -> S-FLOW-014 -> S-FLOW-058 -> S-FLOW-036",
    "用例链路（编号+标题）": "S-FLOW-007(【丸掌柜】主单待接单状态/子单待接单-已推单状态-创建主单已推单) -> S-FLOW-014(丸友集抢单大厅待接单阶段-丸友集确认接单) -> S-FLOW-058(丸友集已接单/未发单到打手抢单大厅阶段-丸掌柜子单发起售后) -> S-FLOW-036(【丸友集】子单售后中状态-拒绝/取消子单售后)",
    "注意事项/缺口": "处理对象必须是 S-FLOW-058 生成的子单售后，不是主单售后；子单售后中拒绝/取消动作已收束到 S-FLOW-036；状态以实际平台回读为准。",
}


def update_case(item: dict, case_id: str) -> None:
    if case_id == "S-FLOW-035":
        item.update(CASE_035)
    elif case_id == "S-FLOW-036":
        item.update(CASE_036)
    elif case_id == "S-FLOW-059":
        item.update(CONSOLIDATED_059)
    elif case_id == "S-FLOW-060":
        item.update(CONSOLIDATED_060)
    elif case_id == "S-FLOW-058":
        item["可组合/被引用关系"] = CASE_058_RELATION


def update_json(path: Path) -> None:
    if not path.exists():
        return
    data = json.loads(path.read_text(encoding="utf-8"))
    for item in data:
        case_id = str(item.get("用例编号", ""))
        update_case(item, case_id)
        if str(item.get("用例编号", "")) == "S-FLOW-032":
            item["用例编号序列"] = FLOW_032["用例编号序列"]
            item["用例链路（编号+标题）"] = FLOW_032["用例链路（编号+标题）"]
            item["注意事项/缺口"] = FLOW_032["注意事项/缺口"]
    path.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")


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


def set_if_header(ws, row: int, h: dict[str, int], key: str, value: str) -> None:
    if key in h:
        ws.cell(row, h[key]).value = value


def update_case_row(ws, row: int, h: dict[str, int], case_id: str) -> None:
    before = {}
    update_case(before, case_id)
    for key, value in before.items():
        set_if_header(ws, row, h, key, value)


def update_excel(path: Path) -> None:
    if not path.exists():
        return
    wb = openpyxl.load_workbook(path)
    for ws in wb.worksheets:
        h = headers(ws)
        for row in range(2, ws.max_row + 1):
            case_id = str(ws.cell(row, h.get("用例编号", h.get("用例编号序列", 1))).value or "")
            chain_id = str(ws.cell(row, h.get("链路编号", 1)).value or "")
            if case_id in {"S-FLOW-035", "S-FLOW-036", "S-FLOW-058", "S-FLOW-059", "S-FLOW-060"}:
                update_case_row(ws, row, h, case_id)
            if chain_id == "FLOW-031":
                for key, value in FLOW_031.items():
                    set_if_header(ws, row, h, key, value)
            elif chain_id == "FLOW-032":
                for key, value in FLOW_032.items():
                    set_if_header(ws, row, h, key, value)
            if chain_id in {"FLOW-031", "FLOW-032"} and "用例编号" in h:
                step_case = str(ws.cell(row, h["用例编号"]).value or "")
                if chain_id == "FLOW-031" and step_case == "S-FLOW-059":
                    ws.cell(row, h["用例编号"]).value = "S-FLOW-035"
                    update_case_row(ws, row, h, "S-FLOW-035")
                elif chain_id == "FLOW-032" and step_case == "S-FLOW-060":
                    ws.cell(row, h["用例编号"]).value = "S-FLOW-036"
                    update_case_row(ws, row, h, "S-FLOW-036")
    wb.save(path)


def main() -> None:
    for rel in [
        "runtime/order_status_flow_cases_for_sheet.json",
        "runtime/order_status_flow_cases_for_excel.json",
        "scripts/order_status_flow_cases.json",
    ]:
        update_json(ROOT / rel)
    for rel in [
        "订单状态流转_链路流程线整理.xlsx",
        "SaaS_E2E测试用例_单Sheet用例测试列表.xlsx",
    ]:
        update_excel(ROOT / rel)


if __name__ == "__main__":
    main()
