# 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"\moving-circle-animation-demo"
backup_path = task_directory + r"\before-moving-circle-demo.cas.h5"

target_time = 2.2
max_chunks = 10
results = []

def show_result(label, result):
    print("\n--- " + label + " ---")
    print(repr(result))

def needs_review(obj):
    if isinstance(obj, dict):
        if obj.get("needs_review") is True:
            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
        if obj.get("all_steps_converged") is False:
            return True
        for value in obj.values():
            if needs_review(value):
                return True
    elif isinstance(obj, (list, tuple)):
        for value in obj:
            if needs_review(value):
                return True
    return False

def find_time(obj):
    keys = (
        "final_time",
        "flow_time",
        "physical_time",
        "current_physical_time",
        "current_time",
        "actual_time",
        "simulation_time"
    )
    if isinstance(obj, dict):
        for key in keys:
            value = obj.get(key)
            if isinstance(value, (int, float)):
                return float(value)
        for value in obj.values():
            result = find_time(value)
            if result is not None:
                return result
    elif isinstance(obj, (list, tuple)):
        for value in obj:
            result = find_time(value)
            if result is not None:
                return result
    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 main():
    print("=== 二维圆形物体运动动画 ===")
    print("任务目录:", task_directory)
    print("独立算例:", case_directory)
    print("目标物理时间:", target_time)
    print("保留原算例，不重复执行失败的颗粒追踪。")

    # 1. 备份当前求解器状态。
    try:
        active = solver.is_active()
        print("当前求解器 active:", active)
        if not active:
            print("求解器不活跃，停止操作。")
            return

        backup = solver.settings.file.write_case_data(
            file_name=backup_path
        )
        show_result("原算例 Case/Data 备份", backup)
        if needs_review(backup):
            print("备份返回异常，停止替换模型。")
            return
    except Exception as exc:
        print("备份失败，未继续替换模型:", repr(exc))
        return

    # 2. 创建独立的二维动态网格算例。
    try:
        setup = fluentagi.prepare_moving_circle(
            directory=case_directory,
            include_target=True,
            body_diameter=0.06,
            target_diameter=0.04,
            speed=0.1,
            ramp_time=0.4,
            end_time=target_time,
            time_step=0.005,
            size=0.012,
            replace_loaded_model=True
        )
        show_result("动态网格与运动配置", setup)
        results.append(setup)
    except Exception as exc:
        print("动态网格配置异常，不初始化:", repr(exc))
        return

    if needs_review(setup):
        print("配置状态需要复核，停止。")
        return

    # 3. 检查网格，再对新算例初始化一次。
    try:
        mesh_check = solver.settings.mesh.check()
        show_result("网格检查", mesh_check)
        if needs_review(mesh_check):
            print("网格检查返回异常，停止初始化。")
            return
    except Exception as exc:
        print("网格检查失败，停止初始化:", repr(exc))
        return

    try:
        init_result = fluentagi.initialize_moving_body(
            directory=case_directory
        )
        show_result("新算例初始化", init_result)
        results.append(init_result)
    except Exception as exc:
        print("初始化异常，不自动重试:", repr(exc))
        return

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

    # 4. 读取实际初始时间。
    try:
        state = fluentagi.read_moving_body(
            directory=case_directory
        )
        show_result("初始原生状态", state)
        results.append(state)
    except Exception as exc:
        print("初始状态读取失败:", repr(exc))
        return

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

    current_time = find_time(state)
    if current_time is None:
        print("未读取到真实物理时间，停止推进。")
        return

    print("初始真实物理时间:", current_time)

    # 5. 每批最多推进 50 步；每批后回读实际时间。
    for chunk in range(max_chunks):
        if current_time >= target_time - 1e-10:
            print("已达到目标物理时间。")
            break

        print(
            "\n推进批次:", chunk + 1,
            "当前时间:", current_time,
            "目标时间:", target_time
        )

        try:
            advance = fluentagi.advance_moving_body(
                directory=case_directory,
                steps=50,
                until_time=target_time,
                max_iter_per_step=100
            )
            show_result("动态网格推进结果", advance)
            results.append(advance)
        except Exception as exc:
            print("推进异常，停止，不盲目重放:", repr(exc))
            break

        if needs_review(advance):
            print("推进结果要求复核，停止后续计算。")
            break

        try:
            state = fluentagi.read_moving_body(
                directory=case_directory
            )
            show_result("推进后原生状态", state)
            results.append(state)
        except Exception as exc:
            print("状态回读失败，停止推进:", repr(exc))
            break

        if needs_review(state):
            print("原生状态要求复核，停止后续计算。")
            break

        next_time = find_time(state)
        if next_time is None:
            print("未取得推进后的实际物理时间，停止。")
            break

        if next_time <= current_time + 1e-12:
            print("物理时间未证实前进，停止以防重复计算。")
            break

        current_time = next_time
        print("已核实物理时间:", current_time)

    # 6. 读取最终原生状态及实际返回的 GIF 路径。
    try:
        final_state = fluentagi.read_moving_body(
            directory=case_directory
        )
        show_result("最终原生状态", final_state)
        results.append(final_state)
    except Exception as exc:
        print("最终状态读取失败:", repr(exc))
        return

    gif_paths = list(dict.fromkeys(find_gifs(results)))
    final_time = find_time(final_state)

    print("\n=== 最终核验 ===")
    print("目标物理时间:", target_time)
    print("最终实际物理时间:", final_time)
    print("GIF 路径:", gif_paths)
    print("算例目录:", case_directory)
    print("运动类型: 预设速度的圆形物体平移")
    print("压力输出: 以运动壁面上的指定弧段为测量区域")
    print("物理精度和网格无关性尚需独立验证。")

    if not gif_paths:
        print("当前返回结果未包含可确认的 GIF 路径。")
    if final_time is None or final_time < target_time - 1e-8:
        print("尚未证实达到目标物理时间。")

main()