from __future__ import annotations

from pathlib import Path

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


ROOT = Path(__file__).resolve().parents[1]
EXCEL_PATH = ROOT / "测试用例" / "SaaS_订阅邀请登录_测试功能点.xlsx"
FALLBACK_PATH = ROOT / "测试用例" / "SaaS_订阅邀请登录_流程用例_应用版本管理.xlsx"
SHEET_NAME = "流程用例-应用版本管理"


COLUMNS = [
    "用例编号",
    "链路模块",
    "用例标题",
    "优先级",
    "入口路径",
    "前置条件",
    "测试数据",
    "流程步骤",
    "预期结果/回读断言",
    "自动化脚本建议",
    "当前实走依据",
]


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


ROWS = [
    [
        "APPVER-FLOW-001",
        "应用管理-应用列表新-版本管理",
        "新增应用版本后在版本列表回读",
        "P0",
        "SaaS-admin -> 应用管理 -> 应用列表新 -> 目标应用 -> 版本管理",
        lines(
            [
                "管理员账号已登录 SaaS-admin",
                "应用列表新中存在目标应用：结算中心",
                "目标应用可打开版本管理弹窗",
            ]
        ),
        "版本名称：自动化版本_{时间戳}；状态：启用；版本说明：自动化新增应用版本",
        lines(
            [
                "进入应用管理-应用列表新",
                "在目标应用行点击版本管理",
                "在应用版本管理弹窗点击新增版本",
                "在新增应用版本弹窗填写版本名称，状态保持启用，填写版本说明",
                "点击保存",
                "返回应用版本管理弹窗左侧版本列表",
                "选择新建版本并观察右侧资源区域",
            ]
        ),
        lines(
            [
                "新增应用版本弹窗关闭或保存成功提示出现",
                "左侧应用版本列表出现新建版本",
                "新版本状态展示为启用",
                "选择新版本后右侧资源区域正常刷新",
                "关闭后再次进入版本管理，新版本仍可回读",
            ]
        ),
        "封装 navigate_to_new_app_list、open_version_manager、create_app_version、assert_version_visible。版本名称使用时间戳避免重复。",
        "用户实走截图：新增应用版本弹窗包含版本名称、状态、版本说明、取消、保存。",
    ],
    [
        "APPVER-FLOW-002",
        "应用管理-应用列表新-版本管理",
        "编辑应用版本后在版本卡片回读",
        "P0",
        "SaaS-admin -> 应用管理 -> 应用列表新 -> 目标应用 -> 版本管理",
        lines(
            [
                "管理员账号已登录 SaaS-admin",
                "目标应用至少存在一个可编辑版本",
                "已打开应用版本管理弹窗",
            ]
        ),
        "版本名称：自动化编辑版本_{时间戳}；版本说明：自动化编辑说明；状态：启用或禁用",
        lines(
            [
                "在应用版本管理弹窗左侧选择目标版本",
                "点击编辑版本",
                "修改版本名称和版本说明",
                "按当前页面能力切换或保持状态",
                "点击保存",
                "回到版本列表查看目标版本卡片",
                "关闭版本管理后重新进入，再次查看目标版本",
            ]
        ),
        lines(
            [
                "编辑保存成功",
                "版本列表卡片展示更新后的版本名称",
                "版本状态与保存时一致",
                "重新进入版本管理后，修改内容仍可回读",
            ]
        ),
        "编辑用例复用 open_version_manager 和 assert_version_visible；状态切换如果控件不稳定，先只断言名称和说明回读。",
        "依据当前弹窗：左侧版本列表存在编辑版本按钮，版本卡片展示名称、资源数、引用数、状态。",
    ],
    [
        "APPVER-FLOW-003",
        "应用管理-应用列表新-版本管理",
        "维护当前版本资源并保存后回读绑定状态",
        "P0",
        "SaaS-admin -> 应用管理 -> 应用列表新 -> 目标应用 -> 版本管理",
        lines(
            [
                "管理员账号已登录 SaaS-admin",
                "目标应用存在至少一个版本",
                "右侧资源区域存在可查询资源，例如菜单资源：结算中心",
            ]
        ),
        "资源名称：结算中心；资源类型：菜单；资源状态：启用或全部状态",
        lines(
            [
                "打开目标应用的版本管理弹窗",
                "在左侧选择目标版本",
                "在右侧资源区按资源名称、类型或状态查询目标资源",
                "勾选或取消目标资源",
                "点击保存当前版本资源",
                "关闭版本管理弹窗",
                "重新进入版本管理并选择同一版本",
                "查询同一资源并查看勾选状态",
            ]
        ),
        lines(
            [
                "资源查询结果正确展示目标资源",
                "保存当前版本资源成功",
                "重新进入后目标资源绑定状态与保存时一致",
                "左侧版本卡片资源数随绑定结果更新",
                "已选资源数量和原已绑定数量展示符合实际",
            ]
        ),
        "资源绑定是这条链路最重要的回读断言。建议封装 search_resource、toggle_resource_binding、save_current_version_resources、assert_resource_checked。",
        "用户实走截图：右侧资源区域有搜索框、类型下拉、状态下拉、查询、全选当前筛选结果、保存当前版本资源。",
    ],
]


def style_sheet(ws) -> None:
    header_fill = PatternFill("solid", fgColor="305496")
    header_font = Font(color="FFFFFF", bold=True)
    for cell in ws[1]:
        cell.fill = header_fill
        cell.font = header_font
        cell.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)

    widths = [18, 28, 34, 10, 42, 42, 36, 52, 52, 48, 42]
    for index, width in enumerate(widths, 1):
        ws.column_dimensions[get_column_letter(index)].width = width

    for row in ws.iter_rows(min_row=2):
        for cell in row:
            cell.alignment = Alignment(vertical="top", wrap_text=True)
    ws.freeze_panes = "A2"
    ws.auto_filter.ref = ws.dimensions


def populate_workbook(wb) -> None:
    if SHEET_NAME in wb.sheetnames:
        del wb[SHEET_NAME]
    ws = wb.create_sheet(SHEET_NAME, 0)
    ws.append(COLUMNS)
    for row in ROWS:
        ws.append(row)
    style_sheet(ws)


def main() -> None:
    wb = load_workbook(EXCEL_PATH)
    populate_workbook(wb)
    try:
        wb.save(EXCEL_PATH)
        print(f"updated={EXCEL_PATH}")
    except PermissionError:
        from openpyxl import Workbook

        fallback = Workbook()
        fallback.remove(fallback.active)
        populate_workbook(fallback)
        fallback.save(FALLBACK_PATH)
        print(f"locked={EXCEL_PATH}")
        print(f"fallback={FALLBACK_PATH}")
    print(f"sheet={SHEET_NAME}")
    print(f"cases={len(ROWS)}")


if __name__ == "__main__":
    main()
