from __future__ import annotations

from pathlib import Path

import openpyxl
from openpyxl.styles import Alignment, Font, PatternFill
from openpyxl.utils import get_column_letter


OUTPUT = Path("功能测试用例_售后图片与撤销图片.xlsx")
SHEET_NAME = "功能测试用例"
HEADERS = [
    "用例编号",
    "需求模块",
    "功能点",
    "用例标题",
    "测试类型",
    "登录平台/角色",
    "前置条件",
    "测试数据",
    "执行步骤",
    "预期结果",
    "备注",
]


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


ROWS = [
    [
        "FEATURE-AFTERSALE-IMAGE-001",
        "丸掌柜售后新增图片",
        "上传入口展示",
        "丸掌柜发起售后时展示图片上传控件",
        "功能测试",
        "丸掌柜：企业主账号",
        "存在一笔可发起售后的订单。",
        "主单号/来源单号。",
        steps(
            [
                "登录丸掌柜，进入订单管理，搜索目标订单。",
                "点击【发起售后】。",
                "查看售后弹框内是否存在图片上传控件。",
            ]
        ),
        "售后弹框中存在图片上传控件。",
        "纯功能测试，暂不接自动化流程。",
    ],
    [
        "FEATURE-AFTERSALE-IMAGE-002",
        "丸掌柜售后新增图片",
        "非必填校验",
        "丸掌柜发起售后时图片非必填",
        "功能测试",
        "丸掌柜：企业主账号",
        "存在一笔可发起售后的订单。",
        "主单号/来源单号、售后原因、售后金额。",
        steps(
            [
                "登录丸掌柜，进入订单管理，搜索目标订单。",
                "点击【发起售后】。",
                "填写售后原因、售后金额，不上传图片直接提交。",
                "观察是否出现图片必填校验。",
            ]
        ),
        "不上传图片也可以正常提交，不出现图片必填校验。",
        "按需求原文：图片非必填。",
    ],
    [
        "FEATURE-AFTERSALE-IMAGE-003",
        "丸掌柜售后新增图片",
        "上传数量边界",
        "丸掌柜发起售后时上传 1 张图片可正常提交",
        "功能测试",
        "丸掌柜：企业主账号",
        "存在一笔可发起售后的订单。",
        "主单号/来源单号、售后原因、售后金额、图片 1 张。",
        steps(
            [
                "登录丸掌柜，进入订单管理，搜索目标订单。",
                "点击【发起售后】。",
                "上传 1 张图片并提交。",
                "查看提交结果。",
            ]
        ),
        "上传 1 张图片后可以正常提交。",
        "数量下界。",
    ],
    [
        "FEATURE-AFTERSALE-IMAGE-004",
        "丸掌柜售后新增图片",
        "上传数量边界",
        "丸掌柜发起售后时上传 5 张图片可正常提交",
        "功能测试",
        "丸掌柜：企业主账号",
        "存在一笔可发起售后的订单。",
        "主单号/来源单号、售后原因、售后金额、图片 5 张。",
        steps(
            [
                "登录丸掌柜，进入订单管理，搜索目标订单。",
                "点击【发起售后】。",
                "上传 5 张图片并提交。",
                "查看提交结果。",
            ]
        ),
        "上传 5 张图片后可以正常提交。",
        "数量上界。",
    ],
    [
        "FEATURE-AFTERSALE-IMAGE-005",
        "丸掌柜售后新增图片",
        "售后记录展示",
        "丸掌柜发起售后后售后记录中展示售后图片",
        "功能测试",
        "丸掌柜：企业主账号",
        "已成功发起一笔带图片的售后。",
        "主单号/来源单号、售后图片。",
        steps(
            [
                "登录丸掌柜，进入目标订单详情。",
                "查看售后记录或售后信息区块。",
                "确认是否展示售后图片。",
            ]
        ),
        "售后记录/售后信息中可查看售后图片。",
        "需求原文明确要求售后记录也要加图。",
    ],
    [
        "FEATURE-AFTERSALE-IMAGE-006",
        "丸掌柜售后新增图片",
        "订单日志展示",
        "丸掌柜发起售后后订单日志中记录售后图片",
        "功能测试",
        "丸掌柜：企业主账号",
        "已成功发起一笔带图片的售后。",
        "主单号/来源单号、售后图片。",
        steps(
            [
                "登录丸掌柜，进入目标订单详情。",
                "查看订单日志/操作日志。",
                "确认日志中是否记录售后图片相关信息。",
            ]
        ),
        "订单日志/操作日志中记录售后图片相关内容。",
        "需求原文明确要求订单日志也要加图。",
    ],
    [
        "FEATURE-AFTERSALE-IMAGE-007",
        "丸掌柜售后新增图片",
        "下游查看能力",
        "丸友集处理主单售后时可查看售后图片",
        "功能测试",
        "丸友集：工作室主账号",
        "上游已发起一笔带图片的主单售后。",
        "主单号/来源单号、售后图片。",
        steps(
            [
                "登录丸友集，进入工作室履约应用-订单列表。",
                "搜索售后中的目标订单。",
                "点击【主单售后】进入处理弹框。",
                "查看是否可见上游上传的售后图片。",
            ]
        ),
        "丸友集处理主单售后时可查看售后图片。",
        "这是查看型需求。",
    ],
    [
        "FEATURE-AFTERSALE-IMAGE-008",
        "丸掌柜售后新增图片",
        "图片位置",
        "丸友集处理主单售后时售后图片位于售后原因上方",
        "功能测试",
        "丸友集：工作室主账号",
        "上游已发起一笔带图片的主单售后。",
        "主单号/来源单号、售后图片。",
        steps(
            [
                "登录丸友集，进入主单售后处理弹框。",
                "观察图片区域与售后原因字段的相对位置。",
            ]
        ),
        "售后图片展示区域位于售后原因上方。",
        "这是布局约束。",
    ],
    [
        "FEATURE-AFTERSALE-IMAGE-009",
        "丸掌柜售后新增图片",
        "只读限制",
        "丸友集处理主单售后时售后图片仅支持查看不支持编辑",
        "功能测试",
        "丸友集：工作室主账号",
        "上游已发起一笔带图片的主单售后。",
        "主单号/来源单号、售后图片。",
        steps(
            [
                "登录丸友集，进入主单售后处理弹框。",
                "检查图片区域是否存在替换、删除、重新上传等入口。",
            ]
        ),
        "售后图片仅支持查看，不支持编辑、删除、替换。",
        "这是只读约束。",
    ],
    [
        "FEATURE-REVOKE-IMAGE-001",
        "丸友集撤销新增图片",
        "原因必填校验",
        "丸友集申请撤销时撤销原因由选填改为必填",
        "功能测试",
        "丸友集：工作室主账号",
        "存在一笔可申请撤销的订单。",
        "主单号/来源单号、撤销金额。",
        steps(
            [
                "登录丸友集，进入订单列表，搜索目标订单。",
                "点击【申请撤销】。",
                "只填写撤销金额，不填写撤销原因直接提交。",
                "查看页面校验。",
            ]
        ),
        "不填写撤销原因时不能提交，页面提示撤销原因必填。",
        "需求原文明确：撤销原因从选填改为必填。",
    ],
    [
        "FEATURE-REVOKE-IMAGE-002",
        "丸友集撤销新增图片",
        "上传入口展示",
        "丸友集申请撤销时展示撤销图片上传控件",
        "功能测试",
        "丸友集：工作室主账号",
        "存在一笔可申请撤销的订单。",
        "主单号/来源单号。",
        steps(
            [
                "登录丸友集，进入订单列表，搜索目标订单。",
                "点击【申请撤销】。",
                "查看撤销弹框是否存在图片上传控件。",
            ]
        ),
        "撤销弹框中存在图片上传控件。",
        "这是展示型需求。",
    ],
    [
        "FEATURE-REVOKE-IMAGE-003",
        "丸友集撤销新增图片",
        "非必填校验",
        "丸友集申请撤销时撤销图片非必填",
        "功能测试",
        "丸友集：工作室主账号",
        "存在一笔可申请撤销的订单。",
        "主单号/来源单号、撤销金额、撤销原因。",
        steps(
            [
                "登录丸友集，进入订单列表，搜索目标订单。",
                "点击【申请撤销】。",
                "填写撤销金额、撤销原因，不上传撤销图片直接提交。",
                "观察是否出现图片必填校验。",
            ]
        ),
        "不上传撤销图片也可正常提交，不出现图片必填校验。",
        "按需求原文：图片非必填。",
    ],
    [
        "FEATURE-REVOKE-IMAGE-004",
        "丸友集撤销新增图片",
        "订单日志展示",
        "丸友集申请撤销后订单日志中记录撤销图片",
        "功能测试",
        "丸友集：工作室主账号；丸掌柜：企业主账号",
        "已成功提交一笔带撤销图片的申请撤销。",
        "主单号/来源单号、撤销图片。",
        steps(
            [
                "在丸友集侧提交带图片的撤销申请。",
                "登录丸掌柜，进入目标订单详情。",
                "查看订单日志/操作日志。",
            ]
        ),
        "订单日志/操作日志中记录撤销图片相关内容。",
        "需求原文明确要求图片要记录订单日志。",
    ],
    [
        "FEATURE-REVOKE-IMAGE-005",
        "丸友集撤销新增图片",
        "处理端查看能力",
        "丸掌柜处理撤销时可查看撤销图片",
        "功能测试",
        "丸掌柜：企业主账号",
        "丸友集已提交一笔带图片的撤销申请。",
        "主单号/来源单号、撤销图片。",
        steps(
            [
                "登录丸掌柜，进入目标订单详情或待处理列表。",
                "点击处理撤销入口。",
                "查看是否可见丸友集上传的撤销图片。",
            ]
        ),
        "丸掌柜处理撤销时可查看撤销图片。",
        "这是处理端查看需求。",
    ],
    [
        "FEATURE-REVOKE-IMAGE-006",
        "丸友集撤销新增图片",
        "处理端只读限制",
        "丸掌柜处理撤销时撤销图片仅支持查看不支持编辑",
        "功能测试",
        "丸掌柜：企业主账号",
        "丸友集已提交一笔带图片的撤销申请。",
        "主单号/来源单号、撤销图片。",
        steps(
            [
                "登录丸掌柜，进入撤销处理页面或处理弹框。",
                "检查图片区域是否存在替换、删除、重新上传等入口。",
            ]
        ),
        "撤销图片仅支持查看，不支持编辑、删除、替换。",
        "这是处理端只读约束。",
    ],
    [
        "FEATURE-REVOKE-IMAGE-007",
        "丸友集撤销新增图片",
        "处理结果日志回写",
        "丸掌柜处理撤销后订单日志记录撤销图片、撤销原因、撤销结果",
        "功能测试",
        "丸掌柜：企业主账号",
        "丸友集已提交撤销申请；丸掌柜已完成一次撤销处理。",
        "主单号/来源单号、撤销图片、撤销原因、撤销结果。",
        steps(
            [
                "登录丸掌柜，处理目标撤销申请。",
                "处理完成后进入订单详情。",
                "查看订单日志/操作日志。",
                "核对撤销图片、撤销原因、撤销结果记录。",
            ]
        ),
        "订单日志/操作日志中同时记录撤销图片、撤销原因、撤销结果。",
        "这是处理后回写需求。",
    ],
]


