// Context Menu Class
class ContextMenu {
    constructor({
        target = null,
        menuItems = [],
        mode = 'dark'
    }) {
        this.target = target;
        this.menuItems = menuItems;
        this.mode = mode;
        this.targetNode = this.getTargetNode();
        this.menuItemsNode = this.getMenuItemsNode();
        this.isOpened = false;
        this.menuContainer = null;
    }

    getTargetNode() {
        const nodes = document.querySelectorAll(this.target);
        if (nodes && nodes.length !== 0) {
            return nodes;
        }
        console.error(`getTargetNode :: "${this.target}" target not found`);
        return [];
    }

    getMenuItemsNode() {
        const itemNodes = [];
        if (!this.menuItems) {
            console.error('getMenuItemsNode :: Please enter menu items');
            return [];
        }
        console.log('this.menuItems', this.menuItems);
        this.menuItems.forEach((menuItem, index) => {
            const itemMarkup = this.createItemMarkup(menuItem);
            itemMarkup.firstChild.setAttribute('style', `animation-delay: ${0.08 * index}s`);
            itemNodes.push(itemMarkup);
        });
        return itemNodes;
    }

    createItemMarkup(menuItem) {
        const button = document.createElement('BUTTON');
        const listItem = document.createElement('LI');

        button.innerHTML = menuItem.content;
        button.classList.add('contextMenu-button');

        if (menuItem.selected) {
            button.classList.add('selected');
        }

        listItem.classList.add('contextMenu-item');

        if (menuItem.divider) {
            listItem.setAttribute('data-divider', menuItem.divider);
        }

        listItem.appendChild(button);

        if (menuItem.events && menuItem.events.length !== 0) {
            Object.entries(menuItem.events).forEach(([eventName, eventHandler]) => {
                button.addEventListener(eventName, eventHandler);
            });
        }

        return listItem;
    }

    renderMenu() {
        console.log('rendering menu', this.menuItemsNode);
        this.menuItemsNode = this.getMenuItemsNode();
        const menuList = document.createElement('UL');

        menuList.classList.add('contextMenu');
        menuList.setAttribute('data-theme', this.mode);

        this.menuItemsNode.forEach(item => menuList.appendChild(item));

        return menuList;
    }

    closeMenu(menuElement) {
        if (this.isOpened) {
            this.isOpened = false;
            menuElement.remove();
        }
    }

    init() {
        document.addEventListener('click', () => this.closeMenu(this.menuContainer));
        window.addEventListener('blur', () => this.closeMenu(this.menuContainer));

        this.targetNode.forEach(node => {
            node.addEventListener('contextmenu', event => {
                console.log('this.menuContainer', this.menuContainer);
                this.menuContainer = this.renderMenu();
                event.preventDefault();
                console.log('this.menuContainer', this.menuContainer);
                this.isOpened = true;

                const { clientX, clientY } = event;
                document.body.appendChild(this.menuContainer);

                const topPosition = clientY + this.menuContainer.scrollHeight >= window.innerHeight
                    ? window.innerHeight - this.menuContainer.scrollHeight - 20
                    : clientY;

                const leftPosition = clientX + this.menuContainer.scrollWidth >= window.innerWidth
                    ? window.innerWidth - this.menuContainer.scrollWidth - 20
                    : clientX;

                this.menuContainer.setAttribute('style',
                    `--width: ${this.menuContainer.scrollWidth}px;
                    --height: ${this.menuContainer.scrollHeight}px;
                    --top: ${topPosition}px;
                    --left: ${leftPosition}px;`
                );
            });
        });
    }
}

// Update Context Menu Function
function updateContextMenu(menuItems, targetId, value) {
    menuItems.forEach(item => {
        if (item.id === targetId) {
            item.selected = false;
        }
    });

    menuItems.forEach(item => {
        if (item.id === targetId && item.value === value) {
            item.selected = true;
        }
    });

    console.log('updateContextMenu', menuItems);
}

