var app_url = 'https://app.seomonitor.com';
var api_url = 'https://api1.seomonitor.com/v1';

var token = false;
var currentTab = {};
var user_id = false;
var is_master_auth = false;
var interval = false;
var myURL = false;

// Helper function to inject content script if needed
async function ensureContentScript(tabId) {
    if (!tabId) {
        return false;
    }
    
    try {
        // Check if tab exists and is valid
        const tab = await chrome.tabs.get(tabId).catch(() => null);
        if (!tab || !tab.url) {
            return false;
        }
        
        // Skip chrome:// and other restricted URLs silently
        if (tab.url.startsWith('chrome://') || tab.url.startsWith('chrome-extension://') || 
            tab.url.startsWith('about:') || tab.url.startsWith('edge://') ||
            tab.url.startsWith('devtools://') || tab.url.startsWith('view-source:') ||
            tab.url.startsWith('file://')) {
            return false;
        }
        
        // Try to send a ping message to check if content script is loaded
        try {
            await chrome.tabs.sendMessage(tabId, { txt: 'ping' });
            return true;
        } catch (pingError) {
            // Expected error - content script not loaded yet, try to inject
        }
        
        // Content script not loaded, inject it
        try {
            await chrome.scripting.executeScript({
                target: { tabId: tabId },
                files: ['jquery-3.7.1.min.js', 'chosen.jquery.js', 'tippy.js', 'popup_loggedin_master_google.js']
            });
            await chrome.scripting.insertCSS({
                target: { tabId: tabId },
                files: ['chosen.min.css', 'popup_loggedin_master_google.css', 'tippy.css']
            });
            return true;
        } catch (injectionError) {
            // Silently fail - likely a restricted page we missed or user navigated away
            return false;
        }
    } catch (error) {
        // Silently fail for any other errors
        return false;
    }
}

// Initialize on install/startup
chrome.runtime.onInstalled.addListener(() => {
    checkIfIamLoggedIn().then(t => {
        token = t;
        initBackground();
    });
});

chrome.runtime.onStartup.addListener(() => {
    checkIfIamLoggedIn().then(t => {
        token = t;
        initBackground();
    });
});

var queryInfo = {
    active: true,
    currentWindow: true
};

var retry_add = 0;
var retry_check = 0;

chrome.runtime.onMessage.addListener(reciver);

chrome.storage.onChanged.addListener(function(changes, namespace) {
    if(typeof changes.token != 'undefined') {
        if (changes.token.newValue != 'undefined') {
            token = changes.token.newValue;
            initBackground();
        } else {
            token = false;
        }
    }
});

function initBackground() {
    var queryInfo = {
        active: true,
        currentWindow: true
    };
    checkIfIamLoggedIn().then(t => token = t);
    chrome.storage.sync.get(['token'], function (result) {
        if(typeof result.token == 'undefined'){
            chrome.storage.sync.set({'token': token}, function () {
                return true;
            });
        } else {
            token = result.token;
        }
        if(token) {
            chrome.storage.sync.get(['user_id'], function (result) {
                user_id = result.user_id;

                chrome.tabs.query(queryInfo, async function (tabs) {
                    if (!tabs || tabs.length === 0) {
                        console.log('No active tabs found');
                        return;
                    }
                    
                    currentTab = tabs[0];
                    if (!currentTab || !currentTab.url) {
                        console.log('Current tab or URL is undefined');
                        return;
                    }
                    
                    myURL = currentTab.url;

                    if (/^https?:\/\/(www\.)?google\.[a-z]+\/search/i.test(myURL)) {
                        if(token != 'no token') {
                            // Ensure content script is loaded first
                            const scriptLoaded = await ensureContentScript(currentTab.id);
                            if (scriptLoaded) {
                                chrome.tabs.sendMessage(currentTab.id, {
                                    txt: 'createButton',
                                    user_id: user_id
                                }).catch(() => {
                                    // Silently handle any message errors
                                });
                            }
                        }
                    }
                });
            });

            chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
                chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
                    if (tabs && tabs.length > 0 && tabs[0] && tabs[0].url) {
                        myURL = tabs[0].url;
                        var d = extractDomain(myURL);
                    }
                });
            });
        }
    });
}

