package me.earthme.luminol.config.modules.optimizations;

import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.enums.EnumConfigCategory;

/**
 * Frustum / distance entity culling — stops sending entity packets for entities that are
 * outside the player's view cone and far enough away that the player cannot see them.
 *
 * <p>Vanilla (and Paper/Folia) decide entity visibility purely by distance: every entity within
 * the tracking range is paired with the player and receives spawn/move/metadata packets, even when
 * it is directly behind the player. In dense scenes (many players fighting, large zombie hordes)
 * this means each client receives a flood of packets for entities it is not even looking at.
 *
 * <p>This module adds a cheap angular gate inside {@code ChunkMap.TrackedEntity.updatePlayer}: an
 * entity is culled (not paired / unpaired) when the angle between the player's facing direction and
 * the player→entity vector exceeds {@code half_fov_degrees}, AND the entity is farther than
 * {@code near_radius} blocks. Entities within {@code near_radius} are always sent (so something
 * spawning right behind the player never pops in late), and players/vehicles are never culled.
 *
 * <p>Horizontal (yaw) only by default — vertical culling is off because looking up/down is common
 * and players expect entities above/below to stay loaded. Folia-safe: runs on the entity's own
 * region thread inside the existing tracker update; reads only the player's rotation/position.
 */
@ConfigClassInfo(category = EnumConfigCategory.OPTIMIZATIONS, name = "entity_cull")
public class EntityCullConfig implements IConfigModule {

    @ConfigInfo(name = "enabled", comments = "Stop sending entity packets for entities outside the player's view cone (beyond near_radius).")
    public static boolean enabled = false;

    @ConfigInfo(name = "half_fov_degrees", comments = "Half-angle of the view cone in degrees. Entities whose bearing from the player's facing exceeds this are culled when beyond near_radius. 70 ~= a generous 140-degree cone (wider than the client FOV, leaves headroom for quick turns).")
    public static double halfFovDegrees = 70.0D;

    @ConfigInfo(name = "near_radius", comments = "Entities within this many blocks are ALWAYS sent regardless of angle (prevents point-blank pop-in behind the player).")
    public static double nearRadius = 16.0D;

    @ConfigInfo(name = "cull_players", comments = "Whether to also cull other players. Off by default — PvP needs every player visible the moment they round a corner.")
    public static boolean cullPlayers = false;

    @ConfigInfo(name = "cull_vehicles", comments = "Whether to cull boats/minecarts. Off by default to avoid riding-into-loaded-area hitches.")
    public static boolean cullVehicles = false;

    @ConfigInfo(name = "vertical_culling", comments = "Also apply the cone test vertically (pitch). Off by default; vertical look changes are frequent and cheap to mis-cull.")
    public static boolean verticalCulling = false;
}
