package com.zombie.game.server;

import com.zombie.game.ecs.ECSWorld;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Game loop running at fixed tick rate for a single room / 以固定帧率运行的游戏循环，为单个房间服务
 */
public class GameLoop {
    // Room ID this loop serves / 该循环服务的房间ID
    private String roomId;
    // The ECS world being updated / 正在更新的ECS世界
    private ECSWorld world;
    // Callback to broadcast state each tick / 每帧广播状态的回调
    private GameService.GameStateBroadcast broadcaster;
    // Whether the loop is currently running / 循环当前是否正在运行
    private volatile boolean running;
    // Target tick rate (30 ticks per second) / 目标帧率（每秒30帧）
    private static final int TICK_RATE = 30;
    // Interval between ticks in milliseconds / 帧间隔（毫秒）
    private static final long TICK_INTERVAL_MS = 1000 / TICK_RATE;
    // Interval between ticks in seconds / 帧间隔（秒）
    private static final float TICK_INTERVAL_SEC = 1.0f / TICK_RATE;
    // Scheduler for running the loop / 运行循环的调度器
    private ScheduledExecutorService scheduler;

    // Constructor: sets up the game loop for a room / 构造函数：为房间设置游戏循环
    public GameLoop(String roomId, ECSWorld world, GameService.GameStateBroadcast broadcaster) {
        this.roomId = roomId;
        this.world = world;
        this.broadcaster = broadcaster;
        this.running = true;
        // Create single-threaded daemon scheduler / 创建单线程守护调度器
        this.scheduler = Executors.newSingleThreadScheduledExecutor(r -> {
            Thread t = new Thread(r, "GameLoop-" + roomId);
            t.setDaemon(true);
            return t;
        });
    }

    // Start the game loop / 启动游戏循环
    public void start() {
        scheduler.scheduleAtFixedRate(this::tick, 0, TICK_INTERVAL_MS, TimeUnit.MILLISECONDS);
    }

    // Single tick: update world and broadcast state / 单帧：更新世界并广播状态
    private void tick() {
        if (!running) return;
        synchronized (world.getLock()) {
            world.update(TICK_INTERVAL_SEC);
        }
        broadcaster.broadcast(roomId, world);
    }

    // Stop the game loop / 停止游戏循环
    public void stop() {
        running = false;
        if (scheduler != null && !scheduler.isShutdown()) {
            scheduler.shutdown();
            try {
                // Force shutdown if graceful shutdown fails / 优雅关闭失败则强制关闭
                if (!scheduler.awaitTermination(1, TimeUnit.SECONDS)) {
                    scheduler.shutdownNow();
                }
            } catch (InterruptedException e) {
                scheduler.shutdownNow();
            }
        }
    }
}
