var pageurl = window.location.href;
var id = "";
var is_setChecked = 0;
var is_invisible = "";
var is_enterprise = "";
var is_recaptcha_v2 = "&version=v2";
var action_value_recaptcha_v3 = "";
var message = document.createElement('span');
var afterElement = null;
var service_value=0;
String.prototype.isNumber = function(){return /^\d+$/.test(this);}
var recaptchaCallbackAlreadyFired=false;
var auto_submit=false;
var auto_callback=false;
var auto_click=false;
var isAutoClickXpathSubmit=false;
var xpathSubmit='';
var now1 = 0;
var now2 = 0;
var is_delete_div = 0;
var is_setupMessageBox = 0;

// config cho max speed 5s thi cho true 3 dong duoi
// config auto cho selenium va cac loai framework khac
// muon dung cai nao thi chuyen tu false qua true
var API_KEY_CAPTCHA69 = "";
var selenium_option_is_auto_on = false;//chuyen qua true de bat dau auto = selenium hoac cac loai framework khac
var selenium_option_auto_submit = false;//auto submit iframe
var selenium_option_isAutoClickXpathSubmit = false;//auto submit xpath full
var selenium_option_auto_callback = false;//auto callback
var selenium_option_xpathSubmit = '/html/body/div[1]/div/main/div/section/form/button[1]';//xpath full of button click submit


function test_code(code)
{
    var taskSolution=code;
	var recursiveCallbackSearch;
    var passedProperties = 0;
	var oneVisibleRecaptchaClientKey = null;
	var script;
    var injectedCode = "(" + function(taskSolution) 
	{
        recaptchaCallbackAlreadyFired = false;
        recursiveCallbackSearch = function(object, solution, currentDepth, maxDepth) 
		{
            if (recaptchaCallbackAlreadyFired) 
			{
                return;
            }
            passedProperties = 0;
            for (var i in object) 
			{
                passedProperties++;
                if (passedProperties > 15) 
				{
                    break;
                }
                try {
                    if (typeof object[i] == "object" && currentDepth <= maxDepth) 
					{
                        recursiveCallbackSearch(object[i], solution, currentDepth + 1, maxDepth)
                    } 
					else if (i == "callback") 
					{
                        if (typeof object[i] == "function") 
						{
                            recaptchaCallbackAlreadyFired = true;
                            object[i](solution);
                        } else if (typeof object[i] == "string" && typeof window[object[i]] == "function") 
						{
                            recaptchaCallbackAlreadyFired = true;
                            window[object[i]](solution);
                        }
                        return;
                    }
                } catch (e) {}
            }
        };

        if (!recaptchaCallbackAlreadyFired) 
		{
            if (typeof ___grecaptcha_cfg != "undefined" && typeof ___grecaptcha_cfg.clients != "undefined") 
			{               
                oneVisibleRecaptchaClientKey = null;
                visible_recaptcha_element_search_loop: for (var i in ___grecaptcha_cfg.clients) {
                    for (var j in ___grecaptcha_cfg.clients[i]) 
					{
                        if (___grecaptcha_cfg.clients[i][j] && typeof ___grecaptcha_cfg.clients[i][j].nodeName == "string" && typeof ___grecaptcha_cfg.clients[i][j].innerHTML == "string" && typeof ___grecaptcha_cfg.clients[i][j].innerHTML.indexOf("iframe") != -1) 
						{
                            if (___grecaptcha_cfg.clients[i][j].offsetHeight != 0 && ___grecaptcha_cfg.clients[i][j].childNodes.length && ___grecaptcha_cfg.clients[i][j].childNodes[0].offsetHeight != 0 || ___grecaptcha_cfg.clients[i][j].dataset.size == "invisible") 
							{
                                if (oneVisibleRecaptchaClientKey === null) {
                                    oneVisibleRecaptchaClientKey = i;
                                    break
                                } else {
                                    oneVisibleRecaptchaClientKey = null;
                                    break visible_recaptcha_element_search_loop;
                                }
                            }
                        }
                    }
                }
                if (oneVisibleRecaptchaClientKey !== null) {
                    recursiveCallbackSearch(___grecaptcha_cfg.clients[oneVisibleRecaptchaClientKey], taskSolution, 1, 2)
                }
            }
        }
    } + ')("' + taskSolution + '");';
    script = document.createElement("script");
    script.textContent = injectedCode;
    (document.head || document.documentElement).appendChild(script);
    script.remove();
}


