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]]:
    cases: 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
        cases.append({header: str(values[index] or "") for index, header in enumerate(HEADERS)})
    return cases


def normalize_title(title: str) -> str:
    result = str(title or "")
    if result.startswith("丸掌柜-"):
        result = "【丸掌柜】" + result[len("丸掌柜-") :]
    result = result.replace("【丸掌柜】主单待接单状态/待接单-待推单状态", "【丸掌柜】主单待接单状态/子单待接单-待推单状态")
    result = result.replace("【丸掌柜】主单待接单状态/待接单-已推单状态", "【丸掌柜】主单待接单状态/子单待接单-已推单状态")
    result = result.replace("丸掌柜视角-", "【丸掌柜】")
    return result


def normalize_text(value: str) -> str:
    result = str(value or "")
    result = result.replace("丸掌柜-", "【丸掌柜】")
    result = result.replace("丸掌柜视角-", "【丸掌柜】")
    result = result.replace("主单待接单状态/待接单-待推单状态", "主单待接单状态/子单待接单-待推单状态")
    result = result.replace("主单待接单状态/待接单-已推单状态", "主单待接单状态/子单待接单-已推单状态")
    return result


def create_dispatched_case(base: dict[str, str]) -> dict[str, str]:
    item = copy.deepcopy(base)
    item["所属模块"] = "上游发单"
    item["来源/组合依据"] = "whiteboard_exported_image.png + 状态机对应关系梳理.html：【上游发单】"
    item["用例标题"] = "【丸掌柜】主单待接单状态/子单待接单-已推单状态-创建主单已推单"
    item["前置条件"] = "丸掌柜账号可创建外来订单；手工录单页面选择推单，并存在可用丸友集推单策略。"
    item["执行步骤"] = numbered(
        [
            "登录丸掌柜账号。",
            "进入丸掌柜-商家管理-订单管理。",
            "点击手工录单，填写主单订单来源、来源单号、订单标题、游戏、区服、服务项目、价格、联系方式等必填信息。",
            "在手工录单页面选择推单。",
            "选择可用丸友集推单策略并填写子单发单信息。",
            "提交订单。",
            "在丸掌柜订单管理页面，按来源单号或订单标题查询目标订单。",
            "点击主单号进入订单详情。",
            "记录丸掌柜主单订单状态。",
            "记录丸掌柜子单状态。",
            "登录丸友集账号，进入工作室履约应用-抢单大厅。",
            "按来源单号或订单标题查询目标订单，并记录丸友集父单状态。",
        ]
    )
    item["预期结果"] = numbered(
        [
            "丸掌柜主单订单状态为待接单。",
            "丸掌柜子单状态为待接单-已推单。",
            "丸友集抢单大厅可以查询到该订单，丸友集父单状态为待接单。",
            "打手侧查询不到此单。",
        ]
    )
    item["跨端/状态断言"] = numbered(
        [
            "创建主单同时推单会创建子单，并将子单推送到丸友集。",
            "主单状态保持待接单，子单状态为待接单-已推单。",
            "丸友集可见性为抢单大厅可见，但不应直接生成打手订单。",
        ]
    )
    item["备注"] = "已推单分支起点：创建主单时同时创建子单并推单到丸友集。"
    return item


def transform(cases: list[dict[str, str]]) -> list[dict[str, str]]:
    normalized: list[dict[str, str]] = []
    for case in cases:
        item = copy.deepcopy(case)
        for header in HEADERS:
            item[header] = normalize_text(item[header])
        item["用例标题"] = normalize_title(item["用例标题"])
        normalized.append(item)

    by_id = {case["用例编号"]: case for case in normalized}
    create_case = create_dispatched_case(by_id["S-FLOW-005"])

    front_order = ["S-FLOW-001", "S-FLOW-002", "S-FLOW-003", "S-FLOW-004", "S-FLOW-005", "S-FLOW-006"]
    updated = [copy.deepcopy(by_id[old_id]) for old_id in front_order]
    updated.append(create_case)
    used = set(front_order)
    updated.extend(copy.deepcopy(case) for case in normalized if case["用例编号"] not in used)

    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_title_bracket_create_dispatched_{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[:14]:
        print(f"{case['用例编号']}\t{case['所属模块']}\t{case['用例标题']}")


if __name__ == "__main__":
    main()
