/**
 * GLSL Shaders for SpotlightBorder effect
 * Uses Signed Distance Functions (SDFs) with aspect-correct coordinates
 * Supports larger canvas for external glow and suppresses inner glow.
 */
const vertexShader = /* glsl */ `
varying vec2 v_texcoord;
void main() {
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    v_texcoord = uv;
}
`;
const fragmentShader = /* glsl */ `
varying vec2 v_texcoord;

uniform vec2 u_mouse;
uniform vec2 u_resolution;         // Canvas resolution
uniform vec2 u_contentResolution;  // Card/Content resolution
uniform vec2 u_offset;             // Pixel offset of content within canvas
uniform float u_pixelRatio;
uniform vec3 u_color;

uniform float u_shapeSize;
uniform float u_roundness;
uniform float u_borderSize;
uniform float u_spotlightSize;
uniform float u_spotlightEdge;
uniform float u_glowIntensity;

#ifndef PI
#define PI 3.1415926535897932384626433832795
#endif
#ifndef TWO_PI
#define TWO_PI 6.2831853071795864769252867665590
#endif

#ifndef VAR
#define VAR 0
#endif

// Signed Distance Function for rounded box
float sdRoundedBox(vec2 p, vec2 b, float r) {
    vec2 q = abs(p) - b + r;
    return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - r;
}

// Signed Distance Function for circle
float sdCircle(vec2 p, float r) {
    return length(p) - r;
}

// Signed Distance Function for equilateral triangle
float sdPoly(vec2 p, float r, int sides) {
    float an = PI / float(sides);
    float en = TWO_PI / float(sides);
    float he = r * tan(0.5 * an);
    float a = atan(p.x, -p.y) + an; 
    float bn = floor(a / en);
    a -= (bn + 0.5) * en;
    p = length(p) * vec2(cos(a), sin(a));
    return p.x * cos(an) - p.y * sin(an) - r * cos(an);
}

// Smooth stroke with anti-aliasing
float smoothStroke(float d, float width, float pixelSize) {
    float halfWidth = width * 0.5;
    float alpha = smoothstep(halfWidth + pixelSize, halfWidth - pixelSize, abs(d));
    return alpha;
}

// Smooth fill
float smoothFill(float d, float pixelSize) {
    return 1.0 - smoothstep(-pixelSize, pixelSize, d);
}

void main() {
    // 1. Setup Coordinates relative to CONTENT area
    // gl_FragCoord is in canvas pixels. We subtract offset to get relative to card.
    vec2 fragRelative = gl_FragCoord.xy - u_offset;
    vec2 uv = fragRelative / u_contentResolution.xy;
    
    // We want the shader to be centered at 0.5 in CONTENT area
    float aspect = u_contentResolution.x / u_contentResolution.y;
    vec2 p = (uv - 0.5) * vec2(aspect, 1.0);
    
    // Mouse setup (mouse is also relative to card)
    vec2 mouseUV = u_mouse * u_pixelRatio / u_contentResolution.xy;
    vec2 m = (mouseUV - 0.5) * vec2(aspect, 1.0);
    m.y *= -1.0; 
    
    // 2. Shape Parameters
    vec2 boxSize = vec2(aspect, 1.0) * 0.5 * u_shapeSize;
    float pixelSize = 1.0 / u_contentResolution.y; 
    
    // 3. Mouse Interaction (Spotlight)
    float mouseDist = length(p - m);
    
    // Spotlight follows mouse - reveal factor
    float spotlight = smoothstep(u_spotlightSize + u_spotlightEdge, u_spotlightSize * 0.1, mouseDist);
    
    // 4. Draw Shape
    float d = 0.0;
    float borderAlpha = 0.0;
    float glowAlpha = 0.0;
    
    if (VAR == 0) {
        // Correctly scale corner radius by the shortest dimension in p-space
        float radius = u_roundness * 0.5 * min(aspect, 1.0);
        d = sdRoundedBox(p, boxSize, radius);
        
        // Sharp border stroke
        float strokeD = d + u_borderSize * 0.5;
        borderAlpha = smoothStroke(strokeD, u_borderSize, pixelSize * 2.0);
        
        // Gradual glow - ONLY OUTSIDE (d > 0)
        float glowRadius = u_borderSize * 15.0; 
        if (d > 0.0) {
            glowAlpha = exp(-d / (glowRadius * 0.25)) * 0.5 * u_glowIntensity;
        } else {
            // Suppress inner glow
            glowAlpha = 0.0;
        }
    } 
    else if (VAR == 1) {
        d = sdCircle(p, 0.5 * u_shapeSize); 
        borderAlpha = smoothFill(d, pixelSize);
        if (d > 0.0) glowAlpha = exp(-d / 0.1) * 0.3 * u_glowIntensity;
    }
    else if (VAR == 2) {
        d = sdCircle(p, 0.5 * u_shapeSize);
        float strokeD = d + u_borderSize * 0.5;
        borderAlpha = smoothStroke(strokeD, u_borderSize, pixelSize * 2.0);
        if (d > 0.0) glowAlpha = exp(-d / (u_borderSize * 5.0)) * 0.4 * u_glowIntensity;
    }
    else if (VAR == 3) {
        d = sdPoly(p + vec2(0.0, 0.1), 0.3 * u_shapeSize, 3);
        borderAlpha = smoothFill(d, pixelSize);
        if (d > 0.0) glowAlpha = exp(-d / 0.1) * 0.3 * u_glowIntensity;
    }
    
    // Apply spotlight mask
    borderAlpha *= spotlight;
    glowAlpha *= spotlight;
    
    // Combine
    float finalAlpha = max(glowAlpha, borderAlpha);

    gl_FragColor = vec4(u_color, finalAlpha);
}
`;

export { fragmentShader, vertexShader };
