// ============================================================
// FETCH UTILITIES
// ============================================================

async function fetchDataSilent(url, data) {
    return new Promise((resolve) => {
        chrome.runtime.sendMessage(
            { type: 'fetchData', url, data },
            function (response) {
                console.log('data sent to fetch', data);
                console.log('fetchData response', response);
                resolve(response.data);
            }
        );
    });
}

async function fetchDataWithErrors(url, data) {
    return new Promise((resolve, reject) => {
        chrome.runtime.sendMessage(
            { type: 'fetchData', url, data },
            function (response) {
                console.log('data sent to fetch', data);
                console.log('fetchData response', response);
                if (response.error) reject(response.error);
                resolve(response.data);
            }
        );
    });
}

// ============================================================
// UI BUILDERS
// ============================================================

function createColorDropdown() {
    const select = document.createElement('select');
    select.id = 'color_id';
    ['black', 'red', 'blue', 'green', 'purple', 'orange', 'yellow'].forEach(color => {
        select.appendChild(new Option(color, color));
    });
    select.style.display = 'none';
    document.body.prepend(select);

    document.getElementById('color_id').onchange = function () {
        const color = document.getElementById('color_id').value;
        document.getElementById('the-textarea').style.color = color;
    };
}

function createSimilarItemInput() {
    const wrapper = document.createElement('div');
    const label = document.createElement('label');
    label.textContent = 'Similar Item Number:';
    label.style.marginRight = '8px';

    const input = document.createElement('input');
    input.type = 'text';
    input.id = 'similar-item-number';
    input.style.border = '1px solid #ccc';
    input.style.borderRadius = '4px';
    input.style.padding = '8px';
    input.style.fontSize = '16px';

    wrapper.appendChild(label);
    wrapper.appendChild(input);
    wrapper.style.display = 'inline-block';
    wrapper.style.marginLeft = '16px';
    return wrapper;
}

function createPromotedListingInput() {
    const wrapper = document.createElement('div');
    wrapper.classList.add('optional-promoted-listing');

    const label = document.createElement('label');
    label.textContent = 'Promoted Listing Percentage %:';
    label.style.marginRight = '8px';

    const input = document.createElement('input');
    input.type = 'number';
    input.id = 'promoted-listing';
    input.style.border = '1px solid #ccc';
    input.style.borderRadius = '4px';
    input.style.padding = '8px';
    input.style.fontSize = '16px';
    input.min = '2';
    input.max = '99';
    input.step = '0.1';

    wrapper.appendChild(label);
    wrapper.appendChild(input);
    wrapper.style.display = 'inline-block';
    wrapper.style.marginLeft = '16px';

    chrome.storage.local.get('promoted_listing_ad_rate', async function (result) {
        let rate = result.promoted_listing_ad_rate;
        if (rate === undefined || isNaN(rate)) {
            rate = 2.1;
            chrome.storage.local.set({ promoted_listing_ad_rate: rate });
        }
        input.value = rate;
    });

    return wrapper;
}

function createSellPriceInput() {
    const wrapper = document.createElement('div');
    const label = document.createElement('label');
    label.textContent = 'Sell it for:';

    const input = document.createElement('input');
    input.type = 'number';
    input.min = '0';
    input.step = '0.01';
    input.id = 'sell-price';
    input.style.border = '1px solid #ccc';
    input.style.borderRadius = '4px';
    input.style.padding = '8px';
    input.style.fontSize = '16px';

    chrome.storage.local.get('markupPrice', async function (result) {
        const markup = result.markupPrice;
        if (markup !== undefined) {
            let amazonPrice = getAmazonPrice();
            if (amazonPrice < 0) amazonPrice = product_data.price;

            let sellPrice = amazonPrice * (1 + markup / 100);
            sellPrice = Math.ceil(sellPrice);

            const endPriceResult = await chrome.storage.local.get('end_price');
            let endPrice = parseFloat(endPriceResult.end_price);
            let remainder = 1 - endPrice;
            if (remainder === 1) remainder = 0;

            sellPrice -= remainder;
            input.value = sellPrice;
        }
    });

    wrapper.appendChild(label);
    wrapper.appendChild(input);
    wrapper.style.display = 'inline-block';
    wrapper.style.marginLeft = '16px';
    return wrapper;
}

function wrapWordsInElements(selector, tagName, className) {
    const elements = document.querySelectorAll(selector);
    for (let i = 0; i < elements.length; i++) {
        const el = elements[i];
        const words = el.innerText.split(' ');
        let html = '';
        for (let j = 0; j < words.length; j++) {
            html += ` <${tagName} class="${className}">${words[j]}</${tagName}>`;
        }
        el.innerHTML = html;
    }
}

function makeProductTitleSortable() {
    wrapWordsInElements('#productTitle', 'div', 'word');
    $('#productTitle').sortable();
    console.log('made sortable');
}

function setupTextareaHighlighting() {
    $('#the-textarea').highlightWithinTextarea({
        highlight: [0, 80],
        className: 'green'
    });
    const textarea = document.getElementById('the-textarea');
    textarea.cols = '200';
    textarea.rows = '3';
}

// ============================================================
// MAIN INIT
// ============================================================