function mktime_last(action,minute)
{
	var now = new Date();
		year = now.getFullYear();//	Get the year as a four digit number (yyyy)
		month = now.getMonth();//	Get the month as a number (0-11)
		day = now.getDate();//	Get the day as a number (1-31)
		hour = now.getHours();//	Get the hour (0-23)
		if(action=="now")
		{
			minute = now.getMinutes();//	Get the minute (0-59)
		}else{
			minute=now.getMinutes()-minute;
		}
		second = now.getSeconds();// Get the second (0-59)
		//second = now.getMilliseconds();//	Returns the milliseconds (from 0-999)
	return new Date(year, month, day, hour, minute, second).getTime()/1000;
}

var isShowLogResUrl = 0;
var NumReRes = 1;
function checkCompletion_captcha69(code, key, repeat) {
    let url = `https://captcha69.com/res.php?key=${API_KEY_CAPTCHA69}&action=get&id=${code}`;
    if(isShowLogResUrl == 0)
    {
        isShowLogResUrl = 1;
        console.log("GET TOKEN URL API => " + url);
    }
    chrome.runtime.sendMessage({
        method: 'GET',
        action: 'xhttp',
        url: url,
        data: ''
    }, function(responseText) {
		console.log(code+":"+responseText+" - Đang Giải: "+NumReRes);
        NumReRes++;
		try{
			if(responseText.trim().includes("CAPCHA_NOT_READY")){
				setTimeout(function() {
					checkCompletion_captcha69(code, API_KEY_CAPTCHA69, repeat);
				}, repeat);
			}
			else if (responseText.trim().includes("ERROR"))
			{
				console.log("ERROR_CAPTCHA_UNSOLVABLE");
				setTimeout(start_solve, 2000);
			} else{
				now2 = mktime_last("now","now");
				var now_time_out = now2 - now1 - 5;//5 là repeat
				console.log("Time Solver Done => " + now_time_out);
				console.log(responseText.trim().substring(3));
				setCaptchaCode(responseText.trim().substring(3));
			}
		}catch(err) {
			console.log(err);
			setTimeout(start_solve, 2000);
		}
    });

}

