# Use the existing connected PyFluent variable solver.
# Continue with the complete executable script here.

task_directory = r"C:\Users\13977\AppData\Local\FluentAGI\data\runs\20261020-131312-807b38"
case_directory = task_directory + r"\water-air-filling-demo"
backup_path = task_directory + r"\before-water-air-filling-demo.cas.h5"

length = 0.05
width = 0.02
height = 0.02
mesh_size = 0.004
velocity = 0.05
time_step = 0.001
frames = 30
steps_per_frame = 10
max_iter_per_step = 20

results = []

def show(label, value):
    print("\n--- " + label + " ---")
    print(repr(value))

def has_failure(obj):
    if isinstance(obj, dict):
        if obj.get("needs_review") is True:
            return True
        if obj.get("all_steps_converged") is False:
            return True
        for key in ("status", "run_status"):
            if str(obj.get(key, "")).lower() in (
                "failed", "error", "aborted", "needs_review"
            ):
                return True
        if obj.get("errors"):
            return True
        for value in obj.values():
            if has_failure(value):
                return True
    elif isinstance(obj, (list, tuple)):
        for value in obj:
            if has_failure(value):
                return True
    return False

def find_value(obj, wanted_key):
    if isinstance(obj, dict):
        if wanted_key in obj and isinstance(obj[wanted_key], str):
            return obj[wanted_key]
        for value in obj.values():
            found = find_value(value, wanted_key)
            if found:
                return found
    elif isinstance(obj, (list, tuple)):
        for value in obj:
            found = find_value(value, wanted_key)
            if found:
                return found
    return None

def find_gifs(obj):
    paths = []
    if isinstance(obj, str):
        if obj.lower().endswith(".gif"):
            paths.append(obj)
    elif isinstance(obj, dict):
        for value in obj.values():
            paths.extend(find_gifs(value))
    elif isinstance(obj, (list, tuple)):
        for value in obj:
            paths.extend(find_gifs(value))
    return paths

def water_is_phase2(obj):
    if isinstance(obj, dict):
        identity = " ".join(
            str(obj.get(key, ""))
            for key in ("phase", "name", "tag", "phase_name")
        ).lower().replace("_", "-")
        material = " ".join(
            str(obj.get(key, ""))
            for key in ("material", "material_name", "assigned_material")
        ).lower()

        if "phase-2" in identity and "water-liquid" in material:
            return True

        for key, value in obj.items():
            normalized_key = str(key).lower().replace("_", "-")
            if (
                "phase-2" in normalized_key
                and "water-liquid" in str(value).lower()
            ):
                return True
            if water_is_phase2(value):
                return True

    elif isinstance(obj, (list, tuple)):
        for value in obj:
            if water_is_phase2(value):
                return True

    return False

