console.log('chat_gpt_web.js loaded');

// Fetches a text file from the extension's bundle
async function fetchExtensionFile(filePath) {
    const url = chrome.runtime.getURL(filePath);
    const response = await fetch(url);
    return await response.text();
}

// Sends a prompt to ChatGPT via the background service worker
// Retries automatically after 5 minutes if no response
async function askChatGpt(prompt, options = { startNewChat: false }) {
    let timeoutHandle;
    return new Promise((resolve, reject) => {
        timeoutHandle = setTimeout(() => {
            console.log('No response received in 5 minutes, retrying...');
            resolve(askChatGpt(prompt, options));
        }, 300000); // 5 minutes

        chrome.runtime.sendMessage(
            { type: 'ask_chat_gpt_web', prompt, options },
            function (result) {
                clearTimeout(timeoutHandle);
                console.log('result: ', result);
                try {
                    resolve(result.response);
                } catch (err) {
                    resolve(askChatGpt(prompt, options));
                }
            }
        );
    });
}

// Asks ChatGPT to generate high-quality eBay listing titles
async function askChatGptForHighQualityTitles(title, description, options = { startNewChat: false }) {
    console.log('askChatGptForHighQualityTitles: ', title, description, options);

    let prompt = await fetchExtensionFile('text_prompts/TitlePrompts/V4.txt');
    prompt = prompt.replace('{{Title}}', title).replace('{{Description}}', description);

    const response = await askChatGpt(prompt, options);

    // Retry with a fresh chat if response is empty/null
    if (!response || response.length === 0 || response === 'undefined' || response == null || response === 'null') {
        return await askChatGptForHighQualityTitles(title, description, { startNewChat: true });
    }

    try {
        const parts = response.split(/Title Versions.*:|Title Variations.*:/i);
        if (parts.length < 2) {
            return await askChatGptForHighQualityTitles(title, description, { startNewChat: true });
        }

        let titles = parts[1].split('\n');
        titles = titles
            .filter(line => line.startsWith('"') && line.endsWith('"'))
            .map(line => line.replace(/^"|"$/g, ''));

        console.log('titles: ', titles);
        return titles;
    } catch (err) {
        console.log('Error in askChatGptForHighQualityTitles: ', err);
        return await askChatGptForHighQualityTitles(title, description, { startNewChat: true });
    }
}

// Enforces eBay title character limits: trims if >80 chars, expands if <73 chars
async function enforceEbayTitleLength(titleCandidate, originalTitle, description) {
    while (titleCandidate.length > 80 || titleCandidate.length < 73) {
        if (titleCandidate.length > 80) {
            titleCandidate = await shortenTitle(titleCandidate, originalTitle, description);
        }
        if (titleCandidate.length < 73) {
            titleCandidate = await lengthenTitle(titleCandidate, originalTitle, description);
        }
    }
    return titleCandidate;
}

// Asks ChatGPT to lengthen a title that's too short
async function lengthenTitle(titleToLengthen, originalTitle, description) {
    let prompt = await fetchExtensionFile('text_prompts/TitlePrompts/LengthenTitle/V2.txt');
    prompt = prompt
        .replace('{{TitleToLengthen}}', titleToLengthen)
        .replace('{{Title}}', originalTitle)
        .replace('{{Description}}', description);

    const response = await askChatGpt(prompt);
    const result = response.split('Enhanced Title:')[1].trim();
    return result.replace(/^"(.*)"$/, '$1');
}

// Asks ChatGPT to shorten a title that's too long
async function shortenTitle(titleToShorten, originalTitle, description) {
    let prompt = await fetchExtensionFile('text_prompts/TitlePrompts/ShortenTitle/V1.txt');
    prompt = prompt
        .replace('{{TitleToShorten}}', titleToShorten)
        .replace('{{Title}}', originalTitle)
        .replace('{{Description}}', description);

    const response = await askChatGpt(prompt);
    if (!response.includes('Shortened Title:')) {
        return await shortenTitle(titleToShorten, originalTitle, description);
    }

    const result = response.split('Shortened Title:')[1].trim();
    return result.replace(/^"(.*)"$/, '$1');
}

// Generates optimized titles using V1 prompt (older flow)
async function generateTitlesV1(title, description) {
    let prompt = await fetchExtensionFile('text_prompts/TitlePrompts/V1.txt');
    prompt = prompt.replace('{{Title}}', title).replace('{{Description}}', description);

    const response = await askChatGpt(prompt);
    const parsedTitles = await parseTitlesFromResponse(response);
    console.log('parsedTitles: ', parsedTitles);
    return parsedTitles;
}

