from __future__ import annotations

import copy
import shutil
from datetime import datetime
from pathlib import Path

from openpyxl import load_workbook
from openpyxl.styles import Alignment


ROOT = Path(__file__).resolve().parents[1]
WORKBOOK = ROOT / "SaaS_E2E测试用例_单Sheet用例测试列表.xlsx"
BACKUP_DIR = ROOT / "runtime" / "excel_backups"
SHEET_NAME = "订单状态流转"
HEADERS = [
    "用例编号",
    "用例层级",
    "来源/组合依据",
    "所属模块",
    "用例标题",
    "登录平台/角色账号",
    "前置条件",
    "测试数据",
    "执行步骤",
    "预期结果",
    "跨端/状态断言",
    "可组合/被引用关系",
    "自动化状态",
    "备注",
]


def numbered(items: list[str]) -> str:
    return "\n".join(f"{index}. {item}" for index, item in enumerate(items, 1))


def read_cases(sheet) -> list[dict[str, str]]:
    rows: list[dict[str, str]] = []
    for values in sheet.iter_rows(min_row=2, max_col=len(HEADERS), values_only=True):
        if not str(values[0] or "").startswith("S-FLOW-"):
            continue
        rows.append({header: str(values[index] or "") for index, header in enumerate(HEADERS)})
    return rows


def transition_case(base: dict[str, str], *, title: str, precondition: str, remark: str) -> dict[str, str]:
    item = copy.deepcopy(base)
    item["所属模块"] = "上游发单"
    item["来源/组合依据"] = "whiteboard_exported_image.png + 状态机对应关系梳理.html：【上游发单】"
    item["用例标题"] = title
    item["前置条件"] = precondition
    item["执行步骤"] = numbered(
        [
            "登录丸掌柜账号。",
            "进入丸掌柜-商家管理-订单管理。",
            "按来源单号或订单标题查询目标待接单订单。",
            "打开订单详情，记录推单前主单状态为待接单，子单状态为待接单-待推单。",
            "点击推单或发布到丸友集。",
            "选择可用丸友集推单策略并确认推单。",
            "在丸掌柜订单管理页面重新查询目标订单。",
            "记录丸掌柜主单订单状态。",
            "记录丸掌柜子单状态。",
            "登录丸友集账号，进入工作室履约应用-抢单大厅。",
            "按来源单号或订单标题查询目标订单，并记录丸友集父单状态。",
        ]
    )
    item["预期结果"] = numbered(
        [
            "丸掌柜主单订单状态仍为待接单。",
            "丸掌柜子单状态由待接单-待推单变为待接单-已推单。",
            "丸友集抢单大厅可以查询到该订单，丸友集父单状态为待接单。",
            "打手侧查询不到此单。",
        ]
    )
    item["跨端/状态断言"] = numbered(
        [
            "该用例核心状态变化为：待接单-待推单 -> 待接单-已推单。",
            "丸友集可见性从不可见变为抢单大厅可见。",
            "推单只创建工作室侧待接单父单，不应直接让打手产生订单。",
        ]
    )
    item["备注"] = remark
    return item


def transform(cases: list[dict[str, str]]) -> list[dict[str, str]]:
    by_id = {case["用例编号"]: case for case in cases}
    direct = transition_case(
        by_id["S-FLOW-005"],
        title="丸掌柜-主单待接单状态/待接单-待推单状态-直接推单到丸友集",
        precondition="已执行 S-FLOW-001，丸掌柜主单订单状态为待接单，子单状态为待接单-待推单，尚未发起售后。",
        remark="待推单分支转已推单分支：S-FLOW-001 后直接推单。",
    )
    after_cancel = transition_case(
        by_id["S-FLOW-005"],
        title="丸掌柜-主单待接单状态/待接单-待推单状态-取消售后后推单到丸友集",
        precondition="已从待接单-待推单状态发起售后并取消售后，当前主单恢复为待接单，子单恢复为待接单-待推单。",
        remark="待推单分支转已推单分支：主单售后取消后推单。",
    )

    front_order = ["S-FLOW-001", "S-FLOW-002", "S-FLOW-003", "S-FLOW-004"]
    updated = [copy.deepcopy(by_id[old_id]) for old_id in front_order]
    updated.extend([direct, after_cancel])
    updated.extend(copy.deepcopy(case) for case in cases if case["用例编号"] not in set(front_order + ["S-FLOW-005"]))

    for index, case in enumerate(updated, 1):
        case["用例编号"] = f"S-FLOW-{index:03d}"
    return updated


def write_cases(workbook, sheet, cases: list[dict[str, str]]) -> None:
    header_styles = [copy.copy(sheet.cell(row=1, column=index)._style) for index in range(1, len(HEADERS) + 1)]
    data_template_row = 2 if sheet.max_row >= 2 else 1
    data_styles = [copy.copy(sheet.cell(row=data_template_row, column=index)._style) for index in range(1, len(HEADERS) + 1)]

    if sheet.max_row > 1:
        sheet.delete_rows(2, sheet.max_row - 1)

    for column, header in enumerate(HEADERS, 1):
        cell = sheet.cell(row=1, column=column, value=header)
        cell._style = copy.copy(header_styles[column - 1])
        cell.alignment = Alignment(wrap_text=True, vertical="top")

    for row_index, case in enumerate(cases, 2):
        for column, header in enumerate(HEADERS, 1):
            cell = sheet.cell(row=row_index, column=column, value=case.get(header, ""))
            cell._style = copy.copy(data_styles[column - 1])
            cell.alignment = Alignment(wrap_text=True, vertical="top")

    sheet.freeze_panes = "A2"
    sheet.column_dimensions["I"].width = 55
    sheet.column_dimensions["J"].width = 45
    sheet.column_dimensions["K"].width = 45
    workbook.save(WORKBOOK)


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

    workbook = load_workbook(WORKBOOK)
    sheet = workbook[SHEET_NAME]
    cases = read_cases(sheet)
    updated = transform(cases)
    write_cases(workbook, sheet, updated)

    print(f"backup={backup}")
    print(f"old_count={len(cases)}")
    print(f"new_count={len(updated)}")
    for case in updated[:12]:
        print(f"{case['用例编号']}\t{case['所属模块']}\t{case['用例标题']}")


if __name__ == "__main__":
    main()