// Custom Context Menu Creator
function createCustomContextMenu(menuId) {
    const menuDiv = document.createElement('div');
    menuDiv.id = menuId;
    menuDiv.className = 'custom-context-menu';
    const menuItems = [];

    function hideMenu() {
        if (menuDiv) {
            menuDiv.style.display = 'none';
            menuDiv.remove();
        }
        document.removeEventListener('click', hideMenu);
    }

    return {
        addMenuItem: function (label, clickHandler) {
            const menuItem = document.createElement('div');
            menuItem.className = 'context-menu-item';
            menuItem.textContent = label;
            menuItem.addEventListener('click', function (event) {
                clickHandler(event);
                hideMenu();
            });
            menuDiv.appendChild(menuItem);
            menuItems.push(menuItem);
        },

        showMenu: function (event) {
            event.preventDefault();
            const existingMenu = document.getElementById(menuId);
            if (existingMenu) {
                existingMenu.remove();
            }
            document.body.appendChild(menuDiv);
            menuDiv.style.left = event.pageX + 'px';
            menuDiv.style.top = event.pageY + 'px';
            menuDiv.style.display = 'block';
            menuDiv.addEventListener('click', function (e) {
                e.stopPropagation();
            });
            document.addEventListener('click', hideMenu);
        },

        hideMenu: hideMenu,
        id: menuId,
        element: menuDiv
    };
}

// Check Membership Status
async function checkMembership() {
    return await new Promise(function (resolve, reject) {
        chrome.runtime.sendMessage({
            type: 'checkMembership'
        }, function (response) {
            console.log('result: ', response.membership);
            resolve(response.membership);
        });
    });
}

// Check Credits Available
async function checkCredits() {
    return await new Promise(function (resolve, reject) {
        chrome.runtime.sendMessage({
            type: 'checkCredits'
        }, function (response) {
            console.log('result: ', response.creditsAvailable);
            resolve(response.creditsAvailable);
        });
    });
}

// Deduct Credits
async function deductCredits(amount) {
    if (await checkMembership() !== 'ultimate') {
        return {
            success: false,
            message: 'You must be an Ultimate member to use this feature.'
        };
    }

    if (await checkCredits() === 0) {
        return {
            success: false,
            message: 'You have no credits available.'
        };
    }

    chrome.runtime.sendMessage({
        type: 'deductCredits',
        amount: amount
    });

    return {
        success: true,
        message: 'Credits deducted.'
    };
}

