from __future__ import annotations

from pathlib import Path

from openpyxl import load_workbook


FLOW_XLSX = Path("测试用例") / "订单状态流转_链路流程线整理.xlsx"

FLOW_STEPS = {
    "FLOW-019": [
        "S-FLOW-007",
        "S-FLOW-014",
        "S-FLOW-021",
        "S-FLOW-026",
        "S-FLOW-078",
        "S-FLOW-033",
        "S-FLOW-017",
        "S-FLOW-034",
        "S-FLOW-035",
        "S-FLOW-051",
    ],
    "FLOW-020": [
        "S-FLOW-007",
        "S-FLOW-014",
        "S-FLOW-021",
        "S-FLOW-026",
        "S-FLOW-078",
        "S-FLOW-033",
        "S-FLOW-017",
        "S-FLOW-034",
        "S-FLOW-036",
    ],
}

NOTES = {
    "S-FLOW-026": "FLOW-019/020 不再从本用例直接接 S-FLOW-033，需先执行 S-FLOW-078 形成异常/撤销相关前置。",
    "S-FLOW-078": "新增承接 FLOW-019、FLOW-020：S-FLOW-026 后先撤销代练中子单，再进入 S-FLOW-033 主单申请上游撤销。",
    "S-FLOW-033": "前置由 S-FLOW-026 代练中调整为 S-FLOW-078 后异常/撤销相关状态；代练中不能直接申请上游撤销。",
    "S-FLOW-017": "FLOW-019/020 中承接 S-FLOW-033 后的撤销中状态；先处理/取消撤销，使子单落到异常中/发单方取消撤销，再接 S-FLOW-034。",
}


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


def find_row(ws, column: int, value: str) -> int | None:
    for row in range(2, ws.max_row + 1):
        if str(ws.cell(row, column).value or "").strip() == value:
            return row
    return None


def append_note(existing: object, note: str) -> str:
    old = str(existing or "").strip()
    if note in old:
        return old
    return f"{old}\n{note}".strip()


def main() -> None:
    workbook = load_workbook(FLOW_XLSX)
    summary = workbook["链路流程线"]
    detail = workbook["链路步骤明细"]
    coverage = workbook["用例覆盖索引"]
    raw = workbook["原始用例索引"]

    raw_h = headers(raw)
    source: dict[str, dict[str, object]] = {}
    for row in range(2, raw.max_row + 1):
        case_id = str(raw.cell(row, raw_h["用例编号"]).value or "").strip()
        if case_id.startswith("S-FLOW-"):
            source[case_id] = {name: raw.cell(row, col).value for name, col in raw_h.items()}

    summary_h = headers(summary)
    for flow_id, steps in FLOW_STEPS.items():
        row = find_row(summary, summary_h["链路编号"], flow_id)
        assert row is not None, f"Missing flow row: {flow_id}"
        summary.cell(row, summary_h["用例编号序列"]).value = " -> ".join(steps)
        summary.cell(row, summary_h["用例链路（编号+标题）"]).value = " -> ".join(
            f"{case_id}({source.get(case_id, {}).get('用例标题', case_id)})" for case_id in steps
        )
        modules: list[str] = []
        for case_id in steps:
            module = source.get(case_id, {}).get("所属模块")
            if module and module not in modules:
                modules.append(str(module))
        summary.cell(row, summary_h["涉及模块"]).value = " -> ".join(modules)
        summary.cell(row, summary_h["注意事项/缺口"]).value = append_note(
            summary.cell(row, summary_h["注意事项/缺口"]).value,
            "2026-06-30 修正：丸友集申请上游撤销必须承接 S-FLOW-078 后的异常/撤销相关状态；S-FLOW-033 后需先执行 S-FLOW-017 处理/取消撤销，使子单从撤销中落到异常中/发单方取消撤销，再进入 S-FLOW-034。",
        )

    detail_h = headers(detail)
    kept_rows = []
    for row in range(2, detail.max_row + 1):
        flow_id = str(detail.cell(row, detail_h["链路编号"]).value or "").strip()
        if flow_id not in FLOW_STEPS:
            kept_rows.append([detail.cell(row, col).value for col in range(1, detail.max_column + 1)])
    for flow_id, steps in FLOW_STEPS.items():
        for index, case_id in enumerate(steps, 1):
            src = source.get(case_id, {})
            kept_rows.append(
                [
                    flow_id,
                    index,
                    case_id,
                    src.get("所属模块"),
                    src.get("用例标题"),
                    src.get("前置条件"),
                    src.get("预期结果"),
                ]
            )
    if detail.max_row > 1:
        detail.delete_rows(2, detail.max_row - 1)
    for row_values in kept_rows:
        detail.append(row_values)

    appearances: dict[str, list[str]] = {}
    for row in range(2, summary.max_row + 1):
        flow_id = str(summary.cell(row, summary_h["链路编号"]).value or "").strip()
        sequence = str(summary.cell(row, summary_h["用例编号序列"]).value or "")
        for case_id in [item.strip() for item in sequence.split("->") if item.strip()]:
            appearances.setdefault(case_id, []).append(flow_id)

    coverage_h = headers(coverage)
    for row in range(2, coverage.max_row + 1):
        case_id = str(coverage.cell(row, coverage_h["用例编号"]).value or "").strip()
        if case_id in appearances:
            coverage.cell(row, coverage_h["覆盖次数"]).value = len(appearances[case_id])
            coverage.cell(row, coverage_h["出现链路"]).value = "、".join(appearances[case_id])
            coverage.cell(row, coverage_h["是否已覆盖"]).value = "是"
        if case_id in NOTES:
            coverage.cell(row, coverage_h["备注"]).value = append_note(
                coverage.cell(row, coverage_h["备注"]).value,
                NOTES[case_id],
            )

    workbook.save(FLOW_XLSX)
    print(FLOW_XLSX)


if __name__ == "__main__":
    main()