function getParameterByName(name, url) {
    if (!url) url = window.location.href;
    name = name.replace(/[\[\]]/g, "\\$&");
    var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
        results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, " "));
}
function insertAfter(el, referenceNode) {
    referenceNode.parentNode.insertBefore(el, referenceNode);
}
function setNewChecked(interval){
    let check = document.createElement("img");
    check.src = chrome.runtime.getURL("./icons/check.png");
    check.className = "setChecked_success_ok";
    check.style.marginTop = "15px";
    check.style.marginLeft = "5px";
    check.style.position = "absolute";
    insertAfter(check, afterElement);
}
function setChecked(interval){
    let check = document.getElementsByClassName("setChecked_success_ok")[0];
    check.src = chrome.runtime.getURL("./icons/check.png");
}
function setUnChecked(interval){
    let check = document.getElementsByClassName("setChecked_success_ok")[0];
    check.src = chrome.runtime.getURL("./icons/icon.png");
}
function setCaptchaCode(code) {
    sendMessage("<b>Callback - CaptCha69.Com</b>");
    let ele = document.getElementsByClassName("g-recaptcha-response")[0];
    if(is_setChecked == 0)
    {
        is_setChecked = 1;
        setNewChecked();
    }else{
        setChecked();
    }

    if(ele != null)
    {
        ele.innerHTML = code;
        if(auto_callback==true)
        {
            test_code(code);
        }
        sendMessage("<b>Giải Xong - CaptCha69.Com</b>");
        if(auto_submit==true)
        {
            try{
                afterElement.closest('form').submit();
            }catch(er){
                console.log("=== ERROR Click Submit iframe ===");
                console.log(er);
            }
        }
        else if(isAutoClickXpathSubmit==true)
        {
            try{
                if(xpathSubmit!='')
                {
                    var xPathRes = document.evaluate(xpathSubmit, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
                    xPathRes.singleNodeValue.click();
                }
            }catch(e){
                console.log("=== ERROR Click Submit xPath ===");
                console.log(e);
            }
        }
    }else{
        setTimeout(() => {
            setCaptchaCode(code);
        }, 5000);
    }
}

function setupMessageBox() {
    let image = '<img src="' + chrome.runtime.getURL('./icons/icon.png') + '" align="left" style="margin-right: 4px;" />';
    message.innerHTML = "<b>Đang Tìm - CaptCha69.Com</b>";
    let container = document.createElement('div');
    container.className = 'ReCaptcha_solver';
    container.innerHTML = image;
    container.appendChild(message);
    container.style.backgroundColor = "#F9F9F9";
    container.style.border = "1px solid #D3D3D3";
    container.style.borderTop = "none";
    container.style.borderRadius = "0 0 3px 3px";
    container.style.padding = "5px";
    container.style.boxSizing = "border-box"
    container.style.width = "302px";
    container.style.margin = "-4px 2px 0 0";
    insertAfter(container, afterElement);
}
function sendMessage(str){
    message.innerHTML = str;
}

function startWatching_captcha69(code, key) {
    let initial = 5000, repeat = 5000;
    setTimeout(function() {
        checkCompletion_captcha69(code, key, repeat);
    }, initial);
}

function onGotauto(item){
    auto_submit=item.Auto;
}
function onGotautoCallBack(item){
    auto_callback=item.AutoCallback;
}
function onGotisAutoClickXpathSubmit(item){
    isAutoClickXpathSubmit=item.isAutoClickXpathSubmit;
}
function onGotxpathSubmit(item){
    xpathSubmit=item.xpathSubmit;
}
function onGotAutoClick(item){
    auto_click=item.AutoClick;

}

function delete_div(){
    var frames = document.getElementsByTagName("iframe");
    for(let i = 0; i < frames.length; i++){
        var src = frames[i].getAttribute('src');
        if(src != null && src.startsWith("https://www.google.com/recaptcha/api2/bframe")){
            frames[i].parentNode.remove();
            break;
        }
    }
}
function try_solve(){
    var actualCode = '(' + function() {
        let isRecaptchaFrame = () => {
            return /https:\/\/www.google.com\/recaptcha\/api2\/anchor/.test(window.location.href);
        };

        let captchaInterval = setInterval(() => {
            if (isRecaptchaFrame()) {
                clearInterval(captchaInterval);
                document.getElementsByClassName('recaptcha-checkbox-checkmark')[0].click();
            }
        }, 500);

    } + ')();';
    var script = document.createElement('script');
    script.textContent = actualCode;
    (document.head||document.documentElement).appendChild(script);
    script.remove();

}

function start_solve()
{
    const scriptTags = document.querySelectorAll('script[src^="https://www.google.com/recaptcha"]');
    scriptTags.forEach(tag => {
      if (tag.src.includes("?render=")) {
        is_recaptcha_v2 = "&version=v3";
      } else {
        is_recaptcha_v2 = "&version=v2";
      }
    });

    const sourceCode = document.documentElement.innerHTML;
    const actionRegex = /action\s*:\s*'([^']+)'|action\s*:\s*"([^"]+)"/;
    const match = sourceCode.match(actionRegex);
    if (match) {
      action_value_recaptcha_v3 = match[1] || match[2];
      action_value_recaptcha_v3 = '&action='+action_value_recaptcha_v3;
    } else {
      action_value_recaptcha_v3 = '';
    }

    if(is_delete_div==0)
    {
        is_delete_div = 1;
        delete_div();
    }
    let frames = document.getElementsByTagName("iframe");
    let is_start_solver = 0;
    for(let i = 0; i < frames.length; i++)
    {
        if(frames[i].offsetParent!=null)
        {
            let src = frames[i].getAttribute('src');

            // enterprise
            if(src != null && src.startsWith("https://www.google.com/recaptcha/enterprise") && getParameterByName("k", src)!= "6LfUZKkUAAAAAJ6J-iUArW3Sva3Iyxxitf8tDmoW")
            {
                is_enterprise = '&enterprise=1';
                id = getParameterByName("k", src);
                is_invisible = getParameterByName("size", src);
                if(is_invisible=='invisible')
                {
                    is_invisible = '&invisible=1';
                }else{
                    is_invisible = '';
                }
                if(id != "" && id != null && id != "6LfUZKkUAAAAAJ6J-iUArW3Sva3Iyxxitf8tDmoW")
                {
                    afterElement = frames[i];
                    console.log("========= start enterprise  ===========");
                    console.log("sitekey => " + id);
                    console.log("pageurl => " + pageurl);
                    console.log("is_invisible => " + is_invisible);
                    console.log("is_recaptcha_v2 => " + is_recaptcha_v2);
                    console.log("action_value_recaptcha_v3 => " + action_value_recaptcha_v3);
                    console.log("========= end enterprise  ===========");
                    if(is_setupMessageBox==0)
                    {
                        is_setupMessageBox = 1;
                        setupMessageBox();
                    }else{
                        setUnChecked();
                        sendMessage("<b>Đang Tìm - CaptCha69.Com</b>");
                    }
                    is_start_solver = 1;
                    break;
                }
            }
            // no enterprise
            else if(src != null && src.startsWith("https://www.google.com/recaptcha") && getParameterByName("k", src)!= "6LfUZKkUAAAAAJ6J-iUArW3Sva3Iyxxitf8tDmoW")
            {
                is_enterprise = '';
                id = getParameterByName("k", src);
                is_invisible = getParameterByName("size", src);
                if(is_invisible=='invisible')
                {
                    is_invisible = '&invisible=1';
                }else{
                    is_invisible = '';
                }
                if(id != "" && id != null && id != "6LfUZKkUAAAAAJ6J-iUArW3Sva3Iyxxitf8tDmoW")
                {
                    afterElement = frames[i];
                    console.log("========= start no enterprise  ===========");
                    console.log("sitekey => " + id);
                    console.log("pageurl => " + pageurl);
                    console.log("is_invisible => " + is_invisible);
                    console.log("is_recaptcha_v2 => " + is_recaptcha_v2);
                    console.log("action_value_recaptcha_v3 => " + action_value_recaptcha_v3);
                    console.log("========= end no enterprise  ===========");
                    if(is_setupMessageBox==0)
                    {
                        is_setupMessageBox = 1;
                        setupMessageBox();
                    }else{
                        sendMessage("<b>Đang Tìm - CaptCha69.Com</b>");
                    }
                    is_start_solver = 1;
                    break;
                }
            }
        }
    }
    if(is_start_solver==0)
    {
        setTimeout(start_solve, 2000);
    }else{
        chrome.storage.sync.get("apiKey", function(result)
        {
            sendMessage("<b>Đang Giải - CaptCha69.Com</b>");
			if(API_KEY_CAPTCHA69=="")
			{
				API_KEY_CAPTCHA69 = result.apiKey;
			}
            // Get UserAgent and Cookies
            let userAgent = encodeURIComponent(navigator.userAgent || "");
            if(userAgent!="")
            {
                userAgent = "&userAgent="+userAgent;
            }
            let cookies = encodeURIComponent(document.cookie || "");
            if(cookies!="")
            {
                cookies = "&cookies="+cookies;
            }
            let url = `https://captcha69.com/in.php?key=${API_KEY_CAPTCHA69}&googlekey=${id}&method=userrecaptcha${is_recaptcha_v2}${is_invisible}${action_value_recaptcha_v3}${is_enterprise}${userAgent}${cookies}&pageurl=${encodeURIComponent(pageurl)}`;
            console.log("GET ID URL API => " + url);
            chrome.runtime.sendMessage({
                method: 'GET',
                action: 'xhttp',
                url: url,
                data: ''
            }, function(responseText)
            {
                try{
                    console.log("GET ID RESPONSE => " + responseText);
                    if(responseText.trim().includes('OK|')==false){
                        sendMessage("<b>"+responseText.trim()+"</b> - "+url)
                        setTimeout(start_solve, 5000);
                    }else{
                        console.log("id: "+responseText.trim().substring(3));
                        now1 = mktime_last("now","now");
                        console.log("Start Solver => " + now1);
                        isShowLogResUrl = 0;
                        NumReRes = 1;
                        startWatching_captcha69(responseText.trim().substring(3), API_KEY_CAPTCHA69);
                    }
                }catch(err) {
                    console.log(err);
                    setTimeout(start_solve, 2000);
                }
            });
        });
    }
}

async function delay(delayInms) {
    return new Promise(resolve  => {
        setTimeout(() => {
            resolve(2);
        }, delayInms);
    });
}

chrome.storage.sync.get("isEnabled",function(result) {
    if(selenium_option_is_auto_on==true)
    {
        auto_submit = selenium_option_auto_submit;
        auto_callback = selenium_option_auto_callback;
        isAutoClickXpathSubmit = selenium_option_isAutoClickXpathSubmit;
        xpathSubmit = selenium_option_xpathSubmit;
        setTimeout(start_solve, 2000);
    }
    else if(result.isEnabled==true)
    {
        chrome.storage.sync.get("Auto",onGotauto);
        chrome.storage.sync.get("AutoCallback",onGotautoCallBack);
        chrome.storage.sync.get("isAutoClickXpathSubmit",onGotisAutoClickXpathSubmit);
        chrome.storage.sync.get("xpathSubmit",onGotxpathSubmit);
        setTimeout(start_solve, 2000);
    }
});