async function sendRequest(tab, action, html = '', is_html) {
    // First ensure content script is loaded
    const scriptLoaded = await ensureContentScript(tab.id);
    if (!scriptLoaded) {
        // Silently fail - content script couldn't be loaded (restricted page, etc.)
        return;
    }
    
    let msg = {
        txt: ""
    };
    switch(action) {
        case 'info':
            msg.txt = 'info';
            msg.info = html;
            break;
        case 'error':
            msg.txt = 'error';
            msg.error_msg = html;
            break;
        case 'setBody':
            msg.txt = 'setBody';
            if(is_html) {
                msg.html = html;
            } else {
                msg.error_msg = html;
            }
            break;
        case 'set_SERP':
            msg.txt = 'set_SERP';
            msg.data = html;
            msg.isIncognito = tab.incognito;
            break;
        default:
            msg.txt = 'getSearch';
            break;
    }
    chrome.tabs.sendMessage(tab.id, msg).catch(() => {
        // Silently handle any remaining message errors
    });
}

function reciver(message, sender, sendResponse) {
    switch(message.action) {
        case 'getSearch':
            getSitesByKw(message.search, currentTab);
            break;
        case 'init':
            initBackground();
            break;
        case 'giveMeSERPPage':
            getSERPPage(message);
            break;
        case 'giveMeSERPTime':
            getSERPTime(message);
            break;
        case 'recrawl':
            generateRecrawlEvent(message);
            break;
    }
}

async function getSitesByKw(keyword, tab, retr = 0) {
    if (!token) {
        token = await checkIfIamLoggedIn();
    }
    
    if(token == 'false'){
        sendRequest(currentTab, 'error', 'Please sign in to your SEOmonitor account to continue.');
        return false;
    }

    if(token == 'no token'){
        sendRequest(currentTab, 'error', 'API authentication required. Please generate an API token in your SEOmonitor account settings.');
        return false;
    }
    
    fetch(api_url + '/sites_by_keyword/' + user_id + '/' + keyword, {
        method: 'GET',
        headers: {
            'Authorization': token
        }
    })
    .then(response => response.json())
    .then(data => {
        if (data.status.ok == true) {
            let site_options_html = '<option></option>';
            for (var i in data.sites) {
                if(i == 0) {
                    site_options_html += '<option value="' + data.sites[i].id + '" kws="' + data.sites[i].kws + '" selected="selected" timeCrawl="' + data.sites[i].crawlTime + '">' + data.sites[i].name + '</option>';
                } else {
                    site_options_html += '<option value="' + data.sites[i].id + '" kws="' + data.sites[i].kws + '">' + data.sites[i].name + '</option>';
                }
            }
            sendRequest(tab, 'setBody', site_options_html, true);
        } else {
            if (data.status.ok == false && data.status.retry == true && retr < 5) {
                retr++;
                getSitesByKw(keyword, tab, retr);
            } else {
                sendRequest(tab, 'error', data['status']['err']);
            }
        }
    })
    .catch(error => {
        sendRequest(currentTab, 'error', 'Authentication failed. Please verify your API token in SEOmonitor account settings.');
    });
}

function getSERPTime(message){
    fetch(api_url + '/keyword_serp_page_time/' + user_id + '/' + message.siteId + '/' + message.ksId, {
        method: 'GET',
        headers: {
            'Authorization': token
        }
    })
    .then(response => response.json())
    .then(data => {
        if (data.status.ok == true) {
            sendRequest(currentTab, 'set_SERP', data.page);
        } else {
            if(data['page']['new_crawl'] == true) {
            } else {
                data.error_msg = 'SERP data is not available for this website. Please try crawling now or select a different site.';
                sendRequest(currentTab, 'set_SERP', data);
            }
        }
    });
}

function getSERPPage(message){
    fetch(api_url + '/keyword_serp_page/' + user_id + '/' + message.siteId + '/' + message.ksId, {
        method: 'GET',
        headers: {
            'Authorization': token
        }
    })
    .then(response => response.json())
    .then(data => {
        if (data.status.ok == true) {
            sendRequest(currentTab, 'set_SERP', data.page);
        } else {
            if(data['page']['new_crawl'] == true) {
            } else {
                data.error_msg = 'SERP data is not available for this website. Please try crawling now or select a different site.';
                sendRequest(currentTab, 'set_SERP', data);
            }
        }
    });
}

