from __future__ import annotations

import json
from pathlib import Path

from openpyxl import load_workbook


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

CASE_UPDATES = {
    "S-FLOW-063": {
        "用例标题": "【丸友集】通用子单处罚处理-同意赔偿",
        "前置条件": "任一子单处罚已由丸掌柜提交；丸友集工作室履约应用-申诉工单中，可按上游单号（丸掌柜主单号）找到目标处罚单；目标处罚单状态为待处理或处理中。",
        "执行步骤": "\n".join(
            [
                "1. 登录丸友集账号，进入工作室履约应用-申诉工单。",
                "2. 按上游单号（丸掌柜主单号）查询目标处罚单。",
                "3. 若同一上游单号存在多条处罚记录，定位状态为待处理或处理中的目标处罚单。",
                "4. 在操作列点击【去处理】；若状态为待处理，先在处罚详情中点击【我要处理】。",
                "5. 在同一处罚详情弹窗中点击【同意赔偿】。",
                "6. 填写处理备注，处罚金额使用整数，提交处理。",
                "7. 回到丸友集申诉工单列表，回读目标处罚单状态、申请处罚金额、处罚金额。",
                "8. 登录丸掌柜，进入商家管理-子单处罚单，按主单号/来源单号查询同一处罚单并回读状态和金额。",
            ]
        ),
        "预期结果": "丸友集侧目标处罚单处理完成，状态为已完成/已通过，处罚金额等于申请处罚金额；丸掌柜侧子单处罚单同步为已完成，申请处罚金额、处罚金额与丸友集侧一致。",
        "跨端/状态断言": "\n".join(
            [
                "1. 本用例是所有子单处罚同意赔偿的通用处理用例，不区分处罚来源是售后结束子单还是撤销结束子单。",
                "2. 处罚处理前置状态统一为待处理或处理中；待处理需先点击【我要处理】，处理中直接点击【同意赔偿】。",
                "3. 查询条件统一使用上游单号；丸友集上游单号等于丸掌柜主单号。",
                "4. 多条处罚记录共存时，必须按状态和处罚单信息定位目标记录，不按页面第一条盲点。",
                "5. 金额类输入统一使用整数。",
            ]
        ),
        "可组合/被引用关系": "承接任一处罚发起用例；S-FLOW-070 等撤销结束子单处罚同意分支统一引用本用例。",
        "备注": "2026-06-24 收束：处罚同意/赔偿处理统一由 S-FLOW-063 覆盖。",
    },
    "S-FLOW-064": {
        "用例标题": "【丸友集】通用子单处罚处理-驳回处罚",
        "前置条件": "任一子单处罚已由丸掌柜提交；丸友集工作室履约应用-申诉工单中，可按上游单号（丸掌柜主单号）找到目标处罚单；目标处罚单状态为待处理或处理中。",
        "执行步骤": "\n".join(
            [
                "1. 登录丸友集账号，进入工作室履约应用-申诉工单。",
                "2. 按上游单号（丸掌柜主单号）查询目标处罚单。",
                "3. 若同一上游单号存在多条处罚记录，定位状态为待处理或处理中的目标处罚单。",
                "4. 在操作列点击【去处理】；若状态为待处理，先在处罚详情中点击【我要处理】。",
                "5. 在同一处罚详情弹窗中点击【驳回】。",
                "6. 填写驳回原因/处理备注后提交。",
                "7. 回到丸友集申诉工单列表，回读目标处罚单状态、申请处罚金额、处罚金额。",
                "8. 登录丸掌柜，进入商家管理-子单处罚单，按主单号/来源单号查询同一处罚单并回读状态和金额。",
            ]
        ),
        "预期结果": "丸友集侧目标处罚单状态为已拒绝，处罚金额为0；丸掌柜侧子单处罚单同步为已拒绝，申请处罚金额保持原值，处罚金额为0，并可回溯驳回原因。",
        "跨端/状态断言": "\n".join(
            [
                "1. 本用例是所有子单处罚驳回处理的通用用例，不区分处罚来源是售后结束子单还是撤销结束子单。",
                "2. 处罚处理前置状态统一为待处理或处理中；待处理需先点击【我要处理】，处理中直接点击【驳回】。",
                "3. 查询条件统一使用上游单号；丸友集上游单号等于丸掌柜主单号。",
                "4. 多条处罚记录共存时，必须按状态和处罚单信息定位目标记录，不按页面第一条盲点。",
                "5. 驳回分支不得产生赔偿金额，处罚金额应为0。",
            ]
        ),
        "可组合/被引用关系": "承接任一处罚发起用例；S-FLOW-071 等撤销结束子单处罚驳回分支统一引用本用例。",
        "备注": "2026-06-24 收束：处罚驳回处理统一由 S-FLOW-064 覆盖。",
    },
    "S-FLOW-070": {
        "用例标题": "【已收束】撤销结束子单处罚同意赔偿（引用S-FLOW-063）",
        "前置条件": "已执行撤销结束子单处罚发起用例 S-FLOW-069，目标处罚单进入待处理或处理中；处理动作统一引用 S-FLOW-063。",
        "执行步骤": "调用 S-FLOW-063【丸友集】通用子单处罚处理-同意赔偿。",
        "预期结果": "同 S-FLOW-063：丸友集侧处罚单已完成/已通过，处罚金额等于申请处罚金额；丸掌柜侧子单处罚单同步已完成。",
        "跨端/状态断言": "不再单独维护处罚同意处理断言，统一以 S-FLOW-063 为准；本编号仅保留撤销结束子单处罚同意分支的链路引用。",
        "可组合/被引用关系": "不再作为独立处理逻辑；链路中统一引用 S-FLOW-063。",
        "备注": "已收束到 S-FLOW-063；撤销结束子单处罚同意赔偿也统一调取通用处罚同意用例。",
    },
    "S-FLOW-071": {
        "用例标题": "【已收束】撤销结束子单处罚驳回（引用S-FLOW-064）",
        "前置条件": "已执行撤销结束子单处罚发起用例 S-FLOW-069，目标处罚单进入待处理或处理中；处理动作统一引用 S-FLOW-064。",
        "执行步骤": "调用 S-FLOW-064【丸友集】通用子单处罚处理-驳回处罚。",
        "预期结果": "同 S-FLOW-064：丸友集侧处罚单已拒绝，处罚金额为0；丸掌柜侧子单处罚单同步已拒绝。",
        "跨端/状态断言": "不再单独维护处罚驳回处理断言，统一以 S-FLOW-064 为准；本编号仅保留撤销结束子单处罚驳回分支的链路引用。",
        "可组合/被引用关系": "不再作为独立处理逻辑；链路中统一引用 S-FLOW-064。",
        "备注": "已收束到 S-FLOW-064；撤销结束子单处罚驳回也统一调取通用处罚驳回用例。",
    },
}

