/**
 * Advanced Anti-Bot Protection - Client Side
 * Multi-layer JavaScript-based bot detection
 */

(function() {
    'use strict';
    
    // Bot detection score (higher = more likely bot)
    let botScore = 0;
    let protectionData = {
        mouseMovements: 0,
        clicks: 0,
        keystrokes: 0,
        scrolls: 0,
        timeOnPage: 0,
        fingerprint: '',
        canvasFingerprint: '',
        startTime: Date.now(),
        touchSupport: false,
        screenData: {},
        timingData: {}
    };
    
    // 1. CANVAS FINGERPRINTING
    function generateCanvasFingerprint() {
        try {
            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext('2d');
            canvas.width = 200;
            canvas.height = 50;
            
            // Draw text with specific styling
            ctx.textBaseline = 'top';
            ctx.font = '14px "Arial"';
            ctx.textBaseline = 'alphabetic';
            ctx.fillStyle = '#f60';
            ctx.fillRect(125, 1, 62, 20);
            ctx.fillStyle = '#069';
            ctx.fillText('Spotify Security', 2, 15);
            ctx.fillStyle = 'rgba(102, 204, 0, 0.7)';
            ctx.fillText('Spotify Security', 4, 17);
            
            // Get canvas data
            const dataURL = canvas.toDataURL();
            return hashCode(dataURL);
        } catch(e) {
            botScore += 20; // Canvas blocking = suspicious
            return 'canvas_blocked';
        }
    }
    
    // 2. BROWSER FINGERPRINTING
    function generateBrowserFingerprint() {
        const data = {
            userAgent: navigator.userAgent,
            language: navigator.language,
            languages: navigator.languages ? navigator.languages.join(',') : '',
            platform: navigator.platform,
            hardwareConcurrency: navigator.hardwareConcurrency || 0,
            deviceMemory: navigator.deviceMemory || 0,
            screen: {
                width: screen.width,
                height: screen.height,
                colorDepth: screen.colorDepth,
                pixelDepth: screen.pixelDepth,
                availWidth: screen.availWidth,
                availHeight: screen.availHeight
            },
            timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
            timezoneOffset: new Date().getTimezoneOffset(),
            plugins: getPlugins(),
            webgl: getWebGLInfo(),
            audio: getAudioFingerprint(),
            fonts: detectFonts()
        };
        
        protectionData.screenData = data.screen;
        return hashCode(JSON.stringify(data));
    }
    
    // Get installed plugins
    function getPlugins() {
        if (!navigator.plugins) return [];
        const plugins = [];
        for (let i = 0; i < navigator.plugins.length; i++) {
            plugins.push(navigator.plugins[i].name);
        }
        return plugins;
    }
    
    // Get WebGL info
    function getWebGLInfo() {
        try {
            const canvas = document.createElement('canvas');
            const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
            if (!gl) return 'not_supported';
            
            const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
            return {
                vendor: gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL),
                renderer: gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL)
            };
        } catch(e) {
            return 'error';
        }
    }
    
    // Audio fingerprinting
    function getAudioFingerprint() {
        try {
            const AudioContext = window.AudioContext || window.webkitAudioContext;
            if (!AudioContext) return 'not_supported';
            
            const context = new AudioContext();
            const oscillator = context.createOscillator();
            const analyser = context.createAnalyser();
            const gainNode = context.createGain();
            const scriptProcessor = context.createScriptProcessor(4096, 1, 1);
            
            gainNode.gain.value = 0;
            oscillator.connect(analyser);
            analyser.connect(scriptProcessor);
            scriptProcessor.connect(gainNode);
            gainNode.connect(context.destination);
            
            oscillator.start(0);
            const fingerprint = analyser.frequencyBinCount;
            oscillator.stop();
            
            return fingerprint;
        } catch(e) {
            return 'error';
        }
    }
    
    // Detect installed fonts
    function detectFonts() {
        const baseFonts = ['monospace', 'sans-serif', 'serif'];
        const testFonts = [
            'Arial', 'Verdana', 'Times New Roman', 'Courier New', 'Georgia',
            'Palatino', 'Garamond', 'Bookman', 'Comic Sans MS', 'Trebuchet MS',
            'Impact', 'Lucida Console'
        ];
        
        const detected = [];
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        
        for (let font of testFonts) {
            let detected_font = false;
            for (let baseFont of baseFonts) {
                ctx.font = '72px ' + baseFont;
                const baseWidth = ctx.measureText('mmmmmmmmmmlli').width;
                
                ctx.font = '72px ' + font + ', ' + baseFont;
                const testWidth = ctx.measureText('mmmmmmmmmmlli').width;
                
                if (baseWidth !== testWidth) {
                    detected_font = true;
                    break;
                }
            }
            if (detected_font) detected.push(font);
        }
        
        return detected;
    }
    
    // Simple hash function
    function hashCode(str) {
        let hash = 0;
        for (let i = 0; i < str.length; i++) {
            const char = str.charCodeAt(i);
            hash = ((hash << 5) - hash) + char;
            hash = hash & hash;
        }
        return hash.toString(36);
    }
    
    // 3. MOUSE MOVEMENT TRACKING
    let lastMouseMove = 0;
    let mouseMovePath = [];
    
    function trackMouseMovement(e) {
        const now = Date.now();
        if (now - lastMouseMove > 50) { // Throttle
            protectionData.mouseMovements++;
            mouseMovePath.push({x: e.clientX, y: e.clientY, t: now});
            
            // Keep only last 20 movements
            if (mouseMovePath.length > 20) {
                mouseMovePath.shift();
            }
            
            lastMouseMove = now;
        }
    }
    
    // Analyze mouse movement patterns
    function analyzeMousePattern() {
        if (mouseMovePath.length < 5) {
            botScore += 30; // Too few movements = suspicious
            return;
        }
        
        // Check for perfectly straight lines (bot behavior)
        let straightLines = 0;
        for (let i = 2; i < mouseMovePath.length; i++) {
            const dx1 = mouseMovePath[i-1].x - mouseMovePath[i-2].x;
            const dy1 = mouseMovePath[i-1].y - mouseMovePath[i-2].y;
            const dx2 = mouseMovePath[i].x - mouseMovePath[i-1].x;
            const dy2 = mouseMovePath[i].y - mouseMovePath[i-1].y;
            
            // Check if vectors are parallel (straight line)
            if (Math.abs(dx1 * dy2 - dy1 * dx2) < 1) {
                straightLines++;
            }
        }
        
        if (straightLines > mouseMovePath.length * 0.8) {
            botScore += 25; // Too many straight lines
        }
    }
    
    // 4. CLICK TRACKING
    function trackClick(e) {
        protectionData.clicks++;
    }
    
    // 5. KEYSTROKE TRACKING
    function trackKeystroke(e) {
        protectionData.keystrokes++;
    }
    
    // 6. SCROLL TRACKING
    let lastScroll = 0;
    function trackScroll(e) {
        const now = Date.now();
        if (now - lastScroll > 100) {
            protectionData.scrolls++;
            lastScroll = now;
        }
    }
    
    // 7. TOUCH SUPPORT DETECTION
    function detectTouchSupport() {
        protectionData.touchSupport = (
            'ontouchstart' in window ||
            navigator.maxTouchPoints > 0 ||
            navigator.msMaxTouchPoints > 0
        );
    }
    
    // 8. TIMING ANALYSIS
    function analyzeTimings() {
        const timeOnPage = Date.now() - protectionData.startTime;
        protectionData.timeOnPage = timeOnPage;
        
        // Too fast = bot
        if (timeOnPage < 1000) {
            botScore += 40;
        } else if (timeOnPage < 2000) {
            botScore += 20;
        }
        
        // No interaction = bot
        if (protectionData.mouseMovements === 0 && timeOnPage > 3000) {
            botScore += 50;
        }
        
        if (protectionData.clicks === 0 && timeOnPage > 5000) {
            botScore += 30;
        }
    }
    
    // 9. AUTOMATION DETECTION
    function detectAutomation() {
        // Check for automation tools
        if (window.navigator.webdriver) {
            botScore += 100; // Selenium/WebDriver detected
        }
        
        // Check for PhantomJS
        if (window.callPhantom || window._phantom) {
            botScore += 100;
        }
        
        // Check for headless Chrome
        if (/HeadlessChrome/.test(window.navigator.userAgent)) {
            botScore += 100;
        }
        
        // Check for automation properties
        const automationProps = [
            '__nightmare',
            '__selenium_unwrapped',
            '__webdriver_evaluate',
            '__driver_evaluate',
            '__webdriver_script_function',
            '__webdriver_script_func',
            '__webdriver_script_fn',
            '__fxdriver_evaluate',
            '__driver_unwrapped',
            '__webdriver_unwrapped',
            '__selenium_evaluate',
            '__fxdriver_unwrapped',
            '__$webdriverAsyncExecutor'
        ];
        
        for (let prop of automationProps) {
            if (window[prop] || document[prop]) {
                botScore += 100;
            }
        }
    }
    
    // 10. GENERATE PROTECTION TOKEN
    function generateProtectionToken() {
        analyzeMousePattern();
        analyzeTimings();
        detectAutomation();
        
        const token = {
            fp: protectionData.fingerprint,
            cfp: protectionData.canvasFingerprint,
            mm: protectionData.mouseMovements,
            c: protectionData.clicks,
            k: protectionData.keystrokes,
            s: protectionData.scrolls,
            t: protectionData.timeOnPage,
            ts: protectionData.touchSupport ? 1 : 0,
            sc: protectionData.screenData,
            bs: botScore,
            v: '1.0'
        };
        
        return btoa(JSON.stringify(token));
    }
    
    // Initialize protection
    function init() {
        // Generate fingerprints
        protectionData.canvasFingerprint = generateCanvasFingerprint();
        protectionData.fingerprint = generateBrowserFingerprint();
        
        // Detect touch support
        detectTouchSupport();
        
        // Add event listeners
        document.addEventListener('mousemove', trackMouseMovement, {passive: true});
        document.addEventListener('click', trackClick, {passive: true});
        document.addEventListener('keydown', trackKeystroke, {passive: true});
        document.addEventListener('scroll', trackScroll, {passive: true});
        
        // Set protection token in hidden field or cookie
        window.addEventListener('load', function() {
            setTimeout(function() {
                const token = generateProtectionToken();
                
                // Store in cookie
                document.cookie = '_abp=' + token + '; path=/; max-age=3600; SameSite=Lax';
                
                // Also add to forms
                const forms = document.querySelectorAll('form');
                forms.forEach(function(form) {
                    let input = form.querySelector('input[name="_abp_token"]');
                    if (!input) {
                        input = document.createElement('input');
                        input.type = 'hidden';
                        input.name = '_abp_token';
                        form.appendChild(input);
                    }
                    input.value = token;
                });
            }, 2000); // Wait 2 seconds to collect data
        });
    }
    
    // Start protection
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
    
    // Expose function to get current token
    window.getAntiBotToken = generateProtectionToken;
    
})();