def main():
    print("=== 三维水箱充水 VOF 动画 ===")
    print("任务目录:", task_directory)
    print("独立算例目录:", case_directory)
    print("现有求解器维度: 3D")
    print("原有结果保留；不重试二维运动适配器。")

    # 1. 检查连接并备份当前 Case/Data。
    try:
        if not solver.is_active():
            print("当前求解器不活跃，停止操作。")
            return

        backup = solver.settings.file.write_case_data(
            file_name=backup_path
        )
        show("当前 Case/Data 备份", backup)
        print("备份目标:", backup_path)

    except Exception as exc:
        print("备份失败，停止操作:", repr(exc))
        return

    # 2. 为独立算例生成真实三维四面体网格。
    try:
        mesh_result = fluentagi.build_volume(
            directory=case_directory,
            shape="box",
            length=length,
            width=width,
            height=height,
            size=mesh_size,
            mesh_type="tet"
        )
        show("三维网格生成结果", mesh_result)
        results.append(mesh_result)

    except Exception as exc:
        print("网格生成失败:", repr(exc))
        return

    if has_failure(mesh_result):
        print("网格生成结果需要复核，停止。")
        return

    mesh_file = find_value(mesh_result, "mesh_file")
    if not mesh_file:
        print("未取得明确的 Fluent 网格文件路径，停止。")
        return

    # 3. 读取新网格并执行网格检查。
    try:
        read_result = solver.settings.file.read_mesh(
            file_name=mesh_file
        )
        show("读取 Fluent 网格", read_result)

        check_result = solver.settings.mesh.check()
        show("网格检查", check_result)
        results.extend([read_result, check_result])

    except Exception as exc:
        print("读取或检查网格失败:", repr(exc))
        return

    if has_failure(check_result):
        print("网格检查异常，停止配置物理模型。")
        return

    # 4. 配置水-空气两相 VOF。
    try:
        physics = fluentagi.configure_water_air(
            directory=case_directory,
            velocity=velocity,
            time_step=time_step,
            gravity_y=-9.81,
            inlet="inlet",
            outlet="outlet"
        )
        show("水-空气 VOF 配置", physics)
        results.append(physics)

    except Exception as exc:
        print("VOF 配置失败:", repr(exc))
        return

    if has_failure(physics):
        print("VOF 配置需要复核，停止。")
        return

    # 5. 必须确认 phase-2 确实是 water-liquid。
    try:
        phase_state = fluentagi.inspect_phases()
        show("实际气液相映射", phase_state)
        results.append(phase_state)

    except Exception as exc:
        print("无法核实气液相映射，停止初始化:", repr(exc))
        return

    if not water_is_phase2(phase_state):
        print("未能确认 phase-2=water-liquid。")
        print("为避免显示错误的体积分数，不执行初始化或动画。")
        return

    # 6. 仅初始化这个新建算例，不初始化原有结果。
    try:
        init_result = fluentagi.initialize_air(
            directory=case_directory
        )
        show("新算例初始化", init_result)
        results.append(init_result)

    except Exception as exc:
        print("初始化失败，不自动重复:", repr(exc))
        return

    if has_failure(init_result):
        print("初始化状态需要复核，停止推进。")
        return

    # 7. 创建内部 Z 中截面，用水相体积分数展示充水过程。
    try:
        section = fluentagi.create_section(
            axis="z",
            position=height / 2.0
        )
        show("内部截面", section)

    except Exception as exc:
        print("创建内部截面失败，停止动画:", repr(exc))
        return

    if not isinstance(section, dict) or not section.get("surface"):
        print("未取得有效的截面名称，停止动画。")
        return

    # 8. 动画会真实推进瞬态求解；每次返回后检查状态。
    try:
        animation = fluentagi.record_animation(
            directory=case_directory,
            field="phase-2-vof",
            frames=frames,
            steps_per_frame=steps_per_frame,
            max_iter_per_step=max_iter_per_step,
            surfaces=[section["surface"]]
        )
        show("水相体积分数动画", animation)
        results.append(animation)

    except Exception as exc:
        print("动画推进或导出异常，不盲目重试:", repr(exc))
        return

    # 9. 导出截面压力和速度结果，不额外推进计算。
    try:
        export_result = fluentagi.export_results(
            directory=case_directory,
            fields=["pressure", "velocity-magnitude"],
            surfaces=[section["surface"]]
        )
        show("截面结果导出", export_result)
        results.append(export_result)

    except Exception as exc:
        print("截面结果导出失败:", repr(exc))

    # 10. 汇总实际返回的文件与状态。
    gif_paths = list(dict.fromkeys(find_gifs(results)))

    print("\n=== 最终核验 ===")
    print("算例目录:", case_directory)
    print("动画帧数:", frames)
    print("每帧间隔推进步数:", steps_per_frame)
    print("时间步长:", time_step)
    print(
        "计划动画物理时长:",
        (frames - 1) * steps_per_frame * time_step,
        "s"
    )
    print("实际返回的 GIF 路径:", gif_paths)
    print("动画返回状态需要复核:", has_failure(animation))

    if not gif_paths:
        print("尚未取得可确认的 GIF 文件路径。")

    if has_failure(animation):
        print("动画结果需要检查残差、质量守恒及原生求解状态。")

    print("截面动画仅代表 Z 中截面，不是完整三维体渲染。")
    print("当前模拟时长有限，不宣称水箱已完全充满。")

main()