def build_workbook() -> openpyxl.Workbook:
    workbook = openpyxl.Workbook()
    sheet = workbook.active
    sheet.title = SHEET_NAME

    header_fill = PatternFill("solid", fgColor="4472C4")
    header_font = Font(color="FFFFFF", bold=True)
    body_alignment = Alignment(vertical="top", wrap_text=True)

    for col, header in enumerate(HEADERS, start=1):
        cell = sheet.cell(1, col, header)
        cell.fill = header_fill
        cell.font = header_font
        cell.alignment = body_alignment

    for row_index, values in enumerate(ROWS, start=2):
        for col_index, value in enumerate(values, start=1):
            cell = sheet.cell(row_index, col_index, value)
            cell.alignment = body_alignment

    widths = {
        "A": 24,
        "B": 24,
        "C": 18,
        "D": 34,
        "E": 14,
        "F": 24,
        "G": 30,
        "H": 28,
        "I": 56,
        "J": 38,
        "K": 26,
    }
    for column, width in widths.items():
        sheet.column_dimensions[column].width = width

    sheet.freeze_panes = "A2"
    return workbook


def main() -> None:
    workbook = build_workbook()
    workbook.save(OUTPUT)
    print(f"generated {OUTPUT} with {len(ROWS)} cases")


if __name__ == "__main__":
    main()
