
window.ClientFingerprint = window.ClientFingerprint || {};

(function() {
    async function sha256(message) {
        if (window.crypto && window.crypto.subtle) {
            const msgUint8 = new TextEncoder().encode(message);
            const hashBuffer = await window.crypto.subtle.digest('SHA-256', msgUint8);
            const hashArray = Array.from(new Uint8Array(hashBuffer));
            return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
        } else {
            console.warn("Web Crypto API not available, using simple hash fallback.");
            return simpleHash(message);
        }
    }

    function simpleHash(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 >>> 0).toString(36);
    }

    async function generateFingerprint() {
        try {
            let components = [];

            components.push(navigator.userAgent || "unknown_ua");

            components.push(navigator.language || navigator.userLanguage || "unknown_lang");

            components.push(screen.colorDepth || "unknown_cd");

            components.push((screen.width || "unknown_w") + "x" + (screen.height || "unknown_h"));

            try {
                const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
                components.push(tz || "unknown_tz");
            } catch (e) {
                components.push("unknown_tz_error");
            }

            components.push(typeof(Storage) !== "undefined" ? "storage_available" : "storage_unavailable");

            let canvas = document.createElement('canvas');
            let ctx = canvas.getContext('2d');
            if (ctx) {
                ctx.textBaseline = "top";
                ctx.font = "14px 'Arial'";
                ctx.textBaseline = "alphabetic";
                ctx.fillStyle = "#f60";
                ctx.fillRect(125, 1, 62, 20);
                ctx.fillStyle = "#069";
                ctx.fillText("Hello, World", 2, 15);
                ctx.fillStyle = "rgba(102, 204, 0, 0.7)"; 
                ctx.fillText("Hello, World", 4, 17);
                let canvasDataUrl = canvas.toDataURL();
                components.push(await sha256(canvasDataUrl));
                // components.push(simpleHash(canvasDataUrl)); 
            } else {
                 components.push("canvas_unsupported");
            }

            let canvas2 = document.createElement('canvas');
            let gl;
            let webglVendor = "unknown";
            let webglRenderer = "unknown";
            try {
                 gl = canvas2.getContext('webgl') || canvas2.getContext('experimental-webgl');
                 if (gl) {
                     const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
                     if (debugInfo) {
                         webglVendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL) || "unknown_vendor";
                         webglRenderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) || "unknown_renderer";
                     } else {
                         webglVendor = "webgl_available_no_ext";
                         webglRenderer = "webgl_available_no_ext";
                     }
                 } else {
                      webglVendor = "webgl_unsupported";
                      webglRenderer = "webgl_unsupported";
                 }
            } catch (e) {
                 webglVendor = "webgl_error";
                 webglRenderer = "webgl_error";
            }
            components.push(webglVendor);
            components.push(webglRenderer);

            components.push(navigator.hardwareConcurrency || 'unknown_cores');

            components.push(navigator.deviceMemory || 'unknown_memory');

            components.push('ontouchstart' in window || navigator.maxTouchPoints > 0 ? 'touch_capable' : 'not_touch_capable');

            let fingerprintString = components.join('###');

            const fingerprintHash = await sha256(fingerprintString);
            // let fingerprintHash = simpleHash(fingerprintString);

            window.ClientFingerprint.hash = fingerprintHash;
            window.ClientFingerprint.components = {
                userAgent: navigator.userAgent || "unknown",
                language: navigator.language || "unknown",
                colorDepth: screen.colorDepth || "unknown",
                resolution: (screen.width || "?") + "x" + (screen.height || "?"),
                timezone: Intl.DateTimeFormat().resolvedOptions().timeZone || "unknown",
                cores: navigator.hardwareConcurrency || "unknown",
                memory: navigator.deviceMemory || "unknown",
                touchCapable: 'ontouchstart' in window || navigator.maxTouchPoints > 0
            };
            window.ClientFingerprint.ready = true;
            console.log("Generated Fingerprint Hash:", fingerprintHash);
            return fingerprintHash;

        } catch (error) {
            console.error("Fingerprint generation failed:", error);
            window.ClientFingerprint.hash = "error"; 
            return "error";
        }
    }

    (async () => {
        await generateFingerprint();
    })();

})();