async function initProductPage() {
    try {
        const skipLink = document.getElementById('skiplink');
        skipLink.parentNode.removeChild(skipLink);
    } catch (e) {
        console.log('error: ', e);
    }

    createColorDropdown();

    const sellPriceInput = createSellPriceInput();
    const similarItemInput = createSimilarItemInput();
    const promotedListingInput = createPromotedListingInput();
    const snipeTitleButton = await createSnipeTitleButton();
    const cleanTitleButton = await createCleanTitleButton();
    const spinner = await createSpinner();
    const snipeListButton = createSnipeListButton();
    const optiListButton = await createOptiListButton();
    const basicListButton = createBasicListButton();

    const actionButtonsDiv = document.createElement('div');
    actionButtonsDiv.id = 'sniper-action-buttons';

    actionButtonsDiv.appendChild(cleanTitleButton);
    actionButtonsDiv.appendChild(snipeTitleButton);
    actionButtonsDiv.appendChild(spinner);
    actionButtonsDiv.appendChild(snipeListButton);
    actionButtonsDiv.appendChild(optiListButton);
    actionButtonsDiv.appendChild(basicListButton);
    actionButtonsDiv.appendChild(sellPriceInput);
    actionButtonsDiv.appendChild(similarItemInput);

    const importButton = createImportButton();
    actionButtonsDiv.appendChild(importButton);
    actionButtonsDiv.appendChild(promotedListingInput);

    const { useReviewImages } = await chrome.storage.local.get('useReviewImages');
    if (useReviewImages) {
        const reviewImagesButton = createLoadReviewImagesButton();
        actionButtonsDiv.appendChild(reviewImagesButton);
    }

    const { useCustomImagePrompt } = await chrome.storage.local.get('useCustomImagePrompt');
    if (useCustomImagePrompt) {
        const generateImageDiv = await createGenerateImageDivV2();
        actionButtonsDiv.appendChild(generateImageDiv);
    }

    await new Promise(resolve => {
        const interval = setInterval(() => {
            if (document.querySelector('#listingToEbayUiButtons')) {
                clearInterval(interval);
                resolve();
            }
        }, 100);
    });

    document.querySelector('#listingToEbayUiButtons').appendChild(actionButtonsDiv);

    const statusContainer = document.querySelector('#listingToEbayUiStatus');

    const maxSpan = document.createElement('span');
    maxSpan.className = 'counted';
    maxSpan.id = 'maximum';
    maxSpan.text = '/ 80';

    const currentSpan = document.createElement('span');
    currentSpan.className = 'counted';
    currentSpan.id = 'current';
    currentSpan.text = '0';

    const textarea = document.createElement('textarea');
    textarea.id = 'the-textarea';
    textarea.cols = '20';
    textarea.rows = '3';

    let placeholder = '';
    for (let i = 0; i < 80; i++) placeholder += 'a';
    textarea.value = placeholder;

    const dropFieldsDiv = document.createElement('div');
    dropFieldsDiv.id = 'divDroppedFields';
    dropFieldsDiv.appendChild(textarea);

    statusContainer.appendChild(dropFieldsDiv);
    statusContainer.appendChild(currentSpan);
    statusContainer.appendChild(maxSpan);

    setupTextareaHighlighting();

    try {
        textarea.value = getFilteredTitle();
    } catch (e) {
        textarea.value = product_data.title;
    }

    updateCharacterCount();
    $('textarea').keyup(function () {
        updateCharacterCount();
    });

    function updateCharacterCount() {
        const length = $('#the-textarea').val().length;
        $('#current').text(length);
        $('#maximum').text('/ 80');
    }
}

if (window.location.href.indexOf('/dp/') > -1) {
    initProductPage().catch(err => console.error(err));
}

// ============================================================
// REVIEW IMAGE LOADING
// ============================================================

function waitForMediaGalleryItems() {
    return new Promise(resolve => {
        const interval = setInterval(() => {
            if (document.querySelectorAll('[class*="media-gallery-item"]').length > 0) {
                console.log('Media items found, proceeding with adding event listeners');
                clearInterval(interval);
                resolve();
            }
        }, 500);
    });
}

let activePopupNotifications = [];

function createLoadReviewImagesButton() {
    let button = document.createElement('button');
    button.id = 'import-review-images-button';
    button.textContent = 'Load Review Images';
    button.classList.add('rainbow-button');

    if (product_data.main_hd_images.length === 0) {
        const noImagesMsg = document.createElement('div');
        noImagesMsg.innerHTML = 'No Review Images Found';
        noImagesMsg.style.color = 'red';
        noImagesMsg.style.fontWeight = 'bold';
        noImagesMsg.style.fontSize = '20px';
        noImagesMsg.style.padding = '10px';
        document.getElementById('imagesContainer').appendChild(noImagesMsg);
        button = noImagesMsg;
    } else {
        button.onclick = async function () {
            console.log('Button clicked');
            const carousel = document.querySelector('[data-csa-c-slot-id*="see_all_image"]');
            if (carousel) {
                carousel.click();
                console.log('Carousel clicked');
                await waitForMediaGalleryItems();
                attachMediaGalleryClickListeners();
            } else {
                console.log('Carousel element not found');
            }
        };
    }
    return button;
}

function attachMediaGalleryClickListeners() {
    function addEventListeners(items) {
        items.forEach(item => {
            if (!item.hasAttribute('data-listener-attached')) {
                item.setAttribute('data-listener-attached', 'true');
                item.addEventListener('click', async function (e) {
                    e.preventDefault();
                    e.stopPropagation();
                    console.log('Media item clicked');
                    item.style.border = '5px solid red';

                    const img = item.querySelector('img');
                    if (img) {
                        let src = img.src;
                        src = enlargeAmazonImage(src);
                        const imageData = await urlToImage(src);
                        createImageAndAppend(imageData, true);
                        showPopupNotification('Picture added!');
                    } else {
                        console.log('No image found in the clicked item.');
                    }
                });
            }
        });
    }

    addEventListeners(document.querySelectorAll('[class*="media-gallery-item"]'));

    const popoverWrapper = document.querySelectorAll('.a-popover-wrapper')[3];
    if (popoverWrapper) {
        new MutationObserver(function (mutations) {
            mutations.forEach(mutation => {
                mutation.addedNodes.forEach(node => {
                    if (node.nodeType === Node.ELEMENT_NODE && node.matches('[class*="media-gallery-item"]')) {
                        addEventListeners([node]);
                    }
                });
            });
        }).observe(popoverWrapper, { childList: true, subtree: true });
    } else {
        console.error('Failed to find the container to observe. Check the selector.');
    }
}

