package com.zombie.game.systems;

import com.zombie.game.ecs.ECSWorld;
import com.zombie.game.ecs.System;
import com.zombie.game.ecs.components.*;

import static com.zombie.game.model.Constants.*;

/**
 * Processes player input to update positions and aim angles.
 * 处理玩家输入以更新位置和瞄准角度。
 */
public class PlayerInputSystem implements System {

    @Override
    public void update(float dt, ECSWorld world) {
        // Iterate over all player entities / 遍历所有玩家实体
        for (int entityId : world.getPlayers()) {
            // Retrieve components for this entity / 获取该实体的组件
            PlayerInput input = world.getPlayerInputs().get(entityId);
            Position pos = world.getPositions().get(entityId);
            Health health = world.getHealths().get(entityId);

            // Skip if any required component is missing or player is dead / 若缺少必要组件或玩家已死亡则跳过
            if (input == null || pos == null || health == null || !health.isAlive()) continue;

            // Calculate movement speed based on tick interval / 根据 tick 间隔计算移动速度
            float speed = PLAYER_SPEED * TICK_INTERVAL;
            // Compute new position from input direction / 根据输入方向计算新位置
            float newX = pos.getX() + input.getDx() * speed;
            float newY = pos.getY() + input.getDy() * speed;

            // Update X position if walkable, clamped to grid bounds / 若可行走则更新 X 位置，限制在网格边界内
            if (world.getMap().isWalkable(newX, pos.getY(), PLAYER_SIZE)) {
                pos.setX(Math.max(0.5f, Math.min(GRID_SIZE - 0.5f, newX)));
            }
            // Update Y position if walkable, clamped to grid bounds / 若可行走则更新 Y 位置，限制在网格边界内
            if (world.getMap().isWalkable(pos.getX(), newY, PLAYER_SIZE)) {
                pos.setY(Math.max(0.5f, Math.min(GRID_SIZE - 0.5f, newY)));
            }

            // Update facing angle based on aim direction / 根据瞄准方向更新朝向角度
            pos.setAngle((float) Math.atan2(input.getAimX() - pos.getX(), input.getAimY() - pos.getY()));
        }
    }
}