// Identifies a short product type/category keyword from a listing title
async function identifyProductType(title, options = { startNewChat: false }) {
    let prompt = await fetchExtensionFile('text_prompts/ProductTypePrompts/V1.txt');
    prompt = prompt.replace('{{Title}}', title);

    let response = await askChatGpt(prompt, options);

    // Extract text after "popular search query:" label if present
    const match = /popular search query:/i.exec(response);
    if (match) {
        response = response.substring(match.index + match[0].length).trim();
    }

    // Retry if response is too long (more than 9 words)
    if (response.split(' ').length > 9) {
        return await identifyProductType(title, { startNewChat: true });
    }

    response = response.split('\n')[0];
    return response.replace(/^"(.*)"$/, '$1');
}

// Identifies a colloquial/popular search query for a product title
async function identifyPopularSearchQuery(title, options = { startNewChat: false }) {
    let prompt = await fetchExtensionFile('text_prompts/Identify_Popular_Search_Query_Prompts/V2.txt');
    prompt = prompt.replace('{{Title}}', title);

    let response = await askChatGpt(prompt, options);

    // Extract text after "colloquial search term:" label if present
    const match = /colloquial search term:/i.exec(response);
    if (match) {
        response = response.substring(match.index + match[0].length).trim();
    }

    if (response.split(' ').length > 9) {
        return await identifyPopularSearchQuery(title, { startNewChat: true });
    }

    response = response.split('\n')[0];
    return response.replace(/^"(.*)"$/, '$1');
}

// Generates a short banner/main benefit phrase for a product
async function generateMainBenefit(title, description, options = { startNewChat: false }) {
    let prompt = await fetchExtensionFile('text_prompts/MainBenefitPrompts/V1.txt');
    prompt = prompt.replace('{{Title}}', title).replace('{{Description}}', description);

    const response = await askChatGpt(prompt, options);

    // If it's a single quoted line, return it directly
    if (response.split('\n').length === 1 && response.startsWith('"')) {
        return response.replace(/^"(.*)"$/, '$1');
    }

    if (!response.includes('Banner Words:')) {
        return await generateMainBenefit(title, description, { startNewChat: true });
    }

    const result = response.split('Banner Words:')[1].trim();
    return result.replace(/^"(.*)"$/, '$1');
}

// Generates an HTML product description for eBay listings
async function generateHTMLDescription(title, description) {
    let prompt = await fetchExtensionFile('text_prompts/DescriptionPrompts/V1.txt');
    prompt = prompt.replace('{{Title}}', title).replace('{{Description}}', description);

    let response = await askChatGpt(prompt, { startNewChat: true });

    if (!response.includes('<h2>')) {
        return await generateHTMLDescription(title, description);
    }

    // Strip any "HTML copy code" preamble if present
    if (/html\s*copy\s*code/i.test(response)) {
        const parts = response.split(/html\s*copy\s*code/i);
        response = parts[1].trim();
    }

    // Trim to last </p> tag
    const match = response.match(/[\s\S]*<\/p>/);
    if (match) response = match[0];

    return response;
}

// Parses "Optimized Title #N: ..." lines from a ChatGPT response
async function parseTitlesFromResponse(responseText) {
    return new Promise(resolve => {
        let titles = [];
        const lines = responseText.trim().split('\n');

        // Include first line if it's not an "Optimized Title #N:" header
        if (lines[0] && !lines[0].startsWith('Optimized Title #')) {
            titles.push(lines[0].trim());
        }

        const titlePattern = /^(Optimized Title #[0-9]+:)\s*(.*)$/gm;
        let match;
        while (null !== (match = titlePattern.exec(responseText))) {
            titles.push(match[2].trim());
        }

        resolve(titles);
    });
}

// Parses a JSON array of values from a response string
function parseValuesFromJson(responseText) {
    try {
        const jsonMatch = responseText.match(/{[^}]+}/);
        if (!jsonMatch) return null;
        const parsed = JSON.parse(jsonMatch[0]);
        return parsed.hasOwnProperty('values') && parsed.values.length > 0 ? parsed.values : null;
    } catch (err) {
        return null;
    }
}

// Parses a single JSON object from a response string
function parseJsonObject(responseText) {
    try {
        const jsonMatch = responseText.match(/{[^}]+}/);
        return jsonMatch ? JSON.parse(jsonMatch[0]) : null;
    } catch (err) {
        return null;
    }
}