function showPopupNotification(message) {
    const popup = document.createElement('div');
    popup.className = 'popup-notification';
    popup.textContent = message;
    document.body.appendChild(popup);

    const count = activePopupNotifications.length;
    popup.style.right = (20 + (5 * count) % 100) + 'px';
    popup.style.top = (50 + (5 * count) % 100) + 'px';
    activePopupNotifications.push(popup);

    setTimeout(() => {
        popup.style.opacity = '0';
        setTimeout(() => {
            const idx = activePopupNotifications.indexOf(popup);
            if (idx !== -1) activePopupNotifications.splice(idx, 1);
            popup.remove();
        }, 500);
    }, 3000);
}

// ============================================================
// TEXT MANIPULATION BUTTONS
// ============================================================

function createReplaceAndButton() {
    const button = document.createElement('button');
    button.id = 'replace-and-button';
    button.textContent = "Replace 'and' with '&'";
    button.onclick = function () {
        const textarea = document.getElementById('the-textarea');
        let text = textarea.value;
        text = text.replace(/\band\b/gi, '&');
        textarea.value = text;
        updateCharacterCount();
    };
    document.body.prepend(button);
}

function createReplaceWithButton() {
    const button = document.createElement('button');
    button.id = 'replace-with-button';
    button.textContent = "Replace 'with' with '/w'";
    button.onclick = function () {
        const textarea = document.getElementById('the-textarea');
        let text = textarea.value;
        text = text.replace(/\bwith\b/gi, 'w/');
        textarea.value = text;
        updateCharacterCount();
    };
    document.body.prepend(button);
}

function createLowerCaseUnnecessaryButton() {
    const button = document.createElement('button');
    button.id = 'replace-unnecessary-button';
    button.textContent = 'Lower Case Unnecessary Words';
    button.onclick = function () {
        const textarea = document.getElementById('the-textarea');
        let text = textarea.value;
        text = text.toLowerCase()
            .replace(/\b([a-z])/gi, c => c.toUpperCase())
            .replace(/\band\b/gi, '&')
            .replace(/\bwith\b/gi, 'with')
            .replace(/\band\b/gi, 'and')
            .replace(/\bfor\b/gi, 'for')
            .replace(/\bin\b/gi, 'in')
            .replace(/\bor\b/gi, 'or')
            .replace(/\bof\b/gi, 'of')
            .replace(/\bupto\b/gi, 'upto');
        textarea.value = text;
        updateCharacterCount();
    };
    document.body.prepend(button);
}

function createSaveTitleButton() {
    const button = document.createElement('button');
    button.id = 'save-title-button';
    button.textContent = 'Save The Title To Top';
    button.onclick = function () {
        const titleText = document.getElementById('the-textarea').value;
        const table = document.getElementById('listing-data-table');
        const rowNumber = createRow(table);
        createCell(table, { rowNumber, cellValue: rowNumber, headerName: 'Rank' });
        createCell(table, { rowNumber, cellValue: titleText, headerName: 'Title' });
        createCell(table, { rowNumber, cellValue: 'Manuel', headerName: 'Type' });
        createCell(table, { rowNumber, cellValue: titleText.length, headerName: 'Total Characters' });

        const changeButton = createButtonToUpdateTextArea({
            buttonInnerText: 'Change',
            textAreaSelector: '#the-textarea',
            valueToSet: titleText,
            callback: updateTheCharacterCountOnTextArea
        });
        createCellWithButton(table, { button: changeButton, rowNumber, headerName: 'Action' });
    };
    document.body.prepend(button);
}

function createUpdateGoogleSheetsButton() {
    const button = document.createElement('button');
    button.id = 'update-google-sheets-button';
    button.textContent = 'Update Google Sheets';
    button.onclick = function () {
        const fields = [];
        const description = getProductDescriptionAndFeatures();
        const title = getProductTitle();
        const asin = getTheAsinFromHref();
        const customTitle = document.getElementById('the-textarea').value;

        fields.push({ key: 'description', value: description });
        fields.push({ key: 'title', value: title });
        fields.push({ key: 'asin', value: asin });
        fields.push({ key: 'customTitle', value: customTitle });

        updateGoogleSheets(
            fields,
            'https://script.google.com/macros/s/AKfycby6JkD3JFSzYZhreDcB1SOcJ1gMiQjSd7gsX7y619hvnvILuUHOC0pcS7f3qspaIvrP/exec?'
        );
    };
    document.body.prepend(button);
}

// ============================================================
// AI TITLE GENERATION BUTTONS
// ============================================================

async function createSnipeTitleButton() {
    const button = document.createElement('button');
    button.innerHTML = '<b>Snipe Title</b>';
    button.id = 'create-title-v4';
    button.classList.add('create-title-v4');

    button.onclick = function () {
        console.log('clicked button');
        chrome.storage.local.get(['useCustomTitleGenerator'], async function (result) {
            if (result.useCustomTitleGenerator) {
                await generateCustomTitle();
            } else {
                await generateTitlesAndAppendToTable();
            }
        });
    };

    const contextMenu = createContextMenu('snipe-title-context-menu');
    contextMenu.addMenuItem('Customize Your Titles', function () {
        const url = chrome.runtime.getURL('Prompt_Tester_page/index.html');
        window.open(url, '_blank');
    });
    button.addEventListener('contextmenu', function (e) {
        e.preventDefault();
        contextMenu.showMenu(e);
    });

    return button;
}

async function createCleanTitleButton() {
    const button = document.createElement('button');
    button.id = 'clean-title-button';
    button.classList.add('list-button');

    const iconUrl = chrome.runtime.getURL('Favicons/addons/sparkle.png');
    const icon = document.createElement('img');
    icon.src = iconUrl;
    icon.style.width = '25px';
    icon.style.height = '25px';
    icon.style.marginRight = '5px';
    button.appendChild(icon);
    button.innerHTML += '<b>Clean Title</b>';

    button.onclick = async function () {
        button.disabled = true;
        button.innerHTML = '<b>Cleaning Title...</b>';
        await runCleanTitle();
        button.innerHTML = '<b>Cleaned Title!</b>';
        setTimeout(function () {
            button.innerHTML = '<b>Clean Title</b>';
            button.disabled = false;
        }, 2000);
    };

    return button;
}