function generateRecrawlEvent(message, eventGenerated = false){
    if(!eventGenerated) {
        fetch(api_url + '/recrawl_keyword_serp_page/' + user_id + '/' + message.siteId + '/' + message.ksId, {
            method: 'GET',
            headers: {
                'Authorization': token
            }
        })
        .then(response => response.json())
        .then(data => {
            if (data) {
                if (data.status.ok == true) {
                    sendRequest(currentTab, 'info', 'Crawling in progress. This may take a few minutes to complete.');
                    self.IntervalRecheckCrawl = setInterval(function () {
                        generateRecrawlEvent(message, true);
                    }, 10000);
                    clearInterval(interval);
                    interval = false;
                } else {
                    if (retry_add <= 5) {
                        retry_add++;
                    } else {
                        clearInterval(interval);
                        sendRequest(currentTab, 'error', 'Request failed. Please try again or contact support if the issue persists.');
                    }
                }
            } else {
                if (retry_add <= 5) {
                    retry_add++;
                } else {
                    clearInterval(interval);
                    sendRequest(currentTab, 'error', 'Something went wrong, please try again!');
                }
            }
        });
    } else {
        fetch(api_url + '/get_recrawled_keyword_serp_page/' + user_id + '/' + message.siteId + '/' + message.ksId, {
            method: 'GET',
            headers: {
                'Authorization': token
            }
        })
        .then(response => response.json())
        .then(data => {
            if (data) {
                if(data.done_recrawl == true) {
                    clearInterval(self.IntervalRecheckCrawl);
                    retry_check = 0;
                    sendRequest(currentTab, 'set_SERP', data);
                } else {
                    if(retry_check < 30) {
                        retry_check++
                    } else {
                        clearInterval(self.IntervalRecheckCrawl);
                        retry_check = 0;
                        sendRequest(currentTab, 'error', 'Crawling process failed. Please try again or contact support if the issue persists.');
                    }
                }
            }
        });
    }
}

function checkIfIamLoggedIn1(message = false){
    chrome.storage.sync.get({'keywords': []}, function (result) {
        var now = new Date();
        if(message != false) {
            if (Object.keys(result.keywords).length == 0) {
                var keywords = new Array();
                keywords.push({ksid: message.ksId, time: now.getTime()});
                interval = setInterval(function(){
                    generateRecrawlEvent(message)
                }, 5000);
            } else {
                var keywords = result.keywords;
                for (var i in keywords) {
                    if(keywords[i].ksid == message.ksId) {
                        var ksidTime = keywords[i].time;
                        if((now.getTime() - ksidTime)/60000 > 10){
                            interval = setInterval(function(){
                                generateRecrawlEvent(message)
                            }, 5000);
                        } else {
                            interval = setInterval(function(){
                                generateRecrawlEvent(message, true)
                            }, 5000);
                        }
                    } else {
                        keywords.push({ksid: message.ksId, time: now.getTime()});
                    }
                }
            }
            chrome.storage.sync.set({keywords: keywords}, function () {
                return true;
            });
        } else {
            if (Object.keys(result.keywords).length != 0) {
                var keywords = result.keywords;
                for (var i in keywords) {
                    var ksidTime = keywords[i].time;
                    if((now.getTime() - ksidTime)/60000 > 10){
                        keywords.splice(i, 1);
                        if( i > 0){
                            i--;
                        }
                    }
                }
                chrome.storage.sync.set({keywords: keywords}, function () {
                    return true;
                });
            }
        }
    });
}