// DOM Content Loaded Event
document.addEventListener('DOMContentLoaded', async () => {
    const {
        amazonLinks,
        minPrice,
        maxPrice,
        fbaOnly,
        threadCount,
        position,
        run_status_bulk_lister,
        closeErrors,
        shouldOnlyListChineseSellers,
        shouldGetGspr,
        shouldOptimizeForSlowComputers,
        maxSuccessfulListings,
        maxSuccessfulListingsToggle
    } = await chrome.storage.local.get([
        'amazonLinks',
        'minPrice',
        'maxPrice',
        'fbaOnly',
        'threadCount',
        'position',
        'run_status_bulk_lister',
        'closeErrors',
        'shouldOnlyListChineseSellers',
        'shouldGetGspr',
        'shouldOptimizeForSlowComputers',
        'maxSuccessfulListings',
        'maxSuccessfulListingsToggle'
    ]);

    console.log('amazonLinks', amazonLinks);
    console.log('minPrice', minPrice);
    console.log('maxPrice', maxPrice);
    console.log('fbaOnly', fbaOnly);
    console.log('threadCount', threadCount);
    console.log('position', position);
    console.log('run_status_bulk_lister', run_status_bulk_lister);
    console.log('closeErrors', closeErrors);
    console.log('shouldOnlyListChineseSellers', shouldOnlyListChineseSellers);
    console.log('shouldGetGspr', shouldGetGspr);
    console.log('shouldOptimizeForSlowComputers', shouldOptimizeForSlowComputers);
    console.log('maxSuccessfulListings', maxSuccessfulListings);

    // Set Amazon links
    if (amazonLinks) {
        document.getElementById('amazon-links').value = amazonLinks.join('\n');
        document.getElementById('total-links-label').innerText = amazonLinks.length;
    }

    // Set default values and update UI
    if (minPrice == null) {
        chrome.storage.local.set({ minPrice: 0 });
    } else {
        document.getElementById('min-price').value = minPrice;
    }

    if (maxPrice == null) {
        chrome.storage.local.set({ maxPrice: 100 });
    } else {
        document.getElementById('max-price').value = maxPrice;
    }

    if (fbaOnly == null) {
        chrome.storage.local.set({ fbaOnly: true });
    } else {
        document.getElementById('fbaOnly').checked = fbaOnly;
    }

    if (closeErrors == null) {
        chrome.storage.local.set({ closeErrors: true });
    } else {
        document.getElementById('closeErrors').checked = closeErrors;
    }

    if (shouldOnlyListChineseSellers == null) {
        chrome.storage.local.set({ shouldOnlyListChineseSellers: false });
    } else {
        document.getElementById('shouldOnlyListChineseSellers').checked = shouldOnlyListChineseSellers;
    }

    if (shouldGetGspr == null) {
        chrome.storage.local.set({ shouldGetGspr: false });
    } else {
        document.getElementById('shouldGetGspr').checked = shouldGetGspr;
    }

    if (shouldOptimizeForSlowComputers == null) {
        chrome.storage.local.set({ shouldOptimizeForSlowComputers: false });
    } else {
        document.getElementById('shouldOptimizeForSlowComputers').checked = shouldOptimizeForSlowComputers;
    }

    if (threadCount == null) {
        chrome.storage.local.set({ threadCount: 1 });
    } else {
        document.getElementById('thread-count').value = threadCount;
    }

    if (position == null) {
        chrome.storage.local.set({ position: 0 });
    } else {
        document.getElementById('position-input').value = position;
    }

    // Handle run status
    if (run_status_bulk_lister == null || run_status_bulk_lister === 0) {
        chrome.storage.local.set({ run_status_bulk_lister: false });
        document.getElementById('pause_button').disabled = true;
    } else if (run_status_bulk_lister === 1) {
        document.getElementById('resume_button').disabled = true;
        document.getElementById('list-btn').disabled = true;
        document.getElementById('standard-listing-button').disabled = true;
        setTextareaBlockedState(true);
    }

    // Update listing counts
    const { successfulListingCount } = await chrome.storage.local.get('successfulListingCount');
    const { failedListingCount } = await chrome.storage.local.get('failedListingCount');

    document.getElementById('successful-listings').textContent = successfulListingCount || 0;
    document.getElementById('failed-listings').textContent = failedListingCount || 0;

    // Handle max successful listings
    if (maxSuccessfulListings == null) {
        chrome.storage.local.set({ maxSuccessfulListings: 0 });
        document.getElementById('max-successful-listings').value = 0;
    } else {
        document.getElementById('max-successful-listings').value = maxSuccessfulListings;
    }

    if (maxSuccessfulListingsToggle == null) {
        chrome.storage.local.set({ maxSuccessfulListingsToggle: false });
        document.getElementById('enable-max-successful-listings').checked = false;
    } else {
        document.getElementById('enable-max-successful-listings').checked = maxSuccessfulListingsToggle;
    }

    // Update progress bar
    const progressPercentage = (position / amazonLinks.length) * 100;
    console.log('updateProgressBar: ', progressPercentage);
    updateProgressBar(progressPercentage);
});

// Event Listeners for form inputs
document.getElementById('amazon-links').addEventListener('change', async event => {
    let links = event.target.value.split('\n');
    links = links.filter(link => link !== '');
    await chrome.storage.local.set({ amazonLinks: links });
    document.getElementById('total-links-label').innerText = links.length;
});

document.getElementById('min-price').addEventListener('change', async event => {
    const value = event.target.value;
    await chrome.storage.local.set({ minPrice: value });
});

document.getElementById('max-price').addEventListener('change', async event => {
    const value = event.target.value;
    await chrome.storage.local.set({ maxPrice: value });
});

document.getElementById('fbaOnly').addEventListener('change', async event => {
    const checked = event.target.checked;
    await chrome.storage.local.set({ fbaOnly: checked });
});

document.getElementById('closeErrors').addEventListener('change', async event => {
    const checked = event.target.checked;
    await chrome.storage.local.set({ closeErrors: checked });
});

document.getElementById('shouldOnlyListChineseSellers').addEventListener('change', async event => {
    const checked = event.target.checked;
    await chrome.storage.local.set({ shouldOnlyListChineseSellers: checked });
});

