from __future__ import annotations

import json
from pathlib import Path

import openpyxl


ROOT = Path(__file__).resolve().parents[1]
CASE_JSON = ROOT / "scripts" / "order_status_flow_cases.json"
CASE_WORKBOOK = ROOT / "测试用例" / "SaaS_E2E测试用例_单Sheet用例测试列表.xlsx"
FLOW_WORKBOOK = ROOT / "测试用例" / "订单状态流转_链路流程线整理.xlsx"


CASE_UPDATES = {
    "S-FLOW-040": {
        "用例层级": "订单状态流转用例",
        "来源/组合依据": "whiteboard_exported_image.png + 状态机对应关系梳理.html：【订单验收】",
        "所属模块": "订单验收",
        "用例标题": "【打手视角】打手代练中 / 丸友集子单代练中 / 丸掌柜主单服务中 / 子单代练中 - 申请验收",
        "登录平台/角色账号": "丸掌柜：企业主账号或客服账号；丸友集：工作室主账号或客服账号；打手：打手子账号。",
        "前置条件": "打手订单处于代练中，已上号并已上传首图；丸友集子单仍在履约中，丸掌柜主单仍为服务中。",
        "测试数据": "来源单号、订单标题、丸掌柜主单号、丸友集父单号、打手子单号、验收说明和验收凭证。",
        "执行步骤": "\n".join(
            [
                "1. 登录打手账号。",
                "2. 进入打手应用-我的订单。",
                "3. 按来源单号查询目标订单。",
                "4. 打开目标订单操作菜单，确认订单状态为代练中。",
                "5. 如存在确认上号入口，先完成确认上号。",
                "6. 如存在上传首图入口，上传首图并确认。",
                "7. 点击提交验收或申请验收。",
                "8. 填写验收说明并确认提交。",
                "9. 回到打手应用-我的订单，按来源单号回查目标订单状态。",
                "10. 登录丸友集账号，进入工作室履约应用-订单列表，按来源单号查询目标订单。",
                "11. 登录丸掌柜账号，进入订单管理详情，记录主单和子单状态。",
            ]
        ),
        "预期结果": "\n".join(
            [
                "1. 打手订单状态变为待验收。",
                "2. 丸友集目标子单状态变为待验收，或订单列表子单统计出现验收中数量。",
                "3. 丸友集父单仍为代练中或页面整体履约状态。",
                "4. 丸掌柜主单仍为服务中。",
                "5. 丸掌柜子单仍为代练中或服务中，不因打手提交验收直接进入待验收。",
            ]
        ),
        "跨端/状态断言": "\n".join(
            [
                "1. 打手申请验收只推进丸友集子单验收，不穿透到福通和丸掌柜待验收。",
                "2. 丸友集需要单独验收打手子单，之后才可申请上游验收。",
                "3. 查询必须按来源单号定位目标订单，不能把来源单号填入主单号字段。",
            ]
        ),
        "可组合/被引用关系": "FLOW-023、FLOW-024、FLOW-025、FLOW-026 等验收链路引用。",
        "自动化状态": "已自动化",
        "备注": "2026-07-01修正：该编号在 FLOW-023 链路中表示打手提交验收，不是丸友集申请上游验收。",
    },
    "S-FLOW-041": {
        "用例层级": "订单状态流转用例",
        "来源/组合依据": "whiteboard_exported_image.png + 状态机对应关系梳理.html：【订单验收】",
        "所属模块": "订单验收",
        "用例标题": "【打手视角】打手待验收 / 丸友集子单待验收 / 丸掌柜主单服务中 / 子单代练中 - 取消验收",
        "登录平台/角色账号": "丸掌柜：企业主账号或客服账号；丸友集：工作室主账号或客服账号；打手：打手子账号。",
        "前置条件": "打手已提交验收，丸友集尚未同意或拒绝该打手子单验收。",
        "测试数据": "来源单号、订单标题、丸掌柜主单号、丸友集父单号、打手子单号、取消验收原因。",
        "执行步骤": "\n".join(
            [
                "1. 登录打手账号。",
                "2. 进入打手应用-我的订单。",
                "3. 按来源单号查询目标待验收订单。",
                "4. 打开目标订单操作菜单，确认存在取消验收或撤回验收入口。",
                "5. 点击取消验收。",
                "6. 填写取消原因并确认。",
                "7. 回到打手应用-我的订单，按来源单号回查目标订单状态。",
                "8. 登录丸友集账号，进入工作室履约应用-订单列表，按来源单号查询目标订单。",
                "9. 登录丸掌柜账号，进入订单管理详情，记录主单和子单状态。",
            ]
        ),
        "预期结果": "\n".join(
            [
                "1. 打手订单状态恢复为代练中。",
                "2. 丸友集目标子单恢复为代练中或页面对应继续履约状态。",
                "3. 丸掌柜主单仍为服务中。",
                "4. 丸掌柜子单仍为代练中或服务中。",
                "5. 取消验收原因可追溯。",
            ]
        ),
        "跨端/状态断言": "\n".join(
            [
                "1. 取消验收不影响福通和丸掌柜上游状态。",
                "2. 取消后不能残留待验收作为目标子单当前状态。",
                "3. 订单可继续进入打手撤销、取消订单或再次提交验收等代练中分支。",
            ]
        ),
        "可组合/被引用关系": "FLOW-023 专用回退节点；验收取消后回到打手代练中分支。",
        "自动化状态": "已自动化",
        "备注": "2026-07-01修正：该编号在 FLOW-023 链路中表示打手取消验收恢复代练中。",
    },
}


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