async function createChatTitleButton() {
    const button = document.createElement('button');
    button.id = 'great_title_chat_gpt_web_version';
    button.classList.add('list-button');

    const iconUrl = chrome.runtime.getURL('Favicons/OpenAi/icon.png');
    const icon = document.createElement('img');
    icon.src = iconUrl;
    icon.style.width = '25px';
    icon.style.height = '25px';
    icon.style.marginRight = '5px';
    button.appendChild(icon);
    button.innerHTML += '<b>Chat Title</b>';

    button.onclick = async function () {
        button.disabled = true;
        button.style.backgroundColor = 'grey';
        button.innerHTML = '<b>Chatting Title...</b>';
        await runChatTitleGeneration();
        button.innerHTML = '<b>Chatted Title!</b>';
        setTimeout(function () {
            button.innerHTML = '';
            button.appendChild(icon);
            button.innerHTML += '<b>Chat Title</b>';
            button.disabled = false;
            button.style.backgroundColor = '#10a37f';
        }, 2000);
    };

    return button;
}

async function createSeoTitleButton() {
    const button = document.createElement('button');
    button.id = 'create-seo-title-v4';
    button.classList.add('list-button');

    const iconUrl = chrome.runtime.getURL('Favicons/OpenAi/icon.png');
    const icon = document.createElement('img');
    icon.src = iconUrl;
    icon.style.width = '25px';
    icon.style.height = '25px';
    icon.style.marginRight = '5px';
    button.appendChild(icon);
    button.innerHTML += '<b>SEO Title</b>';

    button.onclick = async function () {
        button.disabled = true;
        button.style.backgroundColor = 'grey';
        button.innerHTML = '<b>Sniping SEO Title...</b>';
        await runSeoTitleGeneration();
        button.innerHTML = '<b>Sniped SEO Title!</b>';
        setTimeout(function () {
            button.innerHTML = '<b>SEO Title</b>';
            button.disabled = false;
            button.style.backgroundColor = '#3a86ff';
        }, 2000);
    };

    return button;
}

// ============================================================
// TITLE GENERATION RUNNERS
// ============================================================

async function runCleanTitle() {
    turnOffFavicon();
    startSpinner();
    const asin = getTheAsinFromHref();
    document.title = 'Cleaning The Perfect Title - ' + asin + ' please wait...';
    changeFaviconToSniper();

    const description = getProductDescriptionAndFeatures();
    const combined = '(Product Title): ' + getFilteredTitle() + '\n\n(Product Description): ' + description;
    const cleanedTitle = await cleanTitleWithLocalWorkflow(
        document.querySelector('#the-textarea').value,
        combined
    );

    console.log('cleanedTitle: ', cleanedTitle);
    changeFaviconOfPage(chrome.runtime.getURL('Favicons/Completed/received.png'));
    appendTitleToTable(cleanedTitle, 'Cleaned Title');

    const table = document.getElementById('listing-data-table');
    const lastTitleCell = table.rows[table.rows.length - 1].querySelector('.title-cell');
    flyInText(cleanedTitle, lastTitleCell);
    startFlash();
    await new Promise(resolve => setTimeout(resolve, 300));
    stopFlash();
    stopSpinner();
    document.querySelector('#the-textarea').value = cleanedTitle;
    updateTheCharacterCountOnTextArea();
    return cleanedTitle;
}

async function runSeoTitleGeneration(useTextOnly = false) {
    turnOffFavicon();
    startSpinner();
    const asin = getTheAsinFromHref();
    document.title = 'Creating The Perfect Title - ' + asin + ' please wait...';
    changeFaviconToSniper();

    const description = getProductDescriptionAndFeatures();
    const filteredTitle = getFilteredTitle();
    const hiResImages = getHighResProductPictures();
    const regularImages = getProductPictures();
    const imageUrl = hiResImages.length > 0 ? hiResImages[0] : regularImages[0];

    let seoTitles;
    if (useTextOnly) {
        seoTitles = await buildTheSeoTitles(filteredTitle, description);
    } else {
        seoTitles = await new Promise((resolve) => {
            chrome.runtime.sendMessage(
                { type: 'ask_bg_build_the_seo_titles', options: { title: filteredTitle, description, imageUrl } },
                function (response) { resolve(response.seoTitles); }
            );
        });
    }

    console.log('titles: ', seoTitles);
    changeFaviconOfPage(chrome.runtime.getURL('Favicons/Completed/received.png'));

    let bestTitle = '';
    for (let i = 0; i < seoTitles.length; i++) {
        const t = seoTitles[i];
        if (t.length > bestTitle.length && t.length <= 80) bestTitle = t;
    }
    if (bestTitle.length === 0) bestTitle = seoTitles[0];

    for (let i = 0; i < seoTitles.length; i++) {
        const t = seoTitles[i];
        appendTitleToTable(t, bestTitle === t ? 'Perfect SEO Title' : 'Great SEO Title');
        const table = document.getElementById('listing-data-table');
        const lastTitleCell = table.rows[table.rows.length - 1].querySelector('.title-cell');
        flyInText(t, lastTitleCell);
        startFlash();
        await new Promise(resolve => setTimeout(resolve, 300));
        stopFlash();
    }

    stopSpinner();
    startFlash();
    await new Promise(resolve => setTimeout(resolve, 2000));
    stopFlash();
    document.querySelector('#the-textarea').value = bestTitle;
    updateTheCharacterCountOnTextArea();
    return bestTitle;
}