document.getElementById('shouldGetGspr').addEventListener('change', async event => {
    const checked = event.target.checked;
    await chrome.storage.local.set({ shouldGetGspr: checked });
});

document.getElementById('shouldOptimizeForSlowComputers').addEventListener('change', async event => {
    console.log('shouldOptimizeForSlowComputers: ', event.target.checked);
    const checked = event.target.checked;
    await chrome.storage.local.set({ shouldOptimizeForSlowComputers: checked });
});

document.getElementById('thread-count').addEventListener('change', async event => {
    const value = event.target.value;
    await chrome.storage.local.set({ threadCount: value });
});

document.getElementById('position-input').addEventListener('change', async event => {
    const value = event.target.value;
    await chrome.storage.local.set({ position: value });
});

// Pause Button
document.getElementById('pause_button').addEventListener('click', async function (event) {
    event.preventDefault();
    chrome.storage.local.set({ run_status_bulk_lister: false });
    setTextareaBlockedState(false);
    document.getElementById('pause_button').disabled = true;
    document.getElementById('resume_button').disabled = false;
});

// Resume Button
document.getElementById('resume_button').addEventListener('click', async function (event) {
    event.preventDefault();
    chrome.storage.local.set({ run_status_bulk_lister: true });
    setTextareaBlockedState(true);
    document.getElementById('pause_button').disabled = false;
    document.getElementById('resume_button').disabled = true;
});

// List Button (Optimized)
document.getElementById('list-btn').addEventListener('click', function (event) {
    startListing(event, 'opti');
});

// Standard Listing Button
document.getElementById('standard-listing-button').addEventListener('click', function (event) {
    startListing(event, 'standard');
});

// Chat Listing Button
document.getElementById('chat-listing-button').addEventListener('click', async function (event) {
    console.log('chat-listing-button clicked');
    const chatGptWebStatus = await new Promise(resolve => {
        chrome.runtime.sendMessage({
            type: 'getChatGptWebStatus'
        }, function (response) {
            resolve(response.response);
        });
    });
    console.log('chatGptWebTabId: ', chatGptWebStatus);
    startListing(event, 'chatGpt');
});

// SEO Listing Button
document.getElementById('seo-listing-button').addEventListener('click', async function (event) {
    console.log('seo-listing-button clicked');
    const chatGptWebStatus = await new Promise(resolve => {
        chrome.runtime.sendMessage({
            type: 'getChatGptWebStatus'
        }, function (response) {
            resolve(response.response);
        });
    });
    console.log('chatGptWebTabId: ', chatGptWebStatus);
    startListing(event, 'seo');
});

// Start Listing Function
async function startListing(event, listingType) {
    const membership = await checkMembership();
    console.log('membership', membership);

    if (membership === 'ultimate') {
        if (await checkCredits() !== 0) {
            // Terminate existing processes
            await new Promise(resolve => {
                chrome.runtime.sendMessage({
                    type: 'terminateBulkLister'
                }, function (response) {
                    resolve(response.response);
                });
            });

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

            // Set up for listing
            chrome.storage.local.set({
                run_status_bulk_lister: true,
                bulkListType: listingType
            });

            setTextareaBlockedState(true);
            document.getElementById('resume_button').disabled = true;
            document.getElementById('pause_button').disabled = false;
            document.getElementById('list-btn').disabled = true;
            document.getElementById('standard-listing-button').disabled = true;
            document.getElementById('amazon-links').dispatchEvent(new Event('change'));

            // Update progress
            const { position } = await chrome.storage.local.get('position');
            const { amazonLinks } = await chrome.storage.local.get('amazonLinks');
            updateProgressBar((position / amazonLinks.length) * 100);

            // Reset counters
            chrome.storage.local.set({
                successfulListingCount: 0,
                failedListingCount: 0
            });
            document.getElementById('successful-listings').textContent = 0;
            document.getElementById('failed-listings').textContent = 0;

            chrome.storage.local.set({ amazonLinksStatus: [] });

            // Start listing
            chrome.runtime.sendMessage({ action: 'listAmazonProducts' });
        } else {
            alert('You have no credits left. Please purchase more credits.');
        }
    } else {
        alert('You are not a member of the sniper list. Please contact support.');
    }
}