FLOW_REPLACEMENTS = {
    "S-FLOW-070": "S-FLOW-063",
    "S-FLOW-071": "S-FLOW-064",
    "【丸友集】撤销结束子单处罚追缴-同意处罚/赔偿": "【丸友集】通用子单处罚处理-同意赔偿",
    "【丸友集】撤销结束子单处罚追缴-拒绝处罚/驳回申诉": "【丸友集】通用子单处罚处理-驳回处罚",
}


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 = item.get("用例编号")
        if case_id in CASE_UPDATES:
            item.update(CASE_UPDATES[case_id])
        for key in ["用例编号序列", "用例链路（编号+标题）", "可组合/被引用关系", "备注"]:
            value = item.get(key)
            if isinstance(value, str):
                item[key] = replace_flow_text(value)
    path.write_text(json.dumps(data, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")


def update_workbook(path: Path) -> None:
    wb = load_workbook(path)
    for ws in wb.worksheets:
        headers = {str(ws.cell(1, col).value or ""): col for col in range(1, ws.max_column + 1)}
        case_col = headers.get("用例编号")
        if case_col:
            for row in range(2, ws.max_row + 1):
                case_id = str(ws.cell(row, case_col).value or "")
                updates = CASE_UPDATES.get(case_id)
                if updates:
                    for header, value in updates.items():
                        col = headers.get(header)
                        if col:
                            ws.cell(row, col).value = value
        for row in range(2, ws.max_row + 1):
            for header in ["用例编号序列", "用例链路（编号+标题）", "可组合/被引用关系", "备注", "预期结果"]:
                col = headers.get(header)
                if col:
                    cell = ws.cell(row, col)
                    if isinstance(cell.value, str):
                        cell.value = replace_flow_text(cell.value)
            if ws.title == "链路步骤明细":
                case_id = str(ws.cell(row, headers.get("用例编号", 0)).value or "")
                if case_id in CASE_UPDATES:
                    for header in ["用例标题", "前置条件", "预期结果"]:
                        col = headers.get(header)
                        if col and header in CASE_UPDATES[case_id]:
                            ws.cell(row, col).value = CASE_UPDATES[case_id][header]
    wb.save(path)


def replace_flow_text(value: str) -> str:
    result = value
    for old, new in FLOW_REPLACEMENTS.items():
        result = result.replace(old, new)
    return result


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


if __name__ == "__main__":
    main()