async function runChatTitleGeneration() {
    turnOffFavicon();
    startSpinner();
    const asin = getTheAsinFromHref();
    document.title = 'Creating The Perfect Title - ' + asin + ' please wait...';
    changeFaviconToSniper();

    const description = getProductDescriptionAndFeatures();
    const filteredTitle = getFilteredTitle();
    const titles = await askChatGptForHighQualityTitles(filteredTitle, description);

    console.log('titles: ', titles);
    changeFaviconOfPage(chrome.runtime.getURL('Favicons/Completed/received.png'));

    let bestTitle = '';
    for (let i = 0; i < titles.length; i++) {
        const t = titles[i];
        if (t.length > bestTitle.length && t.length <= 80) bestTitle = t;
    }
    if (bestTitle.length === 0) bestTitle = titles[0];

    for (let i = 0; i < titles.length; i++) {
        const t = titles[i];
        appendTitleToTable(t, bestTitle === t ? 'Perfect Title' : 'Great Title');
        const table = document.getElementById('listing-data-table');
        const lastTitleCell = table.rows[table.rows.length - 1].querySelector('.title-cell');
        flyInText(t, lastTitleCell);
        startFlash();
        await new Promise(resolve => setTimeout(resolve, 300));
        stopFlash();
    }

    stopSpinner();
    startFlash();
    await new Promise(resolve => setTimeout(resolve, 2000));
    stopFlash();
    document.querySelector('#the-textarea').value = bestTitle;
    updateTheCharacterCountOnTextArea();
    return bestTitle;
}

async function generateTitlesAndAppendToTable(productTitle, description) {
    const button = document.querySelector('#create-title-v4');
    button.disabled = true;
    button.style.backgroundColor = 'grey';
    button.innerHTML = '<b>Sniping Title...</b>';
    turnOffFavicon();
    startSpinner();

    if (!productTitle) {
        try {
            productTitle = getFilteredTitle();
        } catch (e) {
            if (!product_data.filteredTitle) throw new Error('No title found');
            productTitle = product_data.filteredTitle;
            description = product_data.descriptionText;
        }
    }
    if (!description) description = getProductDescriptionAndFeatures();

    const { domain } = await chrome.storage.local.get('domain');
    const language = (function (d) {
        if (d === 'de') return 'german';
        if (d === 'com' || d === 'co.uk') return 'english';
        if (d === 'fr') return 'french';
        if (d === 'it') return 'italian';
        if (d === 'es') return 'spanish';
        if (d === 'com.au' || d === 'ca') return 'english';
        if (d === 'nl') return 'dutch';
        return 'english';
    })(domain);

    const { email } = await chrome.storage.local.get(['email']);

    const data = await fetchDataSilent(
        'https://suggestoptimizedtitles-djybcnnsgq-uc.a.run.app',
        { request_type: 'generate_10_titles', product_description: description, product_title: productTitle, language, email }
    );

    console.log('generateTitlesAndAppendToTable data: ', data);

    if (!data) {
        appendTitleToTable('Error - Try Again', 'Perfect Title');
        stopSpinner();
        startFlash();
        await new Promise(resolve => setTimeout(resolve, 2000));
        stopFlash();
        button.innerHTML = '<b>Sniped Title!</b>';
        button.style.backgroundColor = '#3a86ff';
        setTimeout(function () {
            button.innerHTML = '<b>Snipe Title</b>';
            button.disabled = false;
        }, 2000);
        return null;
    }

    let titles = Array.isArray(data) ? data : [data];
    titles = titles.filter(t => t.trim().length > 0).map(t => t.trim());

    let bestTitle = '';
    for (let i = 0; i < titles.length; i++) {
        const t = titles[i];
        if (t.length > bestTitle.length && t.length <= 80) bestTitle = t;
    }
    if (bestTitle.length === 0) bestTitle = titles[0];

    for (let i = 0; i < titles.length; i++) {
        const t = titles[i];
        if (t.length <= 90) {
            appendTitleToTable(t, bestTitle === t ? 'Perfect Title' : 'Great Title');
            const table = document.getElementById('listing-data-table');
            const lastTitleCell = table.rows[table.rows.length - 1].querySelector('.title-cell');
            flyInText(t, lastTitleCell);
            startFlash();
            await new Promise(resolve => setTimeout(resolve, 300));
            stopFlash();
        }
    }

    const textarea = document.querySelector('#the-textarea') || document.querySelector('#listTitle');
    textarea.value = bestTitle;
    try { updateTheCharacterCountOnTextArea(); } catch (e) { }

    stopSpinner();
    startFlash();
    await new Promise(resolve => setTimeout(resolve, 2000));
    stopFlash();

    button.innerHTML = '<b>Sniped Title!</b>';
    button.style.backgroundColor = '#3a86ff';
    setTimeout(function () {
        button.innerHTML = '<b>Snipe Title</b>';
        button.disabled = false;
    }, 2000);

    return bestTitle;
}