// Reset Button
document.getElementById('reset-btn').addEventListener('click', async function (event) {
    const terminated = await new Promise(resolve => {
        chrome.runtime.sendMessage({
            type: 'terminateBulkLister'
        }, function (response) {
            resolve(response.response);
        });
    });

    if (terminated === 1) {
        chrome.storage.local.set({ run_status_bulk_lister: false });
        setTextareaBlockedState(false);
        document.getElementById('resume_button').disabled = true;
        document.getElementById('list-btn').disabled = false;
        document.getElementById('standard-listing-button').disabled = false;
        document.getElementById('pause_button').disabled = true;
    }

    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
        const currentTab = tabs[0];
        chrome.tabs.create({
            url: currentTab.url,
            index: currentTab.index + 1
        }, function () {
            chrome.tabs.remove(currentTab.id, function () {
                console.log('Current tab closed and new tab opened to the right with the same URL.');
            });
        });
    });
});

// Update Progress Bar Function
function updateProgressBar(percentage) {
    const progressBar = document.getElementById('progress-bar');
    const progressLabels = document.querySelectorAll('.progress-percentage');

    if (percentage < 0) {
        percentage = 0;
    } else if (percentage > 100) {
        percentage = 100;
    }

    progressBar.style.width = percentage + '%';
    progressLabels.forEach(function (label) {
        label.textContent = percentage + '%';
    });

    if (percentage > 0) {
        progressLabels.forEach(function (label) {
            label.style.visibility = 'visible';
        });
        progressBar.style.backgroundColor = '#90ee90';
    }
}

// Message Listener
chrome.runtime.onMessage.addListener(async function (message, sender, sendResponse) {
    if (message.type === 'updateProgressBar') {
        const { position } = await chrome.storage.local.get('position');
        document.getElementById('position-input').value = position;

        const { amazonLinks } = await chrome.storage.local.get('amazonLinks');
        const progressPercentage = (position / amazonLinks.length) * 100;
        console.log('updateProgressBar: ', progressPercentage);
        updateProgressBar(progressPercentage);

        const { successfulListingCount } = await chrome.storage.local.get('successfulListingCount');
        document.getElementById('successful-listings').textContent = successfulListingCount || 0;

        const { failedListingCount } = await chrome.storage.local.get('failedListingCount');
        document.getElementById('failed-listings').textContent = failedListingCount || 0;
    }

    if (message.type === 'list_amazon_links') {
        console.log('list_amazon_links received');
        fillTextareaWithAmazonLinksAndList(message.amazonLinks);
    }

    if (message.type === 'maxSuccessfulListingsReached') {
        alert('Maximum successful listings reached');
    }
});

// Fill Textarea with Amazon Links
async function fillTextareaWithAmazonLinksAndList(amazonLinks) {
    console.log('fillTextareaWithAmazonLinksAndList called with amazonLinks:', amazonLinks);

    await new Promise(resolve => {
        chrome.runtime.sendMessage({
            type: 'terminateBulkLister'
        }, () => resolve());
    });

    await new Promise(resolve => {
        chrome.runtime.sendMessage({
            type: 'terminateSearch'
        }, () => resolve());
    });

    await chrome.storage.local.set({
        run_status_bulk_lister: false,
        position: 0,
        amazonLinks: amazonLinks,
        successfulListingCount: 0,
        failedListingCount: 0,
        amazonLinksStatus: []
    });

    const textarea = document.getElementById('amazon-links');

    if (amazonLinks.some(link => typeof link === 'object' && link.json)) {
        textarea.value = amazonLinks.map(link => JSON.stringify(link)).join('\n');
    } else {
        textarea.value = amazonLinks.join('\n');
    }

    textarea.dispatchEvent(new Event('change'));

    const positionInput = document.getElementById('position-input');
    positionInput.value = 0;
    positionInput.dispatchEvent(new Event('change'));

    document.getElementById('successful-listings').textContent = 0;
    document.getElementById('failed-listings').textContent = 0;
    updateProgressBar(0);
}

// Status Report Button
document.getElementById('status-report').addEventListener('click', async function (event) {
    event.preventDefault();
    chrome.tabs.create({
        url: chrome.runtime.getURL('bulk_post/table.html')
    });
});