function giveMeUule(location){
    let secretKey = '';
    switch (location.length) {
        case 4:
            secretKey = 'E';
            break;
        case 5:
            secretKey = 'F';
            break;
        case 6:
            secretKey = 'G';
            break;
        case 7:
            secretKey = 'H';
            break;
        case 8:
            secretKey = 'I';
            break;
        case 9:
            secretKey = 'J';
            break;
        case 10:
            secretKey = 'K';
            break;
        case 11:
            secretKey = 'L';
            break;
        case 12:
            secretKey = 'M';
            break;
        case 13:
            secretKey = 'N';
            break;
        case 14:
            secretKey = 'O';
            break;
        case 15:
            secretKey = 'P';
            break;
        case 16:
            secretKey = 'Q';
            break;
        case 17:
            secretKey = 'R';
            break;
        case 18:
            secretKey = 'S';
            break;
        case 19:
            secretKey = 'T';
            break;
        case 20:
            secretKey = 'U';
            break;
        case 21:
            secretKey = 'V';
            break;
        case 22:
            secretKey = 'W';
            break;
        case 23:
            secretKey = 'X';
            break;
        case 24:
            secretKey = 'Y';
            break;
        case 25:
            secretKey = 'Z';
            break;
        case 26:
            secretKey = 'a';
            break;
        case 27:
            secretKey = 'b';
            break;
        case 28:
            secretKey = 'c';
            break;
        case 29:
            secretKey = 'd';
            break;
        case 30:
            secretKey = 'e';
            break;
        case 31:
            secretKey = 'f';
            break;
        case 32:
            secretKey = 'g';
            break;
        case 33:
            secretKey = 'h';
            break;
        case 34:
            secretKey = 'i';
            break;
        case 35:
            secretKey = 'j';
            break;
        case 36:
            secretKey = 'k';
            break;
        case 37:
            secretKey = 'l';
            break;
        case 38:
            secretKey = 'm';
            break;
        case 39:
            secretKey = 'n';
            break;
        case 40:
            secretKey = 'o';
            break;
        case 41:
            secretKey = 'p';
            break;
        case 42:
            secretKey = 'q';
            break;
        case 43:
            secretKey = 'r';
            break;
        case 44:
            secretKey = 's';
            break;
        case 45:
            secretKey = 't';
            break;
        case 46:
            secretKey = 'u';
            break;
        case 47:
            secretKey = 'v';
            break;
        case 48:
            secretKey = 'w';
            break;
        case 49:
            secretKey = 'x';
            break;
        case 50:
            secretKey = 'y';
            break;
        case 51:
            secretKey = 'z';
            break;
        case 52:
            secretKey = '0';
            break;
        case 53:
            secretKey = '1';
            break;
        case 54:
            secretKey = '2';
            break;
        case 55:
            secretKey = '3';
            break;
        case 56:
            secretKey = '4';
            break;
        case 57:
            secretKey = '5';
            break;
        case 58:
            secretKey = '6';
            break;
        case 59:
            secretKey = '7';
            break;
        case 60:
            secretKey = '8';
            break;
        case 61:
            secretKey = '9';
            break;
        case 62:
            secretKey = '-';
            break;
        case 63:
            secretKey = ' ';
            break;
        case 64:
            secretKey = 'A';
            break;
        case 65:
            secretKey = 'B';
            break;
        case 66:
            secretKey = 'C';
            break;
        case 67:
            secretKey = 'D';
            break;
        case 68:
            secretKey = 'E';
            break;
        case 69:
            secretKey = 'F';
            break;
        case 70:
            secretKey = 'G';
            break;
        case 71:
            secretKey = 'H';
            break;
        case 72:
            secretKey = 'I';
            break;
        case 73:
            secretKey = 'J';
            break;
        case 76:
            secretKey = 'M';
            break;
        case 83:
            secretKey = 'T';
            break;
        default:
            secretKey = "L";
            break;
    }

    return 'w+CAIQICI' + secretKey + btoa(location);
}

function extractDomain(url) {
    var domain;
    if (url.indexOf("://") > -1) {
        domain = url.split('/')[2];
    }
    else {
        domain = url.split('/')[0];
    }
    domain = domain.split(':')[0];
    return domain.replace('www.','');
}

function checkIfIamLoggedIn() {
    return new Promise((resolve, reject) => {
        fetch(app_url + '/my_account/misc/amILoggedIn_json')
            .then(response => response.text())
            .then(data => {
                if (data.length !== 0) {
                    data = JSON.parse(data);
                    if (data.id && !isNaN(data.id)) {
                        user_id = data.id;
                        token = data.token;
                        if(token != 'false' && token != false){
                            chrome.storage.sync.set({'user_id': data.id}, function () {
                                return true;
                            });

                            if (token != '') {
                                chrome.storage.sync.set({'token': data.token}, function () {
                                    return true;
                                });
                            }
                        } else {
                            token = 'no token';
                        }
                        resolve(token);
                    } else {
                        chrome.storage.sync.set({'token': ''}, function () {
                            return true;
                        });
                        token = 'false';
                        resolve(false);
                    }
                } else {
                    chrome.storage.sync.set({'token': ''}, function () {
                        return true;
                    });
                    token = 'false';
                    resolve(false);
                }
            })
            .catch(error => {
                resolve(false);
            });
    });
}