// Generates SEO-optimized titles using product type + keywords (V2 prompt)
async function generateSEOTitles(productType, title, description, keywords, options = { startNewChat: true }) {
    let prompt = await fetchExtensionFile('text_prompts/SEO_Title_Prompt/V2.txt');
    prompt = prompt
        .replace('{{Title}}', title)
        .replace('{{Description}}', description)
        .replace('{{Keywords}}', keywords.join(', '))
        .replace('{{ProductType}}', productType);

    const response = await askChatGpt(prompt, options);

    if (!response || response.length === 0 || response === 'undefined' || response == null || response === 'null') {
        return await generateSEOTitles(title, description, keywords, { startNewChat: true });
    }

    try {
        const parts = response.split(/Title Versions.*:|Title Variations.*:/i);
        let titlesSection;

        if (parts.length === 1 && parts[0].startsWith('"')) {
            titlesSection = parts[0];
        } else {
            if (parts.length < 2) {
                return await generateSEOTitles(title, description, keywords, { startNewChat: true });
            }
            titlesSection = parts[1];
        }

        let titles = titlesSection.split('\n');
        titles = titles
            .filter(line => line.startsWith('"') && line.endsWith('"'))
            .map(line => line.replace(/^"|"$/g, ''));

        console.log('titles: ', titles);
        return titles;
    } catch (err) {
        console.log('Error in askChatGptToCreateSEOTitles: ', err);
        return await generateSEOTitles(title, description, keywords, { startNewChat: true });
    }
}

// ─── Popup UI ────────────────────────────────────────────────────────────────

let requestCounter = 0;

// "Send" button: submits a manual prompt to ChatGPT and displays the response
document.getElementById('sendMessage').addEventListener('click', async function () {
    const inputEl = document.getElementById('messageInput');
    const messageText = inputEl.value;
    const chatHistory = document.getElementById('chatHistory');

    if (!messageText) return;

    requestCounter++;
    const requestNum = requestCounter;
    const startTime = Date.now();
    inputEl.value = '';

    // Append user message
    const requestDiv = document.createElement('div');
    requestDiv.classList.add('message', 'request');
    requestDiv.innerHTML = `<span class="request-label">Request ${requestNum}:</span> You: ${messageText}`;
    chatHistory.appendChild(requestDiv);

    // Append response placeholder
    const responseDiv = document.createElement('div');
    responseDiv.classList.add('message', 'response');
    responseDiv.innerHTML = `<span class="response-label">Response ${requestNum}:</span> <span class="loading">Waiting for response...</span>`;

    const timeTrackerContainer = document.createElement('div');
    timeTrackerContainer.classList.add('time-tracker-container');

    const timeTrackerSpan = document.createElement('span');
    timeTrackerSpan.classList.add('time-tracker');
    timeTrackerContainer.appendChild(timeTrackerSpan);
    responseDiv.appendChild(timeTrackerContainer);
    chatHistory.appendChild(responseDiv);

    // Live elapsed time counter
    let timerInterval = setInterval(() => {
        const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
        timeTrackerSpan.innerText = `[${elapsed}s]`;
    }, 100);

    const result = await askChatGpt(messageText);
    clearInterval(timerInterval);
    fetchAndDisplayLastMessage(); // Refresh log

    const totalTime = ((Date.now() - startTime) / 1000).toFixed(1);
    responseDiv.querySelector('.loading').innerText = `ChatGPT: ${result}`;
    timeTrackerSpan.classList.add('time-tracker-final');
    timeTrackerSpan.innerText = `[Time taken: ${totalTime}s]`;
});

// Mock async response (unused/testing)
async function mockAskChatGpt(prompt) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve('Response to: ' + prompt);
        }, Math.random() * 2000 + 1000);
    });
}

// Appends a timestamped log entry to the log panel
function appendLogMessage(text) {
    const logContainer = document.getElementById('logMessages');
    const timestamp = new Date().toLocaleTimeString();

    const logEntry = document.createElement('div');
    logEntry.classList.add('log-message');

    const timestampSpan = document.createElement('span');
    timestampSpan.classList.add('timestamp');
    timestampSpan.textContent = `[${timestamp}] `;
    logEntry.appendChild(timestampSpan);

    const textSpan = document.createElement('span');
    textSpan.classList.add('log-text');
    textSpan.textContent = text;
    logEntry.appendChild(textSpan);

    logContainer.firstChild
        ? logContainer.insertBefore(logEntry, logContainer.firstChild)
        : logContainer.appendChild(logEntry);
}

// Listens for log messages from the background service worker
function setupLogMessageListener() {
    chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
        if (message.type === 'log') {
            appendLogMessage(message.log);
        }
    });
}

setupLogMessageListener();

// Clear log button
document.getElementById('clearLog').addEventListener('click', function () {
    document.getElementById('logMessages').innerHTML = '';
});

// "Get Last Message" button: fetches the last GPT message from the background worker
document.getElementById('getLastMessage').addEventListener('click', async function () {
    console.log('getLastMessage');
    const lastMessage = await new Promise(resolve => {
        chrome.runtime.sendMessage({ type: 'get_last_message' }, function (result) {
            resolve(result.response.message);
        });
    });
    console.log(lastMessage);
    appendLogMessage(lastMessage);
});

// Programmatically triggers "Get Last Message" (called after each chat response)
function fetchAndDisplayLastMessage() {
    document.getElementById('getLastMessage').click();
}