// Clear Button
document.getElementById('clear-btn').addEventListener('click', async function (event) {
    const positionInput = document.getElementById('position-input');
    positionInput.value = 0;
    positionInput.dispatchEvent(new Event('change'));

    const textarea = document.getElementById('amazon-links');
    textarea.value = '';
    textarea.dispatchEvent(new Event('change'));

    updateProgressBar(0);
});

// Set Textarea Blocked State
function setTextareaBlockedState(isBlocked) {
    const textarea = document.getElementById('amazon-links');
    if (isBlocked) {
        textarea.classList.add('blocked');
    } else {
        textarea.classList.remove('blocked');
    }
}

// Import Links Button
document.getElementById('import-links-btn').addEventListener('click', async function (event) {
    event.preventDefault();
    const clipboardText = await navigator.clipboard.readText();
    document.getElementById('add-links').value = clipboardText;
});

// Add Links Button
document.getElementById('add-links-btn').addEventListener('click', async function (event) {
    event.preventDefault();

    const newLinks = document.getElementById('add-links').value;
    const existingLinks = document.getElementById('amazon-links').value.split('\n');
    const linksToAdd = newLinks.split('\n');
    const combinedLinks = existingLinks.concat(linksToAdd);
    const uniqueLinks = [...new Set(combinedLinks)].join('\n');

    document.getElementById('amazon-links').value = uniqueLinks;
    document.getElementById('amazon-links').dispatchEvent(new Event('change'));
    document.getElementById('add-links').value = '';
});

// Context Menu for Standard Listing Button
const standardContextMenu = createCustomContextMenu('my-custom-context-menu');
standardContextMenu.addMenuItem('List To Poshmark', function (event) {
    startListingToMarketplaces(event, 'standard', ['poshmark']);
});

document.querySelector('#standard-listing-button').addEventListener('contextmenu', function (event) {
    event.preventDefault();
    standardContextMenu.showMenu(event);
});

// Context Menu for Optimized Listing Button
const optimizedContextMenu = createCustomContextMenu('optimized-listing-context-menu');
optimizedContextMenu.addMenuItem('List To Poshmark (AI)', function (event) {
    startListingToMarketplaces(event, 'opti', ['poshmark']);
});

document.querySelector('#list-btn').addEventListener('contextmenu', function (event) {
    event.preventDefault();
    optimizedContextMenu.showMenu(event);
});

// Start Listing to Marketplaces
async function startListingToMarketplaces(event, listingType, targetMarketplaces) {
    const membership = await checkMembership();
    console.log('membership', membership);

    if (membership === 'ultimate') {
        if (await checkCredits() !== 0) {
            await new Promise(resolve => {
                chrome.runtime.sendMessage({
                    type: 'terminateBulkLister'
                }, function (response) {
                    resolve(response.response);
                });
            });

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

            chrome.storage.local.set({
                run_status_bulk_lister: true,
                bulkListType: listingType
            });

            setTextareaBlockedState(true);
            document.getElementById('resume_button').disabled = true;
            document.getElementById('pause_button').disabled = false;
            document.getElementById('list-btn').disabled = true;
            document.getElementById('standard-listing-button').disabled = true;
            document.getElementById('amazon-links').dispatchEvent(new Event('change'));

            const { position } = await chrome.storage.local.get('position');
            const { amazonLinks } = await chrome.storage.local.get('amazonLinks');
            updateProgressBar((position / amazonLinks.length) * 100);

            chrome.runtime.sendMessage({
                type: 'start_bulk_listing_to_marketplaces',
                targetMarketplaces: targetMarketplaces,
                listingType: listingType
            });
        } else {
            alert('You have no credits left. Please purchase more credits.');
        }
    } else {
        alert('You are not a member of the sniper list. Please contact support.');
    }
}

// Max Successful Listings Input
document.getElementById('max-successful-listings').addEventListener('change', async event => {
    const value = event.target.value;
    await chrome.storage.local.set({ maxSuccessfulListings: value });
});

// Enable Max Successful Listings Toggle
document.getElementById('enable-max-successful-listings').addEventListener('change', async event => {
    const checked = event.target.checked;
    await chrome.storage.local.set({ maxSuccessfulListingsToggle: checked });
});



