from __future__ import annotations

import json
import shutil
from datetime import datetime
from pathlib import Path

from openpyxl import load_workbook


ROOT = Path(__file__).resolve().parents[1]
EXCEL_PATH = ROOT / "订单状态流转_链路流程线整理.xlsx"
BACKUP_DIR = ROOT / "runtime" / "excel_backups"
JSON_PATHS = [
    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_TEXTS = {
    "S-FLOW-034": {
        "所属模块": "丸掌柜发起售后",
        "用例标题": "【丸掌柜】子单异常中状态-子单发起售后",
        "前置条件": "已执行 S-FLOW-017，丸掌柜拒绝丸友集撤销后，丸掌柜订单详情子单列表中目标子单为异常中，且子单行内存在发起售后入口。",
        "执行步骤": "\n".join(
            [
                "1. 登录丸掌柜主账号或客服账号。",
                "2. 进入商家管理-订单管理。",
                "3. 按主单号、来源单号或订单标题查询目标订单。",
                "4. 打开订单详情并定位子单列表中订单状态为异常中的最新子单。",
                "5. 在该子单行内点击发起售后。",
                "6. 填写售后申请类型、售后金额、售后原因和凭证后提交。",
                "7. 登录丸友集主账号或客服账号。",
                "8. 进入工作室履约应用-订单列表。",
                "9. 按来源单号或上游单号查询目标订单，回读丸友集侧订单状态。",
            ]
        ),
        "预期结果": "\n".join(
            [
                "1. 丸掌柜订单详情中目标异常中子单进入售后中。",
                "2. 丸掌柜主单/子单售后信息保存售后金额、原因和凭证。",
                "3. 丸友集订单列表可查询到该订单，订单状态展示为售后中。",
                "4. 后续售后处理入口在丸友集订单列表【主单售后】中操作，不在丸掌柜侧处理。",
            ]
        ),
        "跨端/状态断言": "\n".join(
            [
                "1. 本用例验证子单行内发起售后，不等同于订单详情右下角主单售后。",
                "2. 丸掌柜负责发起售后；丸友集负责后续同意/拒绝售后。",
                "3. 丸掌柜和丸友集侧均必须回读到售后中状态。",
            ]
        ),
        "自动化状态": "已自动化",
    },
    "S-FLOW-036": {
        "所属模块": "丸友集处理售后",
        "用例标题": "【丸友集】子单异常中售后中状态-拒绝子单售后",
        "前置条件": "已执行 S-FLOW-034，丸掌柜已对异常中子单发起子单售后，丸友集订单列表中目标订单状态为售后中，操作列存在主单售后入口；售后客服非必填，若已添加客服但下拉选不中，需要记录缺陷后继续拒绝流程。",
        "执行步骤": "\n".join(
            [
                "1. 登录丸友集主账号或客服账号。",
                "2. 进入工作室履约应用-订单列表。",
                "3. 按来源单号或上游单号查询目标订单。",
                "4. 如该丸友集企业下已有客服但售后客服下拉选不中，则记录缺陷；售后客服非必填，不阻断拒绝流程。",
                "5. 确认目标订单状态为售后中。",
                "6. 点击操作列【主单售后】。",
                "7. 在订单售后处理弹窗中核对上游要求退回金额、售后原因和凭证，售后客服可不选择。",
                "8. 点击【拒绝】。",
                "9. 在二次弹框中填写拒绝原因并点击确认。",
                "10. 回到丸友集订单列表，按来源单号回读订单状态。",
                "11. 登录丸掌柜账号，进入订单详情回读主单、子单和子单列表状态。",
            ]
        ),
        "预期结果": "\n".join(
            [
                "1. 丸友集侧拒绝售后提交后，目标订单在丸友集订单列表仍展示为售后中。",
                "2. 丸掌柜订单详情仍展示该笔售后为售后中。",
                "3. 丸掌柜子单列表最新目标子单仍展示为售后中。",
                "4. 拒绝原因在售后记录或订单日志中可追溯；若售后客服下拉选不中，需要记录缺陷但不阻断本用例。",
            ]
        ),
        "跨端/状态断言": "\n".join(
            [
                "1. S-FLOW-036 的实际操作方是丸友集，不是丸掌柜。",
                "2. 操作入口为丸友集-工作室履约应用-订单列表-主单售后-拒绝。",
                "3. 点击【拒绝】后必须填写拒绝原因并确认提交。",
                "4. 丸友集和丸掌柜侧最终均回读售后中状态。",
                "5. 售后客服为非必填项；下拉选不中时记录缺陷后继续流程。",
            ]
        ),
        "自动化状态": "已自动化",
    },
    "S-FLOW-035": {
        "所属模块": "丸友集处理售后",
        "用例标题": "【丸友集】子单异常中售后中状态-同意子单售后",
        "前置条件": "已执行 S-FLOW-034，丸掌柜已对异常中子单发起子单售后，丸友集订单列表中目标订单状态为售后中，操作列存在主单售后入口；丸友集企业下存在已注册/已审核通过的客服角色成员，可在售后客服下拉中选择。",
        "执行步骤": "\n".join(
            [
                "1. 登录丸友集主账号或客服账号。",
                "2. 进入工作室履约应用-订单列表。",
                "3. 按来源单号或上游单号查询目标订单。",
                "4. 如该丸友集企业下没有客服角色成员，则先通过企业管理-成员管理邀请客服角色用户注册并完成审核。",
                "5. 确认目标订单状态为售后中。",
                "6. 点击操作列【主单售后】。",
                "7. 在订单售后处理弹窗中选择售后客服。",
                "8. 核对上游要求退回金额、售后原因和凭证。",
                "9. 点击【同意】并提交售后处理。",
                "10. 回到丸友集订单列表，按来源单号回读订单状态。",
                "11. 登录丸掌柜账号，进入订单详情回读主单、子单、子单列表和售后结果。",
                "12. 在丸掌柜订单详情确认主单仍展示【继续发单】入口。",
                "13. 在丸掌柜订单详情确认售后结束的目标子单展示【处罚】入口。",
            ]
        ),
        "预期结果": "\n".join(
            [
                "1. 丸友集侧目标订单同意售后后进入售后结束/售后处理完成的实际终态。",
                "2. 丸掌柜订单详情主单状态展示为异常中，子单状态展示为代练中异常。",
                "3. 丸掌柜子单列表中目标子单订单状态展示为售后结束，售后详情展示“售后处理完成”和退款金额。",
                "4. 售后金额、售后原因、处理结果在丸掌柜和丸友集侧一致。",
                "5. 该异常中子单售后处理完成后，不能再按售后中状态重复处理。",
                "6. 售后结束后，丸掌柜主单仍可继续发单；售后结束的目标子单可进入处罚后续分支。",
            ]
        ),
        "跨端/状态断言": "\n".join(
            [
                "1. S-FLOW-035 的实际操作方是丸友集，不是丸掌柜。",
                "2. 操作入口为丸友集-工作室履约应用-订单列表-主单售后-同意。",
                "3. 售后客服下拉无数据时，应先补客服角色成员前置，不应继续提交同意/拒绝。",
                "4. 同意处理后需同时回读丸友集订单列表和丸掌柜订单详情。",
                "5. 丸友集侧回读目标订单售后结束/售后处理完成状态。",
                "6. 丸掌柜侧回读主单异常中、子单代练中异常、目标子单售后结束。",
                "7. S-FLOW-035 后续可承接“售后结束后主单继续发单”和“售后结束子单处罚”两类分支。",
            ]
        ),
        "自动化状态": "已自动化",
    },
}


def update_json_files() -> None:
    for path in JSON_PATHS:
        if not path.exists():
            continue
        data = json.loads(path.read_text(encoding="utf-8"))
        for item in data:
            case_id = item.get("用例编号")
            if case_id in CASE_TEXTS:
                item.update(CASE_TEXTS[case_id])
        path.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")


def update_excel() -> None:
    BACKUP_DIR.mkdir(parents=True, exist_ok=True)
    backup = BACKUP_DIR / f"{EXCEL_PATH.stem}.before_s_flow_035_036_aftersale_{datetime.now():%Y%m%d-%H%M%S}.xlsx"
    shutil.copy2(EXCEL_PATH, backup)

    wb = load_workbook(EXCEL_PATH)
    for sheet_name in ["用例覆盖索引", "原始用例索引", "链路步骤明细"]:
        ws = wb[sheet_name]
        headers = {str(cell.value): cell.column for cell in ws[1] if cell.value}
        id_col = headers.get("用例编号")
        if not id_col:
            continue
        for row in range(2, ws.max_row + 1):
            case_id = ws.cell(row, id_col).value
            if case_id not in CASE_TEXTS:
                continue
            for field, value in CASE_TEXTS[case_id].items():
                col = headers.get(field)
                if col:
                    ws.cell(row, col).value = value

    ws = wb["链路流程线"]
    headers = {str(cell.value): cell.column for cell in ws[1] if cell.value}
    chain_col = headers.get("用例链路（编号+标题）")
    seq_col = headers.get("用例编号序列")
    name_col = headers.get("链路名称")
    note_col = headers.get("注意事项/缺口")
    for row in range(2, ws.max_row + 1):
        seq = str(ws.cell(row, seq_col).value or "") if seq_col else ""
        if "S-FLOW-034" not in seq:
            continue
        if chain_col:
            chain = str(ws.cell(row, chain_col).value or "")
            for case_id, texts in CASE_TEXTS.items():
                if case_id in chain:
                    parts = chain.split(case_id, 1)
                    if len(parts) == 2:
                        suffix = parts[1].split(" -> ", 1)
                        old_fragment = case_id + suffix[0]
                        new_fragment = f"{case_id} {texts['用例标题']}"
                        chain = chain.replace(old_fragment, new_fragment)
            ws.cell(row, chain_col).value = chain
        if name_col and "异常中发起售后" in str(ws.cell(row, name_col).value or ""):
            ws.cell(row, name_col).value = str(ws.cell(row, name_col).value).replace(
                "异常中发起售后",
                "异常中子单发起售后并由丸友集处理",
            )
        if note_col:
            note = str(ws.cell(row, note_col).value or "")
            add = "S-FLOW-035/036 的实际处理入口在丸友集订单列表【主单售后】，不是丸掌柜侧处理售后。"
            if add not in note:
                ws.cell(row, note_col).value = (note + "\n" + add).strip()

    wb.save(EXCEL_PATH)
    print(f"updated: {EXCEL_PATH}")
    print(f"backup: {backup}")


def main() -> None:
    update_json_files()
    update_excel()


if __name__ == "__main__":
    main()