async function generateCustomTitle(productTitle, description) {
    const button = document.querySelector('#create-title-v4');
    button.disabled = true;
    button.style.backgroundColor = 'grey';
    button.innerHTML = '<b>Sniping Title...</b>';
    turnOffFavicon();
    startSpinner();

    if (!productTitle) {
        try {
            productTitle = getFilteredTitle();
        } catch (e) {
            if (!product_data.filteredTitle) throw new Error('No title found');
            productTitle = product_data.filteredTitle;
            description = product_data.descriptionText;
        }
    }
    if (!description) description = getProductDescriptionAndFeatures();

    const combined = productTitle + '\n\n' + description;
    let titles = await callCustomTitleApi(combined);

    if (!titles || titles.includes('Error')) {
        appendTitleToTable('Error - Try Again', 'Custom Title');
        stopSpinner();
        startFlash();
        await new Promise(resolve => setTimeout(resolve, 2000));
        stopFlash();
        button.innerHTML = '<b>Sniped Title!</b>';
        button.style.backgroundColor = '#3a86ff';
        setTimeout(function () {
            button.innerHTML = '<b>Snipe Title</b>';
            button.disabled = false;
        }, 2000);
        return null;
    }

    titles = Array.isArray(titles) ? titles : [titles];
    titles = titles.filter(t => t.trim().length > 0).map(t => t.trim());

    let bestTitle = '';
    for (let i = 0; i < titles.length; i++) {
        const t = titles[i];
        if (t.length > bestTitle.length && t.length <= 80) bestTitle = t;
    }
    if (bestTitle.length === 0) bestTitle = titles[0];

    const firstTitle = titles[0];
    appendTitleToTable(firstTitle, 'Custom Title');
    const table = document.getElementById('listing-data-table');
    const lastTitleCell = table.rows[table.rows.length - 1].querySelector('.title-cell');
    flyInText(firstTitle, lastTitleCell);
    startFlash();
    await new Promise(resolve => setTimeout(resolve, 300));
    stopFlash();

    const textarea = document.querySelector('#the-textarea') || document.querySelector('#listTitle');
    textarea.value = firstTitle;
    try { updateTheCharacterCountOnTextArea(); } catch (e) { }

    stopSpinner();
    startFlash();
    await new Promise(resolve => setTimeout(resolve, 2000));
    stopFlash();

    button.innerHTML = '<b>Sniped Title!</b>';
    button.style.backgroundColor = '#3a86ff';
    setTimeout(function () {
        button.innerHTML = '<b>Snipe Title</b>';
        button.disabled = false;
    }, 2000);

    return bestTitle;
}

async function callCustomTitleApi(userMessage, systemMessage = null) {
    if (!systemMessage) {
        const { custom_title_prompt } = await chrome.storage.local.get('custom_title_prompt');
        systemMessage = custom_title_prompt;
        if (!systemMessage) {
            systemMessage = 'Make a optimized, clear eBay title.';
            await chrome.storage.local.set({ custom_title_prompt: systemMessage });
        }
    }

    const { email } = await chrome.storage.local.get(['email']);
    const payload = {
        system_message: systemMessage,
        openai_model: 'gpt-4.1-nano',
        model_definition: { title: 'str' },
        email,
        user_message: userMessage
    };

    try {
        const response = await fetchDataSilent(
            'https://us-central1-silentsnipe-ce4ca.cloudfunctions.net/structured_output',
            payload
        );
        return response.success ? response.result.title : 'Error - ' + response.errorMessage;
    } catch (e) {
        return 'Error - ' + e.message;
    }
}

// ============================================================
// CLEAN TITLE LOGIC
// ============================================================

async function cleanTitleWithOpenAI(ourTitle, competitorTitle) {
    let prompt = await fetch(chrome.runtime.getURL('text_prompts/CleanTitlePrompts/v1.txt')).then(r => r.text());
    prompt = prompt
        .replace('{{Competitor_title}}', competitorTitle)
        .replace('{{Our_title}}', ourTitle);

    const payload = {
        model: 'o1-preview',
        messages: [{ role: 'user', content: prompt }]
    };

    const data = await new Promise((resolve) => {
        chrome.runtime.sendMessage(
            { type: 'fetchData', url: 'https://openai-chat-completion-djybcnnsgq-uc.a.run.app', data: payload },
            function (response) { resolve(response.data); }
        );
    });

    if (!data) return 'Error: No data returned';

    let result = data.content;
    result = result.substring(result.indexOf('{'), result.lastIndexOf('}') + 1);
    result = JSON.parse(result);
    return result.restructured_title;
}

async function cleanTitleWithLocalWorkflow(winningTitle, productDetails) {
    const jsonPrompt = await fetch(chrome.runtime.getURL('prompts_json/clean_title.json')).then(r => r.json());
    jsonPrompt.user_input = 'Unfiltered Title To Mimic: ' + winningTitle + ' \n\n\nItem Details:\n' + productDetails;

    const payload = {
        input_as_text: 'winning_title: ' + winningTitle + ' \n\n\nproduct_details:\n' + productDetails
    };

    let data = await new Promise((resolve) => {
        chrome.runtime.sendMessage(
            { type: 'fetchData', url: 'http://localhost:3000/run-workflow?Content-Type=application/json', data: payload },
            function (response) { resolve(response.data); }
        );
    });

    if (!data) return 'Error: No data returned';

    try { data = JSON.parse(data); } catch (e) { }

    let title = data.title;
    title = title.replace('winning_title:', '').trim();

    try {
        const brand = data.brand;
        title = title.replace(new RegExp(brand, 'gi'), '').trim();
    } catch (e) {
        console.log('error: ', e);
    }

    return title;
}

// ============================================================
// TABLE HELPERS
// ============================================================

function appendOpenAiTitleV3ToTable(openAiResponse) {
    let title = openAiResponse.choices[0].text;
    title = title.trim().replace(/\n/g, ' ');

    const table = document.getElementById('listing-data-table');
    const rowNumber = createRow(table);
    createCell(table, { rowNumber, cellValue: rowNumber, headerName: 'Rank' });
    createCell(table, { rowNumber, cellValue: title, headerName: 'Title' });
    createCell(table, { rowNumber, cellValue: 'myAi-v3', headerName: 'Type' });
    createCell(table, { rowNumber, cellValue: title.length, headerName: 'Total Characters' });

    const changeButton = createButtonToUpdateTextArea({
        buttonInnerText: 'Change',
        textAreaSelector: '#the-textarea',
        valueToSet: title,
        callback: updateTheCharacterCountOnTextArea
    });
    createCellWithButton(table, { button: changeButton, rowNumber, headerName: 'Action' });
}

