#version 330 core

in vec2 vTexCoord;
in vec3 vWorldPos;

uniform sampler2D texture0;

// --- Soft bubble (kept) ---
uniform vec3  u_playerPos;
uniform float u_inner;
uniform float u_outer;
uniform float u_minShadow;

// --- Flashlight cone + distance ---
uniform vec3  u_spotDir;     // normalized camera forward
uniform float u_spotCos;     // cos(half-angle)
uniform float u_spotSoft;    // base penumbra width in cos-space
uniform float u_lightRange;  // bright zone distance (>0)
uniform float u_lightFade;   // fade width beyond range

// --- NEW: decouple brightness + widen with distance ---
uniform float u_intensity;   // flashlight peak brightness (independent of range)
uniform float u_beamSpread;  // additional penumbra growth per unit distance (0..~0.5)

// Alpha cut (trees, grass)
uniform float u_alphaCutoff;

out vec4 finalColor;

// Helpers
float remap01(float x, float a, float b) {
    return clamp((x - a) / max(b - a, 1e-5), 0.0, 1.0);
}
float invsq(float d, float r) {
    float s = d / max(r, 1e-4);
    return 1.0 / (1.0 + s*s);
}

void main() {
    vec4 texel = texture(texture0, vTexCoord);
    if (texel.a < u_alphaCutoff) discard;

    float dist = length(vWorldPos - u_playerPos);

    // (A) Soft ambient bubble around the player (unchanged)
    float bubble  = 1.0 - remap01(dist, u_inner, u_outer);          // 1 near, 0 far
    float ambient = mix(1.0 - clamp(u_minShadow,0.0,1.0), 0.0, 1.0 - bubble);

    // (B) Flashlight cone with penumbra + distance drop + widening
    vec3  L        = normalize(vWorldPos - u_playerPos);
    float cosTheta = dot(normalize(u_spotDir), L);

    // Widen penumbra with distance so long ranges don't look like a laser
    float distNorm = dist / max(u_lightRange, 1e-4);
    float softWide = clamp(u_spotSoft + u_beamSpread * distNorm, 0.0, 0.8);

    float innerEdge = u_spotCos;
    float outerEdge = clamp(u_spotCos - softWide, -1.0, 1.0);

    float spotA = smoothstep(outerEdge, innerEdge, cosTheta);
    spotA *= spotA;  // mild hotspot

    // Distance attenuation: inverse-square * soft fade band
    float band   = 1.0 - remap01(dist, u_lightRange, u_lightRange + u_lightFade);
    float lightD = invsq(dist, u_lightRange) * band;

    // Decoupled brightness
    float flashlight = u_intensity * spotA * lightD;

    // Compose
    float light = clamp(ambient + flashlight, 0.0, 1.0);
    finalColor  = vec4(texel.rgb * light, texel.a);
}