def update_case_json() -> None:
    cases = json.loads(CASE_JSON.read_text(encoding="utf-8"))
    for item in cases:
        case_id = str(item.get("用例编号", "")).strip()
        if case_id in CASE_UPDATES:
            item.update(CASE_UPDATES[case_id])
    CASE_JSON.write_text(json.dumps(cases, ensure_ascii=False, indent=2), encoding="utf-8")


def update_rows_by_case_id(workbook_path: Path) -> None:
    workbook = openpyxl.load_workbook(workbook_path)
    try:
        for sheet in workbook.worksheets:
            headers = headers_for(sheet)
            case_col = headers.get("用例编号")
            if not case_col:
                continue
            for row in range(2, sheet.max_row + 1):
                case_id = str(sheet.cell(row, case_col).value or "").strip()
                updates = CASE_UPDATES.get(case_id)
                if not updates:
                    continue
                for header, value in updates.items():
                    column = headers.get(header)
                    if column:
                        cell = sheet.cell(row, column)
                        cell.value = value
                        cell.alignment = cell.alignment.copy(wrap_text=True, vertical="top")
        workbook.save(workbook_path)
    finally:
        workbook.close()


def load_case_map_from_workbook() -> dict[str, dict[str, str]]:
    workbook = openpyxl.load_workbook(CASE_WORKBOOK, data_only=True)
    try:
        sheet = workbook["订单状态流转"]
        headers = headers_for(sheet)
        case_col = headers["用例编号"]
        result: dict[str, dict[str, str]] = {}
        for row in range(2, sheet.max_row + 1):
            case_id = str(sheet.cell(row, case_col).value or "").strip()
            if not case_id:
                continue
            result[case_id] = {
                header: str(sheet.cell(row, column).value or "")
                for header, column in headers.items()
            }
        return result
    finally:
        workbook.close()


def update_flow_summary() -> None:
    case_map = load_case_map_from_workbook()
    workbook = openpyxl.load_workbook(FLOW_WORKBOOK)
    try:
        sheet = workbook["链路流程线"]
        headers = headers_for(sheet)
        sequence_col = headers.get("用例编号序列")
        ref_col = headers.get("用例链路（编号+标题）")
        module_col = headers.get("涉及模块")
        if not sequence_col:
            return
        for row in range(2, sheet.max_row + 1):
            sequence = str(sheet.cell(row, sequence_col).value or "")
            case_ids = [part.strip() for part in sequence.split("->") if part.strip()]
            if not any(case_id in CASE_UPDATES for case_id in case_ids):
                continue
            if ref_col:
                sheet.cell(row, ref_col).value = " -> ".join(
                    f"{case_id}({case_map.get(case_id, {}).get('用例标题', '')})"
                    for case_id in case_ids
                )
            if module_col:
                modules: list[str] = []
                for case_id in case_ids:
                    module = case_map.get(case_id, {}).get("所属模块", "")
                    if module and module not in modules:
                        modules.append(module)
                sheet.cell(row, module_col).value = " -> ".join(modules)
        workbook.save(FLOW_WORKBOOK)
    finally:
        workbook.close()


def main() -> None:
    update_case_json()
    update_rows_by_case_id(CASE_WORKBOOK)
    update_rows_by_case_id(FLOW_WORKBOOK)
    update_flow_summary()
    print("Synced FLOW-023 acceptance cases: S-FLOW-040, S-FLOW-041")


if __name__ == "__main__":
    main()