async function appendTitleToTable(title, type) {
    const table = document.getElementById('listing-data-table');
    const rowNumber = createRow(table);
    createCell(table, { rowNumber, cellValue: rowNumber, headerName: 'Rank' });
    createCell(table, { rowNumber, cellValue: title, headerName: 'Title' });
    createCell(table, { rowNumber, cellValue: type, headerName: 'Type' });
    createCell(table, { rowNumber, cellValue: title.length, headerName: 'Total Characters' });

    const changeButton = createButtonToUpdateTextArea({
        buttonInnerText: 'Change',
        textAreaSelector: '#the-textarea',
        valueToSet: title,
        callback: updateTheCharacterCountOnTextArea
    });
    createCellWithButton(table, { button: changeButton, rowNumber, headerName: 'Action' });
}

// ============================================================
// LISTING BUTTONS
// ============================================================

function createBasicListButton() {
    const button = document.createElement('button');
    button.innerHTML = 'Basic-List';
    button.id = 'standard-listing-button';
    button.classList.add('list-button');

    button.addEventListener('click', function () { listToEbayFree(); });

    const contextMenu = createContextMenu('my-custom-context-menu');
    contextMenu.addMenuItem('List To Poshmark', function () {
        listToPoshmark('standard');
    });
    button.addEventListener('contextmenu', function (e) {
        e.preventDefault();
        contextMenu.showMenu(e);
    });

    return button;
}

function createSnipeListButton() {
    const button = document.createElement('button');
    button.innerHTML = 'Snipe-List';
    button.id = 'snipe-listing-button';
    button.classList.add('list-button');

    button.addEventListener('click', async function () {
        await prepareListingData();
        product_data.listingType = 'paid';
        const similarItemNumber = document.getElementById('similar-item-number').value;
        chrome.runtime.sendMessage({ type: 'deductCredits', amount: 0.2 });
        chrome.runtime.sendMessage(
            { type: 'list_similar_item', productData: product_data, similarItemNumber },
            function (res) { console.log(res.farewell); }
        );
    });

    return button;
}

async function createOptiListButton() {
    const button = document.createElement('button');
    button.innerHTML = '<b>Opti-List</b>';
    button.id = 'paid-listing-button';
    button.classList.add('list-button');

    button.addEventListener('click', function () { listToEbayPaid(); });

    const contextMenu = createContextMenu('my-custom-context-menu-opti');
    contextMenu.addMenuItem('List To Poshmark with AI', function () {
        listToPoshmark('opti');
    });
    button.addEventListener('contextmenu', function (e) {
        e.preventDefault();
        contextMenu.showMenu(e);
    });

    return button;
}

function createImportButton() {
    const button = document.createElement('button');
    button.innerHTML = 'Import';
    button.id = 'import-button';
    button.classList.add('list-button');

    button.addEventListener('click', async function () {
        let clipboardData = await navigator.clipboard.readText();
        console.log('clipboardData: ', clipboardData);

        const data = JSON.parse(clipboardData);
        let price = data.price;
        try {
            price = price.replace(/[^0-9.]/g, '');
        } catch (e) {
            console.log('error: ', e);
        }

        const { sniper_price_markdown } = await chrome.storage.local.get(['sniper_price_markdown']);
        price = (price - sniper_price_markdown).toFixed(2);

        document.getElementById('sell-price').value = price;
        appendTitleToTable(data.title, 'Sniped');
        document.getElementById('similar-item-number').value = data.itemNumber;

        const table = document.getElementById('listing-data-table');
        const lastTitleCell = table.rows[table.rows.length - 1].querySelector('.title-cell');
        flyInText(data.title, lastTitleCell);
        startFlash();
        await new Promise(resolve => setTimeout(resolve, 300));
        stopFlash();

        document.querySelector('#the-textarea').value = data.title;
        document.getElementById('snipe-listing-button').disabled = false;
        document.getElementById('clean-title-button').disabled = false;
    });

    return button;
}

// ============================================================
// LISTING LOGIC
// ============================================================

async function listToEbayFree() {
    await prepareListingData();
    product_data.listingType = 'free';
    chrome.runtime.sendMessage(
        { type: 'list_to_ebay', product_data },
        function (res) { console.log(res.farewell); }
    );
}

async function listToEbayChatGpt() {
    await prepareListingData();
    product_data.listingType = 'chatGpt';
    chrome.runtime.sendMessage(
        { type: 'list_to_ebay', product_data },
        function (res) { console.log(res.farewell); }
    );
}

async function listToEbayPaid() {
    await prepareListingData();
    product_data.listingType = 'paid';
    chrome.runtime.sendMessage(
        { type: 'list_to_ebay', product_data },
        function (res) { console.log(res.farewell); }
    );
    addSkuToSkuListAndSaveToLocalStorage(product_data.sku);
}

async function prepareListingData() {
    addSkuToSkuListAndSaveToLocalStorage(product_data.sku);
    product_data.custom_title = document.getElementById('the-textarea').value;
    console.log('Listed Data', product_data);

    while (!selectedImage) {
        await new Promise(resolve => setTimeout(resolve, 1000));
    }

    product_data.selected_image = selectedImage;
    product_data.custom_price = document.getElementById('sell-price').value;
    product_data.promoted_listing_ad_rate = document.getElementById('promoted-listing').value;

    const arrowIcon = chrome.runtime.getURL('Favicons/Completed/right_arrow.png');
    changeFaviconOfPage(arrowIcon);

    const { shouldGetGspr } = await chrome.storage.local.get('shouldGetGspr');
    if (shouldGetGspr && !product_data.manufacturerInfo) {
        const { manufacturerInfo, responsiblePersonEU, manufacturerInfoText, responsiblePersonEUText } = await fetchGSPR();

        if (manufacturerInfo.country === '' || manufacturerInfo.country === null) {
            document.title = 'ERROR! Manufacturer country is empty!';
            throw new Error('Manufacturer country is empty!');
        }

        product_data.manufacturerInfo = manufacturerInfo;
        product_data.responsiblePersonEU = responsiblePersonEU;
        product_data.manufacturerInfoText = manufacturerInfoText;
        product_data.responsiblePersonEUText = responsiblePersonEUText;
        await new Promise(resolve => setTimeout(resolve, 1000));
    }
}

// ============================================================
// SHOPIFY INTEGRATION
// ============================================================

async function removeShopifyCredentials() {
    await chrome.storage.local.remove('shopify_store_url');
    await chrome.storage.local.remove('shopify_admin_access_token');
    alert('Shopify credentials removed successfully!');
}

async function listItemToShopify() {
    await prepareListingData();

    const { shopify_store_url } = await chrome.storage.local.get('shopify_store_url');
    const { shopify_admin_access_token } = await chrome.storage.local.get('shopify_admin_access_token');

    if (!shopify_store_url || !shopify_admin_access_token) {
        alert('Please set your Shopify store URL and admin access token in the extension settings.');
        await showShopifyCredentialsModal();
    }

    const { response } = await new Promise((resolve) => {
        chrome.runtime.sendMessage(
            { type: 'list_to_shopify', product_data },
            function (res) { resolve(res); }
        );
    });

    console.log('response: ', response);
    alert(response.message);
}

function showShopifyCredentialsModal() {
    return new Promise(resolve => {
        const modal = document.createElement('div');
        modal.style.position = 'fixed';
        modal.style.top = '50%';
        modal.style.left = '50%';
        modal.style.transform = 'translate(-50%, -50%)';
        modal.style.padding = '20px';
        modal.style.backgroundColor = 'white';
        modal.style.border = '1px solid black';
        modal.style.zIndex = '10000';

        const urlLabel = document.createElement('label');
        urlLabel.textContent = 'Shopify Store URL:';
        const urlInput = document.createElement('input');
        urlInput.type = 'text';
        urlInput.placeholder = 'your-store.myshopify.com';
        urlInput.style.width = '100%';
        urlInput.style.marginBottom = '10px';

        const tokenLabel = document.createElement('label');
        tokenLabel.textContent = 'Admin Access Token:';
        const tokenInput = document.createElement('input');
        tokenInput.type = 'password';
        tokenInput.placeholder = 'Your admin access token';
        tokenInput.style.width = '100%';
        tokenInput.style.marginBottom = '10px';

        const saveButton = document.createElement('button');
        saveButton.textContent = 'Save';
        saveButton.style.display = 'block';
        saveButton.style.marginTop = '10px';

        saveButton.addEventListener('click', async () => {
            const storeUrl = urlInput.value.trim();
            const accessToken = tokenInput.value.trim();
            if (storeUrl && accessToken) {
                await chrome.storage.local.set({
                    shopify_store_url: storeUrl,
                    shopify_admin_access_token: accessToken
                });
                alert('Shopify credentials saved successfully!');
                document.body.removeChild(modal);
                resolve();
            } else {
                alert('Both fields are required.');
            }
        });

        modal.appendChild(urlLabel);
        modal.appendChild(urlInput);
        modal.appendChild(tokenLabel);
        modal.appendChild(tokenInput);
        modal.appendChild(saveButton);
        document.body.appendChild(modal);
    });
}

// ============================================================
// POSHMARK INTEGRATION
// ============================================================

async function listToPoshmark(listingType = 'standard') {
    await prepareListingData();
    product_data.listingType = listingType;
    chrome.runtime.sendMessage({ type: 'list_to_poshmark', product_data });
}

// ============================================================
// PROMPT TESTER PAGE (DOMContentLoaded)
// ============================================================

document.addEventListener('DOMContentLoaded', async () => {
    const toggleCustomTitle = document.getElementById('toggleCustomTitle');
    const { useCustomTitleGenerator } = await chrome.storage.local.get(['useCustomTitleGenerator']);
    toggleCustomTitle.checked = !!useCustomTitleGenerator;
    toggleCustomTitle.onchange = async () => {
        await chrome.storage.local.set({ useCustomTitleGenerator: toggleCustomTitle.checked });
    };

    const instructionInput = document.getElementById('instruction');
    const productDescInput = document.getElementById('productDescription');
    const testButton = document.getElementById('testBtn');
    const exampleButton = document.getElementById('exampleBtn');
    const clearButton = document.getElementById('clearBtn');
    const downloadButton = document.getElementById('downloadBtn');
    const generatedTitleEl = document.getElementById('generatedTitle');

    let savedPromptResult = await chrome.storage.local.get(['custom_title_prompt']);
    const savedPrompt = savedPromptResult.custom_title_prompt || null;
    if (savedPrompt) instructionInput.value = savedPrompt;

    const updateTestButtonState = () => {
        testButton.disabled = !(instructionInput.value.trim() && productDescInput.value.trim());
    };
    instructionInput.oninput = productDescInput.oninput = updateTestButtonState;

    exampleButton.onclick = () => {
        instructionInput.value = 'Make a optimized, clear eBay title.';
        productDescInput.value = '3-level adjustable speed: 80 x 80 mm USB fan with three speed settings (low, medium and high)...';
        updateTestButtonState();
    };

    clearButton.onclick = () => {
        instructionInput.value = 'Make a optimized, clear eBay title.';
        productDescInput.value = '';
        generatedTitleEl.textContent = '';
        chrome.storage.local.set({ custom_title_prompt: instructionInput.value });
        updateTestButtonState();
    };

    downloadButton.onclick = async () => {
        await chrome.storage.local.set({ custom_title_prompt: instructionInput.value.trim() });
        downloadButton.textContent = '✅ Saved!';
        setTimeout(() => { downloadButton.textContent = '⬇️ Save Instructions'; }, 2000);
        updateTestButtonState();
    };

    testButton.onclick = async () => {
        generatedTitleEl.textContent = 'Generating...';
        testButton.disabled = true;
        const result = await callCustomTitleApi(productDescInput.value.trim(), instructionInput.value.trim());
        generatedTitleEl.textContent = result;
        testButton.disabled = false;
    };

    updateTestButtonState();
});

document.getElementById('instruction').addEventListener('input', async (e) => {
    await chrome.storage.local.set({ custom_title_prompt: e.target.value.trim() });
});



