Amazon Review Toolkit

Complete review writing toolkit with Unicode formatting, templates, phrases, auto-save, and cloud sync

// ==UserScript==
// @name         Amazon Review Toolkit
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Complete review writing toolkit with Unicode formatting, templates, phrases, auto-save, and cloud sync
// @author       Prismaris
// @match        https://www.amazon.com/review/review-your-purchases*
// @match        https://www.amazon.com/review/create-review*
// @match        https://www.amazon.com/reviews/edit-review/*
// @match        https://www.amazon.ca/review/review-your-purchases*
// @match        https://www.amazon.ca/review/create-review*
// @match        https://www.amazon.ca/reviews/edit-review/*
// @match        https://www.amazon.co.uk/review/review-your-purchases*
// @match        https://www.amazon.co.uk/review/create-review*
// @match        https://www.amazon.co.uk/reviews/edit-review/*
// @match        https://www.amazon.de/review/review-your-purchases*
// @match        https://www.amazon.de/review/create-review*
// @match        https://www.amazon.de/reviews/edit-review/*
// @match        https://www.amazon.fr/review/review-your-purchases*
// @match        https://www.amazon.fr/review/create-review*
// @match        https://www.amazon.fr/reviews/edit-review/*
// @match        https://www.amazon.it/review/review-your-purchases*
// @match        https://www.amazon.it/review/create-review*
// @match        https://www.amazon.it/reviews/edit-review/*
// @match        https://www.amazon.es/review/review-your-purchases*
// @match        https://www.amazon.es/review/create-review*
// @match        https://www.amazon.es/reviews/edit-review/*
// @match        https://www.amazon.co.jp/review/review-your-purchases*
// @match        https://www.amazon.co.jp/review/create-review*
// @match        https://www.amazon.co.jp/reviews/edit-review/*
// @match        https://www.amazon.in/review/review-your-purchases*
// @match        https://www.amazon.in/review/create-review*
// @match        https://www.amazon.in/reviews/edit-review/*
// @match        https://www.amazon.com.au/review/review-your-purchases*
// @match        https://www.amazon.com.au/review/create-review*
// @match        https://www.amazon.com.au/reviews/edit-review/*
// @grant        GM_xmlhttpRequest
// @connect      pastebin.com
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // Add CSS styles
    const styles = `
        #reviewText {
            min-height: 28em !important;
            /* height: 28em !important; */
            resize: vertical;
        }
        .unicode-toolbar {
            position: relative;
            z-index: 10;
            display: flex;
            gap: 8px;
            margin-bottom: 6px;
            align-items: center;
        }
        .unicode-toolbar button {
            position: relative;
            overflow: hidden;
            will-change: transform, background-color;
            font-size: 1.1em;
            padding: 2px 8px;
            border-radius: 4px;
            border: 1px solid #bbb;
            background: #f8f8f8;
            cursor: pointer;
            transition: background 0.15s ease, color 0.15s ease, transform 0.1s ease;
            outline: none;
            user-select: none;
        }
        .unicode-toolbar button:active {
            transform: scale(0.95);
        }
        .unicode-toolbar button:focus {
            outline: 2px solid #1976d2;
            outline-offset: 2px;
        }
        .unicode-toolbar button[aria-pressed="true"] {
            background-color: #1976d2 !important;
            color: #fff !important;
        }
        .unicode-toolbar button[aria-pressed="false"] {
            background-color: #f8f8f8 !important;
            color: inherit !important;
        }
        .unicode-toolbar button {
            -webkit-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
        }
        /* Drag-and-drop highlight for media upload */
        .in-context-ryp__form-field--mediaUploadInput--custom-wrapper.dragover {
            outline: 2px solid #2196f3 !important;
            box-shadow: 0 0 0 2px #2196f3 !important;
            background: #e3f2fd !important;
            transition: outline 0.2s, box-shadow 0.2s, background 0.2s;
        }
        /* Pastebin popover styles */
        .pastebin-popover {
            position: absolute;
            top: 100%;
            right: 0;
            background: white;
            border: 1px solid #ddd;
            border-radius: 6px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.15);
            z-index: 1000;
            min-width: 200px;
            display: none;
            font-size: 14px;
        }
        .pastebin-popover.show {
            display: block;
        }
        .pastebin-popover-item {
            padding: 8px 12px;
            cursor: pointer;
            display: flex;
            align-items: center;
            gap: 8px;
            transition: background 0.15s;
        }
        .pastebin-popover-item:hover {
            background: #f5f5f5;
        }
        .pastebin-popover-item:first-child {
            border-radius: 6px 6px 0 0;
        }
        .pastebin-popover-item:last-child {
            border-radius: 0 0 6px 6px;
        }
        .pastebin-popover-item:not(:last-child) {
            border-bottom: 1px solid #eee;
        }
        .pastebin-popover-item.disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }
        .pastebin-popover-item.disabled:hover {
            background: transparent;
        }
        /* Configuration modal styles */
        .pastebin-modal {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0,0,0,0.5);
            z-index: 10000;
            display: none;
            align-items: center;
            justify-content: center;
        }
        .pastebin-modal.show {
            display: flex;
        }
        .pastebin-modal-content {
            background: white;
            border-radius: 8px;
            padding: 24px;
            max-width: 500px;
            width: 90%;
            max-height: 80vh;
            overflow-y: auto;
        }
        .pastebin-modal-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
        }
        .pastebin-modal-title {
            font-size: 18px;
            font-weight: 600;
            margin: 0;
        }
        .pastebin-modal-close {
            background: none;
            border: none;
            font-size: 20px;
            cursor: pointer;
            padding: 0;
            width: 30px;
            height: 30px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 4px;
            transition: background 0.15s;
        }
        .pastebin-modal-close:hover {
            background: #f5f5f5;
        }
        .pastebin-form-group {
            margin-bottom: 16px;
        }
        .pastebin-form-label {
            display: block;
            font-weight: 500;
            margin-bottom: 4px;
            color: #333;
        }
        .pastebin-form-input {
            width: 100%;
            padding: 8px 12px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 14px;
            box-sizing: border-box;
        }
        .pastebin-form-input:focus {
            outline: none;
            border-color: #1976d2;
            box-shadow: 0 0 0 2px rgba(25, 118, 210, 0.2);
        }
        .pastebin-form-input[readonly] {
            background: #f8f8f8;
            color: #666;
        }
        .pastebin-form-help {
            font-size: 12px;
            color: #666;
            margin-top: 4px;
        }
        .pastebin-form-help a {
            color: #1976d2;
            text-decoration: none;
        }
        .pastebin-form-help a:hover {
            text-decoration: underline;
        }
        .pastebin-form-actions {
            display: flex;
            gap: 8px;
            margin-top: 20px;
            flex-wrap: wrap;
        }
        .pastebin-btn {
            padding: 8px 16px;
            border: 1px solid #ddd;
            border-radius: 4px;
            background: #f8f8f8;
            cursor: pointer;
            font-size: 14px;
            transition: all 0.15s;
            min-width: 100px;
        }
        .pastebin-btn:hover {
            background: #e8e8e8;
        }
        .pastebin-btn:disabled {
            opacity: 0.6;
            cursor: not-allowed;
        }
        .pastebin-btn-primary {
            background: #1976d2;
            color: white;
            border-color: #1976d2;
        }
        .pastebin-btn-primary:hover {
            background: #1565c0;
        }
        /* Sync status indicators */
        .template-sync-status {
            display: inline-block;
            width: 8px;
            height: 8px;
            border-radius: 50%;
            margin-left: 6px;
        }
        .sync-status-synced { background: #4caf50; }
        .sync-status-pending { background: #ff9800; }
        .sync-status-failed { background: #f44336; }
        .sync-status-none { background: #ccc; }
        /* Loading spinner */
        .pastebin-loading {
            display: inline-block;
            width: 12px;
            height: 12px;
            border: 2px solid #f3f3f3;
            border-top: 2px solid #1976d2;
            border-radius: 50%;
            animation: spin 1s linear infinite;
            margin-right: 6px;
        }
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
        /* Template manager modal styles */
        .template-manager-modal {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0,0,0,0.5);
            z-index: 10000;
            display: none;
            align-items: center;
            justify-content: center;
        }
        .template-manager-modal.show {
            display: flex;
        }
        .template-manager-content {
            background: white;
            border-radius: 8px;
            padding: 24px;
            max-width: 600px;
            width: 90%;
            max-height: 80vh;
            overflow-y: auto;
        }
        .template-manager-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
        }
        .template-manager-title {
            font-size: 18px;
            font-weight: 600;
            margin: 0;
        }
        .template-manager-close {
            background: none;
            border: none;
            font-size: 20px;
            cursor: pointer;
            padding: 0;
            width: 30px;
            height: 30px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 4px;
            transition: background 0.15s;
        }
        .template-manager-close:hover {
            background: #f5f5f5;
        }
        .template-manager-body {
            max-height: 400px;
            overflow-y: auto;
        }
        .template-list {
            display: flex;
            flex-direction: column;
            gap: 12px;
        }
        .template-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 12px;
            border: 1px solid #e0e0e0;
            border-radius: 6px;
            background: #fafafa;
            transition: all 0.15s;
        }
        .template-item:hover {
            background: #f5f5f5;
            border-color: #ccc;
        }
        .template-info {
            flex: 1;
            min-width: 0;
        }
        .template-name {
            font-weight: 500;
            margin-bottom: 4px;
            color: #333;
        }
        .template-preview {
            font-size: 12px;
            color: #666;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        .template-actions {
            display: flex;
            gap: 8px;
            margin-left: 12px;
        }
        .template-btn {
            padding: 6px 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
            background: white;
            cursor: pointer;
            font-size: 14px;
            transition: all 0.15s;
            min-width: 32px;
        }
        .template-btn:hover {
            background: #f0f0f0;
        }
        .template-btn:disabled {
            opacity: 0.6;
            cursor: not-allowed;
        }
        .template-insert-btn:hover {
            background: #e8f5e8;
            border-color: #4caf50;
        }
        .template-delete-btn:hover {
            background: #ffe8e8;
            border-color: #f44336;
        }
        .no-templates {
            text-align: center;
            color: #666;
            font-style: italic;
            padding: 40px 20px;
        }
        /* Tab styles */
        .template-manager-tabs {
            display: flex;
            border-bottom: 1px solid #e0e0e0;
            margin-bottom: 20px;
        }
        .tab-btn {
            background: none;
            border: none;
            padding: 12px 20px;
            cursor: pointer;
            font-size: 14px;
            font-weight: 500;
            color: #666;
            border-bottom: 2px solid transparent;
            transition: all 0.15s;
        }
        .tab-btn:hover {
            background: #f5f5f5;
            color: #333;
        }
        .tab-btn.active {
            color: #1976d2;
            border-bottom-color: #1976d2;
            background: #f8f9fa;
        }
        .tab-content {
            animation: fadeIn 0.2s ease-in-out;
        }
        @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
        }
    `;
    // Inject CSS
    const styleSheet = document.createElement('style');
    styleSheet.textContent = styles;
    document.head.appendChild(styleSheet);

    // Add CSS for uploading state
    const uploadStyle = document.createElement('style');
    uploadStyle.textContent = `
        .amazon-uploading {
            position: relative;
        }
        .amazon-uploading .google-photos-btn,
        .amazon-uploading .amazon-dnd-dragtext,
        .amazon-uploading [aria-label="Add a photo"],
        .amazon-uploading .add-photo-btn,
        .amazon-uploading > div, /* fallback for + button */
        .amazon-uploading > button {
            opacity: 0.2 !important;
            pointer-events: none !important;
            filter: blur(1px);
        }
        .amazon-uploading .amazon-dnd-pastetext {
            opacity: 1 !important;
            filter: none !important;
        }
    `;
    document.head.appendChild(uploadStyle);

    // --- PASTEBIN API CONFIGURATION ---
    const PASTEBIN_CONFIG = {
        API_URL: 'https://pastebin.com/api/api_post.php',
        LOGIN_URL: 'https://pastebin.com/api/api_login.php',
        API_DEV_KEY: null,
        API_USER_KEY: null,
        API_USER_NAME: null,
        API_USER_PASSWORD: null,
        PASTE_FORMAT: 'text',
        PASTE_PRIVACY: '0', // 0=public, 1=unlisted, 2=private
        PASTE_EXPIRE: 'N'   // N=never, 10M=10 minutes, 1H=1 hour, 1D=1 day, 1W=1 week, 2W=2 weeks, 1M=1 month, 6M=6 months, 1Y=1 year
    };

    // Load configuration from localStorage
    function loadPastebinConfig() {
        try {
            const saved = localStorage.getItem('amazon_pastebin_config');
            if (saved) {
                const config = JSON.parse(saved);
                PASTEBIN_CONFIG.API_DEV_KEY = config.api_dev_key || null;
                PASTEBIN_CONFIG.API_USER_KEY = config.api_user_key || null;
                PASTEBIN_CONFIG.API_USER_NAME = config.api_user_name || null;
                PASTEBIN_CONFIG.API_USER_PASSWORD = config.api_user_password || null;
            }
        } catch (e) {
            console.error('Error loading Pastebin config:', e);
        }
    }

    // Save configuration to localStorage
    function savePastebinConfig() {
        try {
            const config = {
                api_dev_key: PASTEBIN_CONFIG.API_DEV_KEY,
                api_user_key: PASTEBIN_CONFIG.API_USER_KEY,
                api_user_name: PASTEBIN_CONFIG.API_USER_NAME,
                api_user_password: PASTEBIN_CONFIG.API_USER_PASSWORD
            };
            localStorage.setItem('amazon_pastebin_config', JSON.stringify(config));
        } catch (e) {
            console.error('Error saving Pastebin config:', e);
        }
    }

    // Generate API User Key using Pastebin login API
    async function generatePastebinUserKey(username, password) {
        if (!PASTEBIN_CONFIG.API_DEV_KEY) {
            throw new Error('API Dev Key is required to generate User Key');
        }

        const data = {
            api_dev_key: PASTEBIN_CONFIG.API_DEV_KEY,
            api_user_name: username,
            api_user_password: password
        };

        // Convert to URLSearchParams for proper encoding
        const params = new URLSearchParams();
        Object.entries(data).forEach(([key, value]) => {
            if (value !== null && value !== undefined) {
                params.append(key, value);
            }
        });

        console.log('Generating Pastebin User Key for username:', username);

        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: 'POST',
                url: PASTEBIN_CONFIG.LOGIN_URL,
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                data: params.toString(),
                onload: function(response) {
                    const result = response.responseText.trim();
                    console.log('Pastebin login response:', result);

                    // Check for API errors
                    if (result.startsWith('Bad API request')) {
                        console.error('Pastebin login failed:', result);
                        reject(new Error(`Login failed: ${result}`));
                        return;
                    }

                    // Check if response looks like a valid user key (32 character hex string)
                    if (result.length === 32 && /^[a-f0-9]+$/i.test(result)) {
                        console.log('Successfully generated User Key');
                        resolve(result);
                    } else {
                        console.error('Unexpected login response format:', result);
                        reject(new Error('Invalid response from Pastebin login API'));
                    }
                },
                onerror: function(error) {
                    console.error('Pastebin login request failed:', error);
                    reject(new Error('Network error during login. Please check your internet connection.'));
                }
            });
        });
    }

    // Check if Pastebin is configured
    function isPastebinConfigured() {
        const hasKey = !!(PASTEBIN_CONFIG.API_DEV_KEY);
        if (hasKey) {
            console.log('Pastebin API configured with dev key length:', PASTEBIN_CONFIG.API_DEV_KEY.length);
            console.log('Dev key format looks valid:', /^[a-zA-Z0-9_-]+$/.test(PASTEBIN_CONFIG.API_DEV_KEY));
        }
        return hasKey;
    }

    // --- PASTEBIN API FUNCTIONS ---
    async function pastebinRequest(data) {
        if (!isPastebinConfigured()) {
            throw new Error('Pastebin API not configured');
        }

        // Prepare the request data with proper parameter names
        const requestData = {
            api_dev_key: PASTEBIN_CONFIG.API_DEV_KEY,
            ...data
        };

        // Convert to URLSearchParams for proper encoding
        const params = new URLSearchParams();
        Object.entries(requestData).forEach(([key, value]) => {
            if (value !== null && value !== undefined) {
                params.append(key, value);
            }
        });

        console.log('Sending Pastebin API request to:', PASTEBIN_CONFIG.API_URL);
        console.log('Request params:', params.toString());
        console.log('Dev key being used:', PASTEBIN_CONFIG.API_DEV_KEY.substring(0, 10) + '...');

        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: 'POST',
                url: PASTEBIN_CONFIG.API_URL,
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                data: params.toString(),
                onload: function(response) {
                    const result = response.responseText;
                    console.log('Pastebin API response status:', response.status);
                    console.log('Pastebin API response:', result);
                    console.log('Response length:', result.length);

                    // Check for API errors
                    if (result.startsWith('Bad API request')) {
                        console.error('Pastebin API returned error:', result);
                        reject(new Error(`Pastebin API Error: ${result}`));
                        return;
                    }

                    // Check if response looks like an error page
                    if (result.includes('cors-anywhere') ||
                        result.includes('Access-Control-Allow-Origin') ||
                        result.includes('/corsdemo') ||
                        result.length < 10) {
                        console.error('Unexpected response format:', result);
                        reject(new Error('Unexpected response from Pastebin API. Please check your API keys.'));
                        return;
                    }

                    console.log('Pastebin API request successful, response:', result);
                    resolve(result);
                },
                onerror: function(error) {
                    console.error('Pastebin API request failed:', error);
                    reject(new Error('Network error. Please check your internet connection and try again.'));
                }
            });
        });
    }

    // Create a new paste
    async function createPastebinPaste(name, content, isReview = false) {
        const data = {
            api_option: 'paste',
            api_paste_code: content,
            api_paste_name: isReview ? name : `Amazon Review Template: ${name}`,
            api_paste_format: isReview ? 'json' : PASTEBIN_CONFIG.PASTE_FORMAT,
            api_paste_private: PASTEBIN_CONFIG.PASTE_PRIVACY,
            api_paste_expire_date: PASTEBIN_CONFIG.PASTE_EXPIRE
        };

        // Add user key if available (required for private pastes)
        if (PASTEBIN_CONFIG.API_USER_KEY) {
            data.api_user_key = PASTEBIN_CONFIG.API_USER_KEY;
        }

        console.log('Creating paste with data:', { ...data, api_paste_code: '[content]' });
        const response = await pastebinRequest(data);
        console.log('Raw paste response:', response);

        // Validate the response
        if (!response || response.includes('Bad API request') || response.includes('error')) {
            throw new Error(`Pastebin API error: ${response}`);
        }

        // Extract paste key from response
        let pasteKey;
        if (response.startsWith('https://pastebin.com/')) {
            // Response is a full URL, extract the key
            pasteKey = response.split('/').pop();
            console.log('Extracted paste key from URL:', pasteKey);
        } else {
            // Response is already a paste key
            pasteKey = response;
        }

        // Validate the paste key format
        if (!pasteKey || pasteKey.length !== 8) {
            throw new Error(`Invalid paste key format. Expected 8 characters, got: ${pasteKey}`);
        }

        return pasteKey;
    }

    // Note: Pastebin API does not support updating existing pastes
    // The updatePastebinPaste function has been removed as it's not functional
    // Instead, we use delete + recreate approach for all paste updates:
    // - Template updates: delete old paste, create new one
    // - Review updates: delete old paste, create new one  
    // - Phrase sync: delete old phrases paste, create new one

    // Delete a paste
    async function deletePastebinPaste(pasteKey) {
        if (!PASTEBIN_CONFIG.API_USER_KEY) {
            throw new Error('User key required for deleting pastes');
        }

        const data = {
            api_option: 'delete',
            api_user_key: PASTEBIN_CONFIG.API_USER_KEY,
            api_paste_key: pasteKey
        };

        const result = await pastebinRequest(data);
        return result === 'Paste deleted successfully';
    }

    // Get paste content
    async function getPastebinPaste(pasteKey) {
        const data = {
            api_option: 'show_paste',
            api_paste_key: pasteKey
        };

        // Add user key if available (required for private pastes)
        if (PASTEBIN_CONFIG.API_USER_KEY) {
            data.api_user_key = PASTEBIN_CONFIG.API_USER_KEY;
        }

        const content = await pastebinRequest(data);
        return content;
    }

    // List user's pastes
    async function listUserPastes() {
        if (!PASTEBIN_CONFIG.API_USER_KEY) {
            throw new Error('User key required for listing pastes');
        }

        const data = {
            api_option: 'list',
            api_user_key: PASTEBIN_CONFIG.API_USER_KEY,
            api_results_limit: 100
        };

        const result = await pastebinRequest(data);

        // Parse XML result
        const parser = new DOMParser();
        const xmlDoc = parser.parseFromString(result, 'text/xml');
        const pastes = xmlDoc.getElementsByTagName('paste');

        console.log('Raw XML result:', result);
        console.log('XML parsing result:', xmlDoc);
        console.log('Found paste elements:', pastes);
        console.log('Number of paste elements:', pastes.length);

        const pasteList = [];
        console.log(`Processing ${pastes.length} pastes from Pastebin API...`);
        
        // If XML parsing didn't work properly, try manual parsing as fallback
        if (pastes.length === 0 || pastes.length === 1) {
            console.log('XML parsing may have failed, trying manual parsing...');
            
            // Manual parsing using regex
            const pasteMatches = result.match(/<paste>([\s\S]*?)<\/paste>/g);
            if (pasteMatches) {
                console.log(`Manual parsing found ${pasteMatches.length} pastes`);
                
                for (let i = 0; i < pasteMatches.length; i++) {
                    const pasteXml = pasteMatches[i];
                    console.log(`Manual parsing paste ${i + 1}:`, pasteXml);
                    
                    const titleMatch = pasteXml.match(/<paste_title>([^<]+)<\/paste_title>/);
                    const keyMatch = pasteXml.match(/<paste_key>([^<]+)<\/paste_key>/);
                    const dateMatch = pasteXml.match(/<paste_date>([^<]+)<\/paste_date>/);
                    
                    if (titleMatch && keyMatch && dateMatch) {
                        const title = titleMatch[1];
                        const key = keyMatch[1];
                        const date = dateMatch[1];
                        
                        console.log(`  Manual extracted - Title: "${title}", Key: "${key}", Date: "${date}"`);
                        
                        // Include both Amazon Review Template pastes and review pastes
                        if (title.startsWith('Amazon Product:') && title.includes(' — REVIEW — ')) {
                            // This is a review paste (has the new Amazon Product prefix and review indicator)
                            console.log(`  -> Categorizing as REVIEW (has Amazon Product prefix and review indicator)`);
                            pasteList.push({
                                key: key,
                                title: title.replace('Amazon Product: ', ''),
                                date: parseInt(date) * 1000, // Convert to milliseconds
                                type: 'review'
                            });
                        } else if (title.startsWith('Amazon Review Template:') && title.includes(' — REVIEW — ')) {
                            // This is an old review paste (has old prefix and review indicator) - for backward compatibility
                            console.log(`  -> Categorizing as REVIEW (has old Amazon Review Template prefix and review indicator)`);
                            pasteList.push({
                                key: key,
                                title: title.replace('Amazon Review Template: ', ''),
                                date: parseInt(date) * 1000, // Convert to milliseconds
                                type: 'review'
                            });
                        } else if (title.startsWith('Amazon Review Template:')) {
                            // This is a template paste (has prefix but no review indicator)
                            console.log(`  -> Categorizing as TEMPLATE (has prefix but no review indicator)`);
                            pasteList.push({
                                key: key,
                                title: title.replace('Amazon Review Template: ', ''),
                                date: parseInt(date) * 1000, // Convert to milliseconds
                                type: 'template'
                            });
                        } else if (title.includes(' — REVIEW — ')) {
                            // This is a review paste (no prefix but has review indicator)
                            console.log(`  -> Categorizing as REVIEW (no prefix but has review indicator)`);
                            pasteList.push({
                                key: key,
                                title: title,
                                date: parseInt(date) * 1000, // Convert to milliseconds
                                type: 'review'
                            });
                        } else {
                            console.log(`  -> Skipping (doesn't match any criteria)`);
                        }
                    }
                }
            }
        } else {
            // Use normal XML parsing
            for (let i = 0; i < pastes.length; i++) {
                const paste = pastes[i];
                console.log(`Processing paste element ${i}:`, paste);
                
                const titleElement = paste.getElementsByTagName('paste_title')[0];
                const keyElement = paste.getElementsByTagName('paste_key')[0];
                const dateElement = paste.getElementsByTagName('paste_date')[0];
                
                const title = titleElement?.textContent || '';
                const key = keyElement?.textContent || '';
                const date = dateElement?.textContent || '';

                console.log(`  Title element:`, titleElement);
                console.log(`  Key element:`, keyElement);
                console.log(`  Date element:`, dateElement);
                console.log(`  Extracted values - Title: "${title}", Key: "${key}", Date: "${date}"`);

                console.log(`Processing paste ${i + 1}: "${title}"`);

                // Include both Amazon Review Template pastes and review pastes
                if (title.startsWith('Amazon Product:') && title.includes(' — REVIEW — ')) {
                    // This is a review paste (has the new Amazon Product prefix and review indicator)
                    console.log(`  -> Categorizing as REVIEW (has Amazon Product prefix and review indicator)`);
                    pasteList.push({
                        key: key,
                        title: title.replace('Amazon Product: ', ''),
                        date: parseInt(date) * 1000, // Convert to milliseconds
                        type: 'review'
                    });
                } else if (title.startsWith('Amazon Review Template:') && title.includes(' — REVIEW — ')) {
                    // This is an old review paste (has old prefix and review indicator) - for backward compatibility
                    console.log(`  -> Categorizing as REVIEW (has old Amazon Review Template prefix and review indicator)`);
                    pasteList.push({
                        key: key,
                        title: title.replace('Amazon Review Template: ', ''),
                        date: parseInt(date) * 1000, // Convert to milliseconds
                        type: 'review'
                    });
                } else if (title.startsWith('Amazon Review Template:')) {
                    // This is a template paste (has prefix but no review indicator)
                    console.log(`  -> Categorizing as TEMPLATE (has prefix but no review indicator)`);
                    pasteList.push({
                        key: key,
                        title: title.replace('Amazon Review Template: ', ''),
                        date: parseInt(date) * 1000, // Convert to milliseconds
                        type: 'template'
                    });
                } else if (title.includes(' — REVIEW — ')) {
                    // This is a review paste (no prefix but has review indicator)
                    console.log(`  -> Categorizing as REVIEW (no prefix but has review indicator)`);
                    pasteList.push({
                        key: key,
                        title: title,
                        date: parseInt(date) * 1000, // Convert to milliseconds
                        type: 'review'
                    });
                } else {
                    console.log(`  -> Skipping (doesn't match any criteria)`);
                }
            }
        }

        console.log(`Final paste list has ${pasteList.length} items:`, pasteList);

        return pasteList;
    }

    // Test API connection
    async function testPastebinConnection() {
        try {
            if (!isPastebinConfigured()) {
                return { success: false, message: 'API not configured' };
            }

            console.log('Testing Pastebin connection with dev key:', PASTEBIN_CONFIG.API_DEV_KEY);
            console.log('User key available:', !!PASTEBIN_CONFIG.API_USER_KEY);

            // Try a simple test first - just check if we can get a response
            const testData = {
                api_option: 'paste',
                api_paste_code: 'Test connection',
                api_paste_name: 'Test',
                api_paste_format: 'text',
                api_paste_private: '0',
                api_paste_expire_date: 'N'
            };

            // Add user key if available
            if (PASTEBIN_CONFIG.API_USER_KEY) {
                testData.api_user_key = PASTEBIN_CONFIG.API_USER_KEY;
            }

            console.log('Sending test request with data:', testData);

            // Try to create a test paste
            const testKey = await createPastebinPaste('Test Connection', 'This is a test paste to verify API connection.');

            console.log('Test paste created successfully with key:', testKey);

            // Try to delete the test paste
            if (PASTEBIN_CONFIG.API_USER_KEY) {
                await deletePastebinPaste(testKey);
                console.log('Test paste deleted successfully');
            }

            return { success: true, message: 'Connection successful' };
        } catch (error) {
            console.error('Test connection failed:', error);

            // Provide specific error messages
            if (error.message.includes('Network error')) {
                return {
                    success: false,
                    message: 'Network error. Please check your internet connection and try again.'
                };
            } else if (error.message.includes('Bad API request')) {
                return {
                    success: false,
                    message: `API Error: ${error.message}. Please check your API keys.`
                };
            } else if (error.message.includes('Unexpected response')) {
                return {
                    success: false,
                    message: 'Unexpected response from Pastebin API. Please check your API keys.'
                };
            }

            return { success: false, message: error.message };
        }
    }

    // Load configuration on script start
    loadPastebinConfig();

    // --- Unicode Style Maps ---
    // a-z and A-Z
    const unicodeMaps = {
        bold: {
            A:'𝗔',B:'𝗕',C:'𝗖',D:'𝗗',E:'𝗘',F:'𝗙',G:'𝗚',H:'𝗛',I:'𝗜',J:'𝗝',K:'𝗞',L:'𝗟',M:'𝗠',N:'𝗡',O:'𝗢',P:'𝗣',Q:'𝗤',R:'𝗥',S:'𝗦',T:'𝗧',U:'𝗨',V:'𝗩',W:'𝗪',X:'𝗫',Y:'𝗬',Z:'𝗭',
            a:'𝗮',b:'𝗯',c:'𝗰',d:'𝗱',e:'𝗲',f:'𝗳',g:'𝗴',h:'𝗵',i:'𝗶',j:'𝗷',k:'𝗸',l:'𝗹',m:'𝗺',n:'𝗻',o:'𝗼',p:'𝗽',q:'𝗾',r:'𝗿',s:'𝘀',t:'𝘁',u:'𝘂',v:'𝘃',w:'𝘄',x:'𝘅',y:'𝘆',z:'𝘇'
        },
        boldserif: {
            A:'𝐀',B:'𝐁',C:'𝐂',D:'𝐃',E:'𝐄',F:'𝐅',G:'𝐆',H:'𝐇',I:'𝐈',J:'𝐉',K:'𝐊',L:'𝐋',M:'𝐌',N:'𝐍',O:'𝐎',P:'𝐏',Q:'𝐐',R:'𝐑',S:'𝐒',T:'𝐓',U:'𝐔',V:'𝐕',W:'𝐖',X:'𝐗',Y:'𝐘',Z:'𝐙',
            a:'𝐚',b:'𝐛',c:'𝐜',d:'𝐝',e:'𝐞',f:'𝐟',g:'𝐠',h:'𝐡',i:'𝐢',j:'𝐣',k:'𝐤',l:'𝐥',m:'𝐦',n:'𝐧',o:'𝐨',p:'𝐩',q:'𝐪',r:'𝐫',s:'𝐬',t:'𝐭',u:'𝐮',v:'𝐯',w:'𝐰',x:'𝐱',y:'𝐲',z:'𝐳'
        },
        italic: {
            A:'𝘐',B:'𝘉',C:'𝘊',D:'𝘋',E:'𝘌',F:'𝘍',G:'𝘎',H:'𝘏',I:'𝘐',J:'𝘑',K:'𝘒',L:'𝘓',M:'𝘔',N:'𝘕',O:'𝘖',P:'𝘗',Q:'𝘘',R:'𝘙',S:'𝘚',T:'𝘛',U:'𝘜',V:'𝘝',W:'𝘞',X:'𝘟',Y:'𝘠',Z:'𝘡',
            a:'𝘢',b:'𝘣',c:'𝘤',d:'𝘥',e:'𝘦',f:'𝘧',g:'𝘨',h:'𝘩',i:'𝘪',j:'𝘫',k:'𝘬',l:'𝘭',m:'𝘮',n:'𝘯',o:'𝘰',p:'𝘱',q:'𝘲',r:'𝘳',s:'𝘴',t:'𝘵',u:'𝘶',v:'𝘷',w:'𝘸',x:'𝘹',y:'𝘺',z:'𝘻'
        },
        bolditalic: {
            A:'𝘼',B:'𝘽',C:'𝘾',D:'𝘿',E:'𝙀',F:'𝙁',G:'𝙂',H:'𝙃',I:'𝙄',J:'𝙅',K:'𝙆',L:'𝙇',M:'𝙈',N:'𝙉',O:'𝙊',P:'𝙋',Q:'𝙌',R:'𝙍',S:'𝙎',T:'𝙏',U:'𝙐',V:'𝙑',W:'𝙒',X:'𝙓',Y:'𝙔',Z:'𝙕',
            a:'𝙖',b:'𝙗',c:'𝙘',d:'𝙙',e:'𝙚',f:'𝙛',g:'𝙜',h:'𝙝',i:'𝙞',j:'𝙟',k:'𝙠',l:'𝙡',m:'𝙢',n:'𝙣',o:'𝙤',p:'𝙥',q:'𝙦',r:'𝙧',s:'𝙨',t:'𝙩',u:'𝙪',v:'𝙫',w:'𝙬',x:'𝙭',y:'𝙮',z:'𝙯'
        },
        serif: {
            A:'𝐴',B:'𝐵',C:'𝐶',D:'𝐷',E:'𝐸',F:'𝐹',G:'𝐺',H:'𝐻',I:'𝐼',J:'𝐽',K:'𝐾',L:'𝐿',M:'𝑀',N:'𝑁',O:'𝑂',P:'𝑃',Q:'𝑄',R:'𝑅',S:'𝑆',T:'𝑇',U:'𝑈',V:'𝑉',W:'𝑊',X:'𝑋',Y:'𝑌',Z:'𝑍',
            a:'𝑎',b:'𝑏',c:'𝑐',d:'𝑑',e:'𝑒',f:'𝑓',g:'𝑔',h:'ℎ',i:'𝑖',j:'𝑗',k:'𝑘',l:'𝑙',m:'𝑚',n:'𝑛',o:'𝑜',p:'𝑝',q:'𝑞',r:'𝑟',s:'𝑠',t:'𝑡',u:'𝑢',v:'𝑣',w:'𝑤',x:'𝑥',y:'𝑦',z:'𝑧'
        },
        serifitalic: {
            A:'𝐴',B:'𝐵',C:'𝐶',D:'𝐷',E:'𝐸',F:'𝐹',G:'𝐺',H:'𝐻',I:'𝐼',J:'𝐽',K:'𝐾',L:'𝐿',M:'𝑀',N:'𝑁',O:'𝑂',P:'𝑃',Q:'𝑄',R:'𝑅',S:'𝑆',T:'𝑇',U:'𝑈',V:'𝑉',W:'𝑊',X:'𝑋',Y:'𝑌',Z:'𝑍',
            a:'𝑎',b:'𝑏',c:'𝑐',d:'𝑑',e:'𝑒',f:'𝑓',g:'𝑔',h:'ℎ',i:'𝑖',j:'𝑗',k:'𝑘',l:'𝑙',m:'𝑚',n:'𝑛',o:'𝑜',p:'𝑝',q:'𝑞',r:'𝑟',s:'𝑠',t:'𝑡',u:'𝑢',v:'𝑣',w:'𝑤',x:'𝑥',y:'𝑦',z:'𝑧'
        },
        serifbolditalic: {
            A:'𝑨',B:'𝑩',C:'𝑪',D:'𝑫',E:'𝑬',F:'𝑭',G:'𝑮',H:'𝑯',I:'𝑰',J:'𝑱',K:'𝑲',L:'𝑳',M:'𝑴',N:'𝑵',O:'𝑶',P:'𝑷',Q:'𝑸',R:'𝑹',S:'𝑺',T:'𝑻',U:'𝑼',V:'𝑽',W:'𝑾',X:'𝑿',Y:'𝒀',Z:'𝒁',
            a:'𝒂',b:'𝒃',c:'𝒄',d:'𝒅',e:'𝒆',f:'𝒇',g:'𝒈',h:'𝒉',i:'𝒊',j:'𝒋',k:'𝒌',l:'𝒍',m:'𝒎',n:'𝒏',o:'𝒐',p:'𝒑',q:'𝒒',r:'𝒓',s:'𝒔',t:'𝒕',u:'𝒖',v:'𝒗',w:'𝒘',x:'𝒙',y:'𝒚',z:'𝒛'
        },
        cursive: {
            A:'𝓐',B:'𝓑',C:'𝓒',D:'𝓓',E:'𝓔',F:'𝓕',G:'𝓖',H:'𝓗',I:'𝓘',J:'𝓙',K:'𝓚',L:'𝓛',M:'𝓜',N:'𝓝',O:'𝓞',P:'𝓟',Q:'𝓠',R:'𝓡',S:'𝓢',T:'𝓣',U:'𝓤',V:'𝓥',W:'𝓦',X:'𝓧',Y:'𝓨',Z:'𝓩',
            a:'𝒶',b:'𝒷',c:'𝒸',d:'𝒹',e:'𝑒',f:'𝒻',g:'𝑔',h:'𝒽',i:'𝒾',j:'𝒿',k:'𝓀',l:'𝓁',m:'𝓂',n:'𝓃',o:'𝑜',p:'𝓅',q:'𝓆',r:'𝓇',s:'𝓈',t:'𝓉',u:'𝓊',v:'𝓋',w:'𝓌',x:'𝓍',y:'𝓎',z:'𝓏'
        },
        cursivebold: {
            A:'𝓐',B:'𝓑',C:'𝓒',D:'𝓓',E:'𝓔',F:'𝓕',G:'𝓖',H:'𝓗',I:'𝓘',J:'𝓙',K:'𝓚',L:'𝓛',M:'𝓜',N:'𝓝',O:'𝓞',P:'𝓟',Q:'𝓠',R:'𝓡',S:'𝓢',T:'𝓣',U:'𝓤',V:'𝓥',W:'𝓦',X:'𝓧',Y:'𝓨',Z:'𝓩',
            a:'𝓪',b:'𝓫',c:'𝓬',d:'𝓭',e:'𝓮',f:'𝓯',g:'𝓰',h:'𝓱',i:'𝓲',j:'𝓳',k:'𝓴',l:'𝓵',m:'𝓶',n:'𝓷',o:'𝓸',p:'𝓹',q:'𝓺',r:'𝓻',s:'𝓼',t:'𝓽',u:'𝓾',v:'𝓿',w:'𝔀',x:'𝔁',y:'𝔂',z:'𝔃'
        },
        superscript: {
            A:'ᴬ',B:'ᴮ',C:'ᶜ',D:'ᴰ',E:'ᴱ',F:'ᶠ',G:'ᴳ',H:'ᴴ',I:'ᴵ',J:'ᴶ',K:'ᴷ',L:'ᴸ',M:'ᴹ',N:'ᴺ',O:'ᴼ',P:'ᴾ',R:'ᴿ',S:'ˢ',T:'ᵀ',U:'ᵁ',V:'ⱽ',W:'ᵂ',X:'ˣ',Y:'ʸ',Z:'ᶻ',
            a:'ᵃ',b:'ᵇ',c:'ᶜ',d:'ᵈ',e:'ᵉ',f:'ᶠ',g:'ᵍ',h:'ʰ',i:'ᶦ',j:'ʲ',k:'ᵏ',l:'ˡ',m:'ᵐ',n:'ⁿ',o:'ᵒ',p:'ᵖ',r:'ʳ',s:'ˢ',t:'ᵗ',u:'ᵘ',v:'ᵛ',w:'ʷ',x:'ˣ',y:'ʸ',z:'ᶻ'
        },
        underline: {
            A:'A͟',B:'B͟',C:'C͟',D:'D͟',E:'E͟',F:'F͟',G:'G͟',H:'H͟',I:'I͟',J:'J͟',K:'K͟',L:'L͟',M:'M͟',N:'N͟',O:'O͟',P:'P͟',Q:'Q͟',R:'R͟',S:'S͟',T:'T͟',U:'U͟',V:'V͟',W:'W͟',X:'X͟',Y:'Y͟',Z:'Z͟',
            a:'a͟',b:'b͟',c:'c͟',d:'d͟',e:'e͟',f:'f͟',g:'g͟',h:'h͟',i:'i͟',j:'j͟',k:'k͟',l:'l͟',m:'m͟',n:'n͟',o:'o͟',p:'p͟',q:'q͟',r:'r͟',s:'s͟',t:'t͟',u:'u͟',v:'v͟',w:'w͟',x:'x͟',y:'y͟',z:'z͟'
        },
        monospace: {
            A:'𝙰',B:'𝙱',C:'𝙲',D:'𝙳',E:'𝙴',F:'𝙵',G:'𝙶',H:'𝙷',I:'𝙸',J:'𝙹',K:'𝙺',L:'𝙻',M:'𝙼',N:'𝙽',O:'𝙾',P:'𝙿',Q:'𝚀',R:'𝚁',S:'𝚂',T:'𝚃',U:'𝚄',V:'𝚅',W:'𝚆',X:'𝚇',Y:'𝚈',Z:'𝚉',
            a:'𝚊',b:'𝚋',c:'𝚌',d:'𝚍',e:'𝚎',f:'𝚏',g:'𝚐',h:'𝚑',i:'𝚒',j:'𝚓',k:'𝚔',l:'𝚕',m:'𝚖',n:'𝚗',o:'𝚘',p:'𝚙',q:'𝚚',r:'𝚛',s:'𝚜',t:'𝚝',u:'𝚞',v:'𝚟',w:'𝚠',x:'𝚡',y:'𝚢',z:'𝚣'
        },
        wide: {
            A:'A',B:'B',C:'C',D:'D',E:'E',F:'F',G:'G',H:'H',I:'I',J:'J',K:'K',L:'L',M:'M',N:'N',O:'O',P:'P',Q:'Q',R:'R',S:'S',T:'T',U:'U',V:'V',W:'W',X:'X',Y:'Y',Z:'Z',
            a:'a',b:'b',c:'c',d:'d',e:'e',f:'f',g:'g',h:'h',i:'i',j:'j',k:'k',l:'l',m:'m',n:'n',o:'o',p:'p',q:'q',r:'r',s:'s',t:'t',u:'u',v:'v',w:'w',x:'x',y:'y',z:'z'
        },
        strikethrough: {
            A:'A̶',B:'B̶',C:'C̶',D:'D̶',E:'E̶',F:'F̶',G:'G̶',H:'H̶',I:'I̶',J:'J̶',K:'K̶',L:'L̶',M:'M̶',N:'N̶',O:'O̶',P:'P̶',Q:'Q̶',R:'R̶',S:'S̶',T:'T̶',U:'U̶',V:'V̶',W:'W̶',X:'X̶',Y:'Y̶',Z:'Z̶',
            a:'a̶',b:'b̶',c:'c̶',d:'d̶',e:'e̶',f:'f̶',g:'g̶',h:'h̶',i:'i̶',j:'j̶',k:'k̶',l:'l̶',m:'m̶',n:'n̶',o:'o̶',p:'p̶',q:'q̶',r:'r̶',s:'s̶',t:'t̶',u:'u̶',v:'v̶',w:'w̶',x:'x̶',y:'y̶',z:'z̶'
        }
    };

    // --- Style Combination Logic ---
    const styleCombinationMap = [
        { styles: ['superscript'], key: 'superscript' },
        { styles: ['underline'], key: 'underline' },
        { styles: ['monospace'], key: 'monospace' },
        { styles: ['wide'], key: 'wide' },
        { styles: ['strikethrough'], key: 'strikethrough' },
        { styles: ['cursive', 'bold'], key: 'cursivebold' },
        { styles: ['cursive'], key: 'cursive' },
        { styles: ['serif', 'bold', 'italic'], key: 'serifbolditalic' },
        { styles: ['serif', 'bold'], key: 'boldserif' },
        { styles: ['serif', 'italic'], key: 'serifitalic' },
        { styles: ['serif'], key: 'serif' },
        { styles: ['bold', 'italic'], key: 'bolditalic' },
        { styles: ['bold'], key: 'bold' },
        { styles: ['italic'], key: 'italic' }
    ];

    function stylize(text, styles) {
        if (styles.size === 0) return text;
        for (const combo of styleCombinationMap) {
            if (combo.styles.every(s => styles.has(s)) && combo.styles.length === styles.size) {
                const map = unicodeMaps[combo.key];
                if (!map) return text;
                return [...text].map(ch => map[ch] || ch).join('');
            }
        }
        return text;
    }

    function detectAppliedStyles(text) {
        const detectedStyles = new Set();
        for (let i = 0; i < text.length; i++) {
            const char = text[i];
            const two_chars = text.substring(i, i + 2);
            let styleFound = false;

            for (const [styleName, styleMap] of Object.entries(unicodeMaps)) {
                for (const [ascii, unicode] of Object.entries(styleMap)) {
                    let match = false;
                    if (unicode.length === 1 && char === unicode) {
                        match = true;
                    } else if (unicode.length > 1 && two_chars === unicode) {
                        match = true;
                    }

                    if (match) {
                        if (unicode.length > 1) i++;

                        if (styleName === 'bold') detectedStyles.add('bold');
                        else if (styleName === 'italic') detectedStyles.add('italic');
                        else if (styleName === 'serif') detectedStyles.add('serif');
                        else if (styleName === 'cursive') detectedStyles.add('cursive');
                        else if (styleName === 'superscript') detectedStyles.add('superscript');
                        else if (styleName === 'underline') detectedStyles.add('underline');
                        else if (styleName === 'monospace') detectedStyles.add('monospace');
                        else if (styleName === 'wide') detectedStyles.add('wide');
                        else if (styleName === 'strikethrough') detectedStyles.add('strikethrough');
                        else if (styleName === 'boldserif') {
                            detectedStyles.add('bold');
                            detectedStyles.add('serif');
                        } else if (styleName === 'bolditalic') {
                            detectedStyles.add('bold');
                            detectedStyles.add('italic');
                        } else if (styleName === 'serifitalic') {
                            detectedStyles.add('serif');
                            detectedStyles.add('italic');
                        } else if (styleName === 'serifbolditalic') {
                            detectedStyles.add('serif');
                            detectedStyles.add('bold');
                            detectedStyles.add('italic');
                        } else if (styleName === 'cursivebold') {
                            detectedStyles.add('cursive');
                            detectedStyles.add('bold');
                        }
                        styleFound = true;
                        break;
                    }
                }
                if(styleFound) break;
            }
        }
        return detectedStyles;
    }

    function convertToPlainText(text) {
        let plainText = text;
        for (const [mapName, map] of Object.entries(unicodeMaps)) {
            for (const [ascii, uni] of Object.entries(map)) {
                plainText = plainText.replace(new RegExp(uni.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), ascii);
            }
        }
        return plainText;
    }

    // --- Toolbar UI ---
    function createToolbar(textarea) {
        const toolbar = document.createElement('div');
        toolbar.className = 'unicode-toolbar';
        toolbar.style.display = 'flex';
        toolbar.style.gap = '8px';
        toolbar.style.marginBottom = '6px';
        toolbar.style.alignItems = 'center';

        // --- TEMPLATE FEATURE ---
        // Enhanced template storage helpers with cloud sync support
        function getTemplates() {
            try {
                return JSON.parse(localStorage.getItem('amazon_review_templates') || '[]');
            } catch (e) { return []; }
        }
        function saveTemplates(templates) {
            localStorage.setItem('amazon_review_templates', JSON.stringify(templates));
        }

        // --- PHRASE STORAGE FUNCTIONS ---
        function getPhrases() {
            try {
                return JSON.parse(localStorage.getItem('amazon_review_phrases') || '[]');
            } catch (e) { return []; }
        }
        
        function savePhrases(phrases) {
            localStorage.setItem('amazon_review_phrases', JSON.stringify(phrases));
        }
        
        async function upsertPhrase(name, text) {
            let phrases = getPhrases();
            const idx = phrases.findIndex(p => p.name === name);
            const now = Date.now();
            
            if (idx !== -1) {
                // Update existing phrase
                phrases[idx].text = text;
                phrases[idx].lastModified = now;
                phrases[idx].syncStatus = 'pending';
            } else {
                // Create new phrase
                const newPhrase = {
                    name: name,
                    text: text,
                    lastModified: now,
                    syncStatus: 'none'
                };
                phrases.push(newPhrase);
            }
            
            savePhrases(phrases);
            
            // Sync to cloud if configured
            if (isPastebinConfigured()) {
                try {
                    await syncPhrasesToCloud();
                } catch (error) {
                    console.error('Failed to sync phrases to cloud:', error);
                }
            }
            
            return phrases[idx !== -1 ? idx : phrases.length - 1];
        }
        
        function getPhraseByName(name) {
            return getPhrases().find(p => p.name === name);
        }
        
        async function removePhrase(name) {
            let phrases = getPhrases();
            phrases = phrases.filter(p => p.name !== name);
            savePhrases(phrases);
            
            // Sync to cloud if configured
            if (isPastebinConfigured()) {
                try {
                    await syncPhrasesToCloud();
                } catch (error) {
                    console.error('Failed to sync phrases to cloud:', error);
                }
            }
        }

        // Enhanced template structure with cloud sync support
        async function upsertTemplate(name, text, height) {
            let templates = getTemplates();
            const idx = templates.findIndex(t => t.name === name);
            const now = Date.now();

            if (idx !== -1) {
                // Update existing template
                templates[idx].text = text;
                templates[idx].height = height;
                templates[idx].lastModified = now;
                templates[idx].syncStatus = 'pending';

                // Update cloud paste if it exists (using delete + recreate since Pastebin doesn't support updates)
                if (templates[idx].pasteCode && isPastebinConfigured()) {
                    try {
                        // Delete old paste and create new one
                        await deletePastebinPaste(templates[idx].pasteCode);
                        const newPasteCode = await createPastebinPaste(name, JSON.stringify({
                            name: name,
                            text: text,
                            height: height,
                            lastModified: now
                        }));
                        templates[idx].pasteCode = newPasteCode;
                        templates[idx].syncStatus = 'synced';
                        templates[idx].lastSynced = now;
                    } catch (error) {
                        console.error('Failed to update cloud template:', error);
                        templates[idx].syncStatus = 'failed';
                    }
                }
            } else {
                // Create new template
                const newTemplate = {
                    name: name,
                    text: text,
                    height: height,
                    lastModified: now,
                    syncStatus: 'none',
                    pasteCode: null,
                    lastSynced: null
                };

                // Create cloud paste if configured
                if (isPastebinConfigured()) {
                    try {
                        const pasteCode = await createPastebinPaste(name, JSON.stringify(newTemplate));
                        newTemplate.pasteCode = pasteCode;
                        newTemplate.syncStatus = 'synced';
                        newTemplate.lastSynced = now;
                    } catch (error) {
                        console.error('Failed to create cloud template:', error);
                        newTemplate.syncStatus = 'failed';
                    }
                }

                templates.push(newTemplate);
            }

            saveTemplates(templates);
            return templates[idx !== -1 ? idx : templates.length - 1];
        }

        function getTemplateByName(name) {
            return getTemplates().find(t => t.name === name);
        }

        async function removeTemplate(name) {
            let templates = getTemplates();
            const template = templates.find(t => t.name === name);

            if (template && template.pasteCode && isPastebinConfigured()) {
                try {
                    await deletePastebinPaste(template.pasteCode);
                } catch (error) {
                    console.error('Failed to delete cloud template:', error);
                }
            }

            templates = templates.filter(t => t.name !== name);
            saveTemplates(templates);
        }

        // --- PHRASE CLOUD SYNC FUNCTIONS ---
        async function syncPhrasesToCloud() {
            if (!isPastebinConfigured()) {
                throw new Error('Pastebin API not configured');
            }

            const phrases = getPhrases();
            if (phrases.length === 0) {
                console.log('No phrases to sync');
                return { success: true, message: 'No phrases to sync' };
            }

            // Create aggregated phrases data
            const phrasesData = {
                version: '1.0',
                lastUpdated: new Date().toISOString(),
                phrases: phrases.map(p => ({
                    name: p.name,
                    text: p.text,
                    lastModified: p.lastModified || Date.now()
                }))
            };

            try {
                // Check if phrases paste already exists
                const existingPhrasesPaste = await findPhrasesPaste();
                
                if (existingPhrasesPaste) {
                    // Pastebin API doesn't support updates, so we must delete and recreate
                    console.log('Deleting existing phrases paste and recreating...');
                    try {
                        await deletePastebinPaste(existingPhrasesPaste.key);
                        console.log('Successfully deleted old phrases paste');
                    } catch (deleteError) {
                        console.warn('Failed to delete old phrases paste, continuing with recreation:', deleteError);
                    }
                }

                // Create new paste (either first time or after deletion)
                const pasteCode = await createPastebinPaste('Amazon Review Phrases', JSON.stringify(phrasesData, null, 2));
                console.log('Created new phrases paste with key:', pasteCode);

                // Mark all phrases as synced
                phrases.forEach(phrase => phrase.syncStatus = 'synced');
                savePhrases(phrases);

                return { success: true, message: 'Phrases synced successfully' };
            } catch (error) {
                console.error('Failed to sync phrases:', error);
                // Mark phrases as failed
                phrases.forEach(phrase => {
                    if (phrase.syncStatus === 'pending') {
                        phrase.syncStatus = 'failed';
                    }
                });
                savePhrases(phrases);
                throw error;
            }
        }

        async function findPhrasesPaste() {
            try {
                const pastes = await listUserPastes();
                return pastes.find(paste => 
                    paste.type === 'template' && 
                    paste.title === 'Amazon Review Phrases'
                );
            } catch (error) {
                console.error('Error finding phrases paste:', error);
                return null;
            }
        }

        async function syncPhrasesFromCloud() {
            if (!isPastebinConfigured() || !PASTEBIN_CONFIG.API_USER_KEY) {
                throw new Error('Pastebin API not configured or user key missing');
            }

            try {
                const phrasesPaste = await findPhrasesPaste();
                if (!phrasesPaste) {
                    return { imported: 0, updated: 0, message: 'No phrases found in cloud' };
                }

                const content = await getPastebinPaste(phrasesPaste.key);
                const phrasesData = JSON.parse(content);

                if (!phrasesData.phrases || !Array.isArray(phrasesData.phrases)) {
                    throw new Error('Invalid phrases data format');
                }

                const localPhrases = getPhrases();
                let importedCount = 0;
                let updatedCount = 0;

                for (const cloudPhrase of phrasesData.phrases) {
                    const existingIndex = localPhrases.findIndex(p => p.name === cloudPhrase.name);

                    if (existingIndex === -1) {
                        // Import new phrase
                        localPhrases.push({
                            ...cloudPhrase,
                            syncStatus: 'synced'
                        });
                        importedCount++;
                    } else {
                        // Update existing phrase if cloud version is newer
                        const localPhrase = localPhrases[existingIndex];
                        if (cloudPhrase.lastModified > localPhrase.lastModified) {
                            localPhrases[existingIndex] = {
                                ...cloudPhrase,
                                syncStatus: 'synced'
                            };
                            updatedCount++;
                        }
                    }
                }

                savePhrases(localPhrases);
                return { imported: importedCount, updated: updatedCount };
            } catch (error) {
                console.error('Failed to import phrases from cloud:', error);
                throw error;
            }
        }

        // Cloud sync functions
        async function syncTemplatesToCloud() {
            if (!isPastebinConfigured()) {
                throw new Error('Pastebin API not configured');
            }

            const templates = getTemplates();
            let syncedCount = 0;
            let failedCount = 0;

            console.log(`Starting sync for ${templates.length} templates...`);

            for (const template of templates) {
                try {
                    console.log(`Processing template: ${template.name} (status: ${template.syncStatus})`);

                    if (template.syncStatus === 'none' || template.syncStatus === 'failed') {
                        // Create new paste
                        console.log(`Creating new paste for: ${template.name}`);
                        const pasteCode = await createPastebinPaste(template.name, JSON.stringify(template));
                        console.log(`Received paste code: ${pasteCode}`);

                        // Validate the paste code
                        if (!pasteCode || pasteCode.length < 8) {
                            throw new Error(`Invalid paste code received: ${pasteCode}`);
                        }

                        template.pasteCode = pasteCode;
                        template.syncStatus = 'synced';
                        template.lastSynced = Date.now();
                        syncedCount++;
                        console.log(`Successfully created paste for: ${template.name}`);

                        // Verify the paste was actually created
                        const verified = await verifyPasteCreation(pasteCode);
                        if (!verified) {
                            console.warn(`Warning: Paste ${pasteCode} may not have been created successfully`);
                            template.syncStatus = 'failed';
                            syncedCount--;
                            failedCount++;
                        }
                    } else if (template.syncStatus === 'pending') {
                        // Update existing paste (using delete + recreate since Pastebin doesn't support updates)
                        console.log(`Updating existing paste for: ${template.name} (code: ${template.pasteCode})`);
                        try {
                            // Delete old paste and create new one
                            await deletePastebinPaste(template.pasteCode);
                            const newPasteCode = await createPastebinPaste(template.name, JSON.stringify(template));
                            template.pasteCode = newPasteCode;
                            template.syncStatus = 'synced';
                            template.lastSynced = Date.now();
                            syncedCount++;
                            console.log(`Successfully updated paste for: ${template.name}`);
                        } catch (error) {
                            console.error(`Failed to update paste for: ${template.name}:`, error);
                            throw new Error('Update operation failed');
                        }
                    } else if (template.syncStatus === 'synced') {
                        console.log(`Template ${template.name} already synced, skipping`);
                    }
                } catch (error) {
                    console.error(`Failed to sync template "${template.name}":`, error);
                    template.syncStatus = 'failed';
                    failedCount++;
                }
            }

            console.log(`Sync completed. Synced: ${syncedCount}, Failed: ${failedCount}`);
            saveTemplates(templates);
            return { synced: syncedCount, failed: failedCount };
        }

        // Verify that pastes were actually created
        async function verifyPasteCreation(pasteCode) {
            try {
                // Try to fetch the paste content to verify it exists
                const response = await fetch(`https://pastebin.com/raw/${pasteCode}`);
                if (response.ok) {
                    const content = await response.text();
                    console.log(`Paste ${pasteCode} verified - content length: ${content.length}`);
                    return true;
                } else {
                    console.error(`Paste ${pasteCode} verification failed - status: ${response.status}`);
                    return false;
                }
            } catch (error) {
                console.error(`Paste ${pasteCode} verification error:`, error);
                return false;
            }
        }

        async function syncTemplatesFromCloud() {
            if (!isPastebinConfigured()) {
                throw new Error('Pastebin API not configured');
            }

            if (!PASTEBIN_CONFIG.API_USER_KEY) {
                throw new Error('User key required for importing from cloud');
            }

            const cloudTemplates = await listUserPastes();
            const localTemplates = getTemplates();
            let importedCount = 0;
            let updatedCount = 0;

            console.log(`Found ${cloudTemplates.length} total pastes in cloud:`);
            cloudTemplates.forEach(paste => {
                console.log(`- ${paste.type}: "${paste.title}"`);
            });

            for (const cloudTemplate of cloudTemplates) {
                // Only process template pastes (not review pastes)
                if (cloudTemplate.type !== 'template') {
                    console.log(`Skipping non-template paste: "${cloudTemplate.title}" (type: ${cloudTemplate.type})`);
                    continue;
                }

                console.log(`Processing template: "${cloudTemplate.title}"`);

                try {
                    const content = await getPastebinPaste(cloudTemplate.key);
                    const templateData = JSON.parse(content);

                    console.log(`Template data:`, templateData);

                    const existingIndex = localTemplates.findIndex(t => t.name === templateData.name);

                    if (existingIndex === -1) {
                        // Import new template
                        const newTemplate = {
                            ...templateData,
                            pasteCode: cloudTemplate.key,
                            syncStatus: 'synced',
                            lastSynced: Date.now()
                        };
                        localTemplates.push(newTemplate);
                        importedCount++;
                        console.log(`Imported new template: "${templateData.name}"`);
                    } else {
                        // Update existing template if cloud version is newer
                        const localTemplate = localTemplates[existingIndex];
                        if (templateData.lastModified > localTemplate.lastModified) {
                            localTemplates[existingIndex] = {
                                ...templateData,
                                pasteCode: cloudTemplate.key,
                                syncStatus: 'synced',
                                lastSynced: Date.now()
                            };
                            updatedCount++;
                            console.log(`Updated existing template: "${templateData.name}"`);
                        } else {
                            console.log(`Template "${templateData.name}" already up to date`);
                        }
                    }
                } catch (error) {
                    console.error(`Failed to import template "${cloudTemplate.title}":`, error);
                }
            }

            console.log(`Import completed. Imported: ${importedCount}, Updated: ${updatedCount}`);
            saveTemplates(localTemplates);
            return { imported: importedCount, updated: updatedCount };
        }

        // Create Pastebin button and popover
        function createPastebinButton() {
            const pastebinBtn = document.createElement('button');
            pastebinBtn.type = 'button';
            pastebinBtn.innerHTML = '☁️';
            pastebinBtn.title = 'Pastebin Cloud Sync';
            pastebinBtn.style.fontSize = '1.1em';
            pastebinBtn.style.padding = '2px 8px';
            pastebinBtn.style.borderRadius = '4px';
            pastebinBtn.style.border = '1px solid #bbb';
            pastebinBtn.style.background = '#f8f8f8';
            pastebinBtn.style.cursor = 'pointer';
            pastebinBtn.style.transition = 'background 0.15s ease, color 0.15s ease, transform 0.1s ease';
            pastebinBtn.style.outline = 'none';
            pastebinBtn.style.userSelect = 'none';
            pastebinBtn.style.position = 'relative';

            // Create popover
            const popover = document.createElement('div');
            popover.className = 'pastebin-popover';

            const menuItems = [
                { icon: '💾', text: 'Save Review', action: 'save-review', requiresConfig: true, requiresUserKey: true },
                { icon: '📥', text: 'Fetch Review', action: 'fetch-review', requiresConfig: true, requiresUserKey: true },
                { icon: '📋', text: 'Create Manual Paste', action: 'create-manual', requiresConfig: false },
                { icon: '📥', text: 'Import from Paste URL', action: 'import-manual', requiresConfig: false },
                { icon: '📚', text: 'Import Templates', action: 'import-templates', requiresConfig: true, requiresUserKey: true },
                { icon: '🔗', text: 'My Pastebin', action: 'my-pastebin', requiresConfig: true, requiresUserKey: true },
                { icon: '⚙️', text: 'API Settings', action: 'settings', requiresConfig: false },
                { icon: '📊', text: 'Sync Status', action: 'status', requiresConfig: false },
                { icon: '🗑️', text: 'Clear Cloud Data', action: 'clear-cloud', requiresConfig: true }
            ];

            menuItems.forEach(item => {
                const menuItem = document.createElement('div');
                menuItem.className = 'pastebin-popover-item';
                if (item.requiresConfig && !isPastebinConfigured()) {
                    menuItem.classList.add('disabled');
                }
                if (item.requiresUserKey && !PASTEBIN_CONFIG.API_USER_KEY) {
                    menuItem.classList.add('disabled');
                }

                menuItem.innerHTML = `
                    <span>${item.icon}</span>
                    <span>${item.text}</span>
                `;

                menuItem.addEventListener('click', () => {
                    if (!menuItem.classList.contains('disabled')) {
                        handlePastebinAction(item.action);
                    }
                    popover.classList.remove('show');
                });

                popover.appendChild(menuItem);
            });

            pastebinBtn.appendChild(popover);

            // Toggle popover
            pastebinBtn.addEventListener('click', (e) => {
                e.preventDefault();
                e.stopPropagation();
                popover.classList.toggle('show');
            });

            // Close popover when clicking outside
            document.addEventListener('click', (e) => {
                if (!pastebinBtn.contains(e.target)) {
                    popover.classList.remove('show');
                }
            });

            // Close popover on ESC key
            document.addEventListener('keydown', (e) => {
                if (e.key === 'Escape') {
                    popover.classList.remove('show');
                }
            });

            return pastebinBtn;
        }

        // Handle Pastebin popover actions
        async function handlePastebinAction(action) {
            switch (action) {
                case 'save-review':
                    await handleSaveReview();
                    break;
                case 'fetch-review':
                    await handleFetchReview();
                    break;
                case 'sync-to-cloud':
                    await handleSyncToCloud();
                    break;
                case 'import-from-cloud':
                    await handleImportFromCloud();
                    break;
                case 'create-manual':
                    await handleCreateManualPaste();
                    break;
                case 'import-manual':
                    await handleImportManualPaste();
                    break;
                case 'import-templates':
                    await handleImportTemplates();
                    break;
                case 'my-pastebin':
                    handleMyPastebin();
                    break;
                case 'settings':
                    showPastebinSettings();
                    break;
                case 'status':
                    showSyncStatus();
                    break;
                case 'clear-cloud':
                    await handleClearCloudData();
                    break;
                default:
                    console.warn('Unknown Pastebin action:', action);
            }
        }

        // Handle sync to cloud
        async function handleSyncToCloud() {
            try {
                console.log('Starting sync to cloud...');
                const result = await syncTemplatesToCloud();

                let message = `Sync completed!\nSynced: ${result.synced}\nFailed: ${result.failed}`;

                if (result.failed > 0) {
                    message += '\n\nSome templates failed to sync. Check the browser console for details.';
                }

                if (result.synced === 0 && result.failed === 0) {
                    message = 'No templates to sync. All templates are already up to date.';
                }

                alert(message);
                refreshTemplateOptions();
            } catch (error) {
                console.error('Sync failed:', error);
                alert(`Sync failed: ${error.message}\n\nTry using the manual paste method instead.`);
            }
        }

        // Handle import from cloud
        async function handleImportFromCloud() {
            try {
                const result = await syncTemplatesFromCloud();
                alert(`Import completed!\nImported: ${result.imported}\nUpdated: ${result.updated}`);
                refreshTemplateOptions();
            } catch (error) {
                alert(`Import failed: ${error.message}`);
            }
        }

        // Handle clear cloud data
        async function handleClearCloudData() {
            if (!confirm('This will delete all templates from Pastebin. Continue?')) {
                return;
            }

            const templates = getTemplates();
            let deletedCount = 0;

            for (const template of templates) {
                if (template.pasteCode) {
                    try {
                        await deletePastebinPaste(template.pasteCode);
                        template.pasteCode = null;
                        template.syncStatus = 'none';
                        template.lastSynced = null;
                        deletedCount++;
                    } catch (error) {
                        console.error(`Failed to delete template "${template.name}":`, error);
                    }
                }
            }

            saveTemplates(templates);
            alert(`Cleared ${deletedCount} templates from cloud`);
            refreshTemplateOptions();
        }

        // Handle manual paste creation
        async function handleCreateManualPaste() {
            const templates = getTemplates();
            if (templates.length === 0) {
                alert('No templates to export. Please save some templates first.');
                return;
            }

            // Create a combined export of all templates
            const exportData = {
                version: '1.0',
                exportDate: new Date().toISOString(),
                templates: templates.map(t => ({
                    name: t.name,
                    text: t.text,
                    height: t.height,
                    lastModified: t.lastModified || Date.now()
                }))
            };

            const exportText = JSON.stringify(exportData, null, 2);

            // Create a temporary textarea to copy the data
            const textarea = document.createElement('textarea');
            textarea.value = exportText;
            textarea.style.position = 'fixed';
            textarea.style.left = '-9999px';
            textarea.style.top = '-9999px';
            document.body.appendChild(textarea);
            textarea.select();
            document.execCommand('copy');
            document.body.removeChild(textarea);

            // Open Pastebin in a new tab
            const pastebinUrl = 'https://pastebin.com/';
            window.open(pastebinUrl, '_blank');

            alert(`Template data copied to clipboard!\n\nInstructions:\n1. Paste the data into Pastebin\n2. Set title to "Amazon Review Templates"\n3. Set format to "JSON"\n4. Set expiration to "Never"\n5. Click "Create New Paste"\n6. Copy the paste URL for importing later`);
        }

        // Handle manual paste import
        async function handleImportManualPaste() {
            const pasteUrl = prompt('Enter Pastebin URL (e.g., https://pastebin.com/abc123):', '');
            if (!pasteUrl) return;

            // Extract paste key from URL
            const pasteKeyMatch = pasteUrl.match(/pastebin\.com\/([a-zA-Z0-9]+)/);
            if (!pasteKeyMatch) {
                alert('Invalid Pastebin URL. Please enter a valid URL like https://pastebin.com/abc123');
                return;
            }

            const pasteKey = pasteKeyMatch[1];

            try {
                // Try to fetch the paste content
                const response = await fetch(`https://pastebin.com/raw/${pasteKey}`);
                if (!response.ok) {
                    throw new Error('Failed to fetch paste content');
                }

                const content = await response.text();
                const importData = JSON.parse(content);

                if (!importData.templates || !Array.isArray(importData.templates)) {
                    throw new Error('Invalid template data format');
                }

                const localTemplates = getTemplates();
                let importedCount = 0;
                let updatedCount = 0;

                for (const templateData of importData.templates) {
                    const existingIndex = localTemplates.findIndex(t => t.name === templateData.name);

                    if (existingIndex === -1) {
                        // Import new template
                        const newTemplate = {
                            ...templateData,
                            syncStatus: 'none',
                            pasteCode: null,
                            lastSynced: null
                        };
                        localTemplates.push(newTemplate);
                        importedCount++;
                    } else {
                        // Update existing template if import version is newer
                        const localTemplate = localTemplates[existingIndex];
                        if (templateData.lastModified > localTemplate.lastModified) {
                            localTemplates[existingIndex] = {
                                ...templateData,
                                syncStatus: 'none',
                                pasteCode: null,
                                lastSynced: null
                            };
                            updatedCount++;
                        }
                    }
                }

                saveTemplates(localTemplates);
                refreshTemplateOptions();
                alert(`Import completed!\nImported: ${importedCount}\nUpdated: ${updatedCount}`);

            } catch (error) {
                console.error('Import failed:', error);
                alert(`Import failed: ${error.message}\n\nMake sure the paste contains valid template data in JSON format.`);
            }
        }

        // Show sync status
        function showSyncStatus() {
            const templates = getTemplates();
            let statusText = 'Template Sync Status:\n\n';

            if (templates.length === 0) {
                statusText += 'No templates found.';
            } else {
                templates.forEach(template => {
                    const statusIcon = {
                        'synced': '🟢',
                        'pending': '🟡',
                        'failed': '🔴',
                        'none': '⚪'
                    }[template.syncStatus] || '⚪';

                    statusText += `${statusIcon} ${template.name}\n`;
                });
            }

            alert(statusText);
        }

        // Handle save review action
        async function handleSaveReview() {
            const textarea = document.getElementById('reviewText');
            if (!textarea) {
                alert('Review textarea not found');
                return;
            }

            if (!textarea.value.trim()) {
                alert('Please enter some review text before saving to cloud');
                return;
            }

            try {
                const result = await saveReviewToCloud(textarea);
                alert(`${result.message}\n\nPaste URL: ${result.pasteUrl}`);
            } catch (error) {
                console.error('Save review failed:', error);
                alert(`Failed to save review: ${error.message}`);
            }
        }

        // Handle fetch review action
        async function handleFetchReview() {
            const textarea = document.getElementById('reviewText');
            if (!textarea) {
                alert('Review textarea not found');
                return;
            }

            // Check if textarea has content and warn user
            if (textarea.value.trim()) {
                if (!confirm('This will replace your current review text. Continue?')) {
                    return;
                }
            }

            try {
                const result = await fetchReviewFromCloud(textarea);
                alert(`${result.message}\n\nPaste URL: ${result.pasteUrl}`);
            } catch (error) {
                console.error('Fetch review failed:', error);
                alert(`Failed to fetch review: ${error.message}`);
            }
        }

        // Handle import templates action (same as previous "Import from Cloud")
        async function handleImportTemplates() {
            try {
                await handleImportFromCloud();
            } catch (error) {
                console.error('Import templates failed:', error);
                alert(`Failed to import templates: ${error.message}`);
            }
        }

        // Handle My Pastebin action
        function handleMyPastebin() {
            // Extract username from the user key or use a default approach
            // Since we can't directly get the username from the API, we'll use a generic approach
            const pastebinUrl = 'https://pastebin.com/u/';
            window.open(pastebinUrl, '_blank');
            
            // Show a helpful message
            alert('Opening Pastebin user page.\n\nNote: You may need to log in to see your pastes. The URL format is typically:\nhttps://pastebin.com/u/[username]\n\nYou can find your username in your Pastebin account settings.');
        }

        // Show Pastebin settings modal
        function showPastebinSettings() {
            // Create modal if it doesn't exist
            let modal = document.querySelector('.pastebin-modal');
            if (!modal) {
                modal = document.createElement('div');
                modal.className = 'pastebin-modal';
                modal.innerHTML = `
                    <div class="pastebin-modal-content">
                        <div class="pastebin-modal-header">
                            <h3 class="pastebin-modal-title">Pastebin API Settings</h3>
                            <button class="pastebin-modal-close">&times;</button>
                        </div>
                        <form id="pastebin-settings-form">
                            <div class="pastebin-form-group">
                                <label class="pastebin-form-label" for="api-dev-key">API Dev Key *</label>
                                <input type="text" id="api-dev-key" class="pastebin-form-input" placeholder="Enter your Pastebin API Dev Key" required>
                                <div class="pastebin-form-help">
                                    Get your API Dev Key from <a href="https://pastebin.com/doc_api" target="_blank">Pastebin API documentation</a>
                                </div>
                            </div>
                            <div class="pastebin-form-group">
                                <label class="pastebin-form-label" for="api-username">Pastebin Username</label>
                                <input type="text" id="api-username" class="pastebin-form-input" placeholder="Enter your Pastebin username">
                                <div class="pastebin-form-help">
                                    Your Pastebin account username (required to post under your account)
                                </div>
                            </div>
                            <div class="pastebin-form-group">
                                <label class="pastebin-form-label" for="api-password">Pastebin Password</label>
                                <input type="password" id="api-password" class="pastebin-form-input" placeholder="Enter your Pastebin password">
                                <div class="pastebin-form-help">
                                    Your Pastebin account password (will be used to generate User Key)
                                </div>
                            </div>
                            <div class="pastebin-form-group">
                                <label class="pastebin-form-label" for="api-user-key">API User Key (Auto-generated)</label>
                                <input type="text" id="api-user-key" class="pastebin-form-input" placeholder="Will be generated automatically" readonly>
                                <div class="pastebin-form-help">
                                    This will be automatically generated from your username/password
                                </div>
                            </div>
                            <div class="pastebin-form-actions">
                                <button type="button" class="pastebin-btn" id="generate-user-key">Generate User Key</button>
                                <button type="button" class="pastebin-btn" id="test-connection">Test Connection</button>
                                <button type="button" class="pastebin-btn" id="cancel-settings">Cancel</button>
                                <button type="submit" class="pastebin-btn pastebin-btn-primary">Save Settings</button>
                            </div>
                        </form>
                    </div>
                `;
                document.body.appendChild(modal);

                // Add event listeners
                const closeBtn = modal.querySelector('.pastebin-modal-close');
                const cancelBtn = modal.querySelector('#cancel-settings');
                const testBtn = modal.querySelector('#test-connection');
                const generateBtn = modal.querySelector('#generate-user-key');
                const form = modal.querySelector('#pastebin-settings-form');

                closeBtn.addEventListener('click', () => modal.classList.remove('show'));
                cancelBtn.addEventListener('click', () => modal.classList.remove('show'));

                generateBtn.addEventListener('click', async () => {
                    const devKey = modal.querySelector('#api-dev-key').value;
                    const username = modal.querySelector('#api-username').value;
                    const password = modal.querySelector('#api-password').value;

                    if (!devKey) {
                        alert('Please enter an API Dev Key first.');
                        return;
                    }

                    if (!username || !password) {
                        alert('Please enter both username and password to generate User Key.');
                        return;
                    }

                    generateBtn.disabled = true;
                    generateBtn.innerHTML = '<span class="pastebin-loading"></span> Generating...';

                    try {
                        // Temporarily set dev key for generation
                        const originalDevKey = PASTEBIN_CONFIG.API_DEV_KEY;
                        PASTEBIN_CONFIG.API_DEV_KEY = devKey;

                        const userKey = await generatePastebinUserKey(username, password);

                        // Update the user key field
                        modal.querySelector('#api-user-key').value = userKey;

                        // Automatically save the configuration
                        PASTEBIN_CONFIG.API_DEV_KEY = devKey;
                        PASTEBIN_CONFIG.API_USER_NAME = username;
                        PASTEBIN_CONFIG.API_USER_PASSWORD = password;
                        PASTEBIN_CONFIG.API_USER_KEY = userKey;

                        savePastebinConfig();

                        alert('User Key generated and saved successfully!');

                    } catch (error) {
                        alert(`Failed to generate User Key: ${error.message}`);
                    } finally {
                        generateBtn.disabled = false;
                        generateBtn.textContent = 'Generate User Key';
                    }
                });

                testBtn.addEventListener('click', async () => {
                    const devKey = modal.querySelector('#api-dev-key').value;
                    const userKey = modal.querySelector('#api-user-key').value;

                    if (!devKey) {
                        alert('Please enter an API Dev Key first.');
                        return;
                    }

                    testBtn.disabled = true;
                    testBtn.innerHTML = '<span class="pastebin-loading"></span> Testing...';

                    try {
                        // Temporarily set keys for testing
                        const originalDevKey = PASTEBIN_CONFIG.API_DEV_KEY;
                        const originalUserKey = PASTEBIN_CONFIG.API_USER_KEY;
                        PASTEBIN_CONFIG.API_DEV_KEY = devKey;
                        PASTEBIN_CONFIG.API_USER_KEY = userKey;

                        const result = await testPastebinConnection();

                        if (result.success) {
                            alert('Connection successful!');
                        } else {
                            alert(`Connection failed: ${result.message}`);
                        }

                        // Restore original keys
                        PASTEBIN_CONFIG.API_DEV_KEY = originalDevKey;
                        PASTEBIN_CONFIG.API_USER_KEY = originalUserKey;
                    } catch (error) {
                        alert(`Test failed: ${error.message}`);
                    } finally {
                        testBtn.disabled = false;
                        testBtn.textContent = 'Test Connection';
                    }
                });

                form.addEventListener('submit', (e) => {
                    e.preventDefault();
                    const devKey = modal.querySelector('#api-dev-key').value;
                    const username = modal.querySelector('#api-username').value;
                    const password = modal.querySelector('#api-password').value;
                    const userKey = modal.querySelector('#api-user-key').value;

                    PASTEBIN_CONFIG.API_DEV_KEY = devKey || null;
                    PASTEBIN_CONFIG.API_USER_NAME = username || null;
                    PASTEBIN_CONFIG.API_USER_PASSWORD = password || null;
                    PASTEBIN_CONFIG.API_USER_KEY = userKey || null;

                    savePastebinConfig();
                    modal.classList.remove('show');
                    alert('Settings saved!');
                });

                // Close modal when clicking outside
                modal.addEventListener('click', (e) => {
                    if (e.target === modal) {
                        modal.classList.remove('show');
                    }
                });
            }

            // Populate current values
            const devKeyInput = modal.querySelector('#api-dev-key');
            const usernameInput = modal.querySelector('#api-username');
            const passwordInput = modal.querySelector('#api-password');
            const userKeyInput = modal.querySelector('#api-user-key');
            devKeyInput.value = PASTEBIN_CONFIG.API_DEV_KEY || '';
            usernameInput.value = PASTEBIN_CONFIG.API_USER_NAME || '';
            passwordInput.value = PASTEBIN_CONFIG.API_USER_PASSWORD || '';
            userKeyInput.value = PASTEBIN_CONFIG.API_USER_KEY || '';

            // Show modal
            modal.classList.add('show');
        }

        // Template and Phrase UI Container
        const templateContainer = document.createElement('div');
        templateContainer.style.marginLeft = '';
        templateContainer.style.display = 'flex';
        templateContainer.style.alignItems = 'center';
        templateContainer.style.gap = '6px';

        // Phrase dropdown
        const phraseSelect = document.createElement('select');
        phraseSelect.style.maxWidth = '150px';
        phraseSelect.style.fontSize = '1em';
        phraseSelect.style.padding = '2px 6px';
        phraseSelect.style.borderRadius = '4px';
        phraseSelect.style.border = '1px solid #bbb';
        phraseSelect.style.background = '#fff';
        phraseSelect.style.color = '#222';
        phraseSelect.title = 'Insert a saved phrase';
        
        function refreshPhraseOptions() {
            const phrases = getPhrases();
            phraseSelect.innerHTML = '';
            const defaultOpt = document.createElement('option');
            defaultOpt.value = '';
            defaultOpt.textContent = 'Insert phrase...';
            phraseSelect.appendChild(defaultOpt);
            phrases.forEach(p => {
                const opt = document.createElement('option');
                opt.value = p.name;
                
                // Add sync status indicator
                const statusIcon = {
                    'synced': '🟢',
                    'pending': '🟡',
                    'failed': '🔴',
                    'none': '⚪'
                }[p.syncStatus] || '⚪';
                
                opt.textContent = `${statusIcon} ${p.name}`;
                phraseSelect.appendChild(opt);
            });
        }
        refreshPhraseOptions();

        // Insert phrase on select
        phraseSelect.addEventListener('change', function() {
            const name = phraseSelect.value;
            if (!name) return;
            const phrase = getPhraseByName(name);
            if (!phrase) return;
            
            // Insert phrase at cursor position
            const cursorPos = textarea.selectionStart;
            const textBefore = textarea.value.substring(0, cursorPos);
            const textAfter = textarea.value.substring(textarea.selectionEnd);
            
            textarea.value = textBefore + phrase.text + textAfter;
            
            // Move cursor to end of inserted phrase
            const newCursorPos = cursorPos + phrase.text.length;
            textarea.setSelectionRange(newCursorPos, newCursorPos);
            
            // Trigger input event for autosave
            textarea.dispatchEvent(new Event('input', { bubbles: true }));
            phraseSelect.value = '';
            textarea.focus();
        });

        const templateSelect = document.createElement('select');
        templateSelect.style.maxWidth = '180px';
        templateSelect.style.fontSize = '1em';
        templateSelect.style.padding = '2px 6px';
        templateSelect.style.borderRadius = '4px';
        templateSelect.style.border = '1px solid #bbb';
        templateSelect.style.background = '#fff'; // Ensure default background
        templateSelect.style.color = '#222'; // Ensure default text color
        templateSelect.title = 'Insert a saved template';
        function refreshTemplateOptions() {
            const templates = getTemplates();
            templateSelect.innerHTML = '';
            const defaultOpt = document.createElement('option');
            defaultOpt.value = '';
            defaultOpt.textContent = 'Insert template...';
            templateSelect.appendChild(defaultOpt);
            templates.forEach(t => {
                const opt = document.createElement('option');
                opt.value = t.name;

                // Add sync status indicator
                const statusIcon = {
                    'synced': '🟢',
                    'pending': '🟡',
                    'failed': '🔴',
                    'none': '⚪'
                }[t.syncStatus] || '⚪';

                opt.textContent = `${statusIcon} ${t.name}`;
                templateSelect.appendChild(opt);
            });
        }
        refreshTemplateOptions();

        // Insert template on select
        templateSelect.addEventListener('change', function() {
            const name = templateSelect.value;
            if (!name) return;
            const template = getTemplateByName(name);
            if (!template) return;
            // Confirm if textbox is not empty and would overwrite
            if (textarea.value && textarea.value !== template.text) {
                if (!confirm('Replace current text with template "' + name + '"?')) {
                    templateSelect.value = '';
                    return;
                }
            }
            textarea.value = template.text;
            if (template.height) textarea.style.height = template.height;
            // Trigger input event for autosave
            textarea.dispatchEvent(new Event('input', { bubbles: true }));
            templateSelect.value = '';
        });

        // Save as template button
        const saveTemplateBtn = document.createElement('button');
        saveTemplateBtn.type = 'button';
        saveTemplateBtn.textContent = 'Save as...';
        saveTemplateBtn.style.fontSize = '1em';
        saveTemplateBtn.style.padding = '2px 8px';
        saveTemplateBtn.style.borderRadius = '4px';
        saveTemplateBtn.style.border = '1px solid #bbb';
        saveTemplateBtn.style.background = '#f8f8f8';
        saveTemplateBtn.style.color = '#222'; // Normal text color
        saveTemplateBtn.style.opacity = '1'; // Not faded
        saveTemplateBtn.style.cursor = 'pointer';
        saveTemplateBtn.style.transition = 'background 0.15s, color 0.15s, transform 0.1s';
        saveTemplateBtn.style.userSelect = 'none';
        saveTemplateBtn.title = 'Save current text as a reusable template';
        saveTemplateBtn.addEventListener('mouseenter', () => {
            saveTemplateBtn.style.background = '#e8e8e8';
        });
        saveTemplateBtn.addEventListener('mouseleave', () => {
            saveTemplateBtn.style.background = '#f8f8f8';
        });
        saveTemplateBtn.addEventListener('click', async function() {
            // Smart detection: selected text = phrase, no selection = template
            const hasSelection = textarea.selectionStart !== textarea.selectionEnd;
            const selectedText = hasSelection ? textarea.value.substring(textarea.selectionStart, textarea.selectionEnd) : '';
            
            if (hasSelection && selectedText.trim()) {
                // Save as phrase
                let name = prompt('Phrase name:', '');
                if (!name) return;
                name = name.trim();
                if (!name) return;
                
                // Check if phrase exists
                const exists = !!getPhraseByName(name);
                if (exists && !confirm('A phrase with this name exists. Overwrite?')) return;

                // Show loading state
                const originalText = saveTemplateBtn.textContent;
                saveTemplateBtn.textContent = 'Saving phrase...';
                saveTemplateBtn.disabled = true;

                try {
                    await upsertPhrase(name, selectedText);
                    refreshPhraseOptions();
                    alert('Phrase saved!');
                } catch (error) {
                    alert(`Failed to save phrase: ${error.message}`);
                } finally {
                    saveTemplateBtn.textContent = originalText;
                    saveTemplateBtn.disabled = false;
                }
            } else {
                // Save as template
                let name = prompt('Template name:', '');
                if (!name) return;
                name = name.trim();
                if (!name) return;
                
                // Check if template exists
                const exists = !!getTemplateByName(name);
                if (exists && !confirm('A template with this name exists. Overwrite?')) return;

                // Show loading state
                const originalText = saveTemplateBtn.textContent;
                saveTemplateBtn.textContent = 'Saving template...';
                saveTemplateBtn.disabled = true;

                try {
                    await upsertTemplate(name, textarea.value, textarea.style.height);
                    refreshTemplateOptions();
                    alert('Template saved!');
                } catch (error) {
                    alert(`Failed to save template: ${error.message}`);
                } finally {
                    saveTemplateBtn.textContent = originalText;
                    saveTemplateBtn.disabled = false;
                }
            }
        });

        // Remove template button (optional, for user convenience)
        const deleteTemplateBtn = document.createElement('button');
        deleteTemplateBtn.type = 'button';
        deleteTemplateBtn.textContent = 'Manage';
        deleteTemplateBtn.style.fontSize = '1em';
        deleteTemplateBtn.style.padding = '2px 8px';
        deleteTemplateBtn.style.borderRadius = '4px';
        deleteTemplateBtn.style.border = '1px solid #bbb';
        deleteTemplateBtn.style.background = '#f8f8f8';
        deleteTemplateBtn.style.color = '#222';
        deleteTemplateBtn.style.cursor = 'pointer';
        deleteTemplateBtn.style.transition = 'background 0.15s, color 0.15s, transform 0.1s';
        deleteTemplateBtn.style.userSelect = 'none';
        deleteTemplateBtn.title = 'Manage templates (view, delete, etc.)';
        deleteTemplateBtn.addEventListener('mouseenter', () => {
            deleteTemplateBtn.style.background = '#e8e8e8';
        });
        deleteTemplateBtn.addEventListener('mouseleave', () => {
            deleteTemplateBtn.style.background = '#f8f8f8';
        });
        deleteTemplateBtn.addEventListener('click', function() {
            showTemplateManager();
        });

        // Unified Template and Phrase Manager
        function showTemplateManager() {
            const templates = getTemplates();
            const phrases = getPhrases();

            // Create modal if it doesn't exist
            let modal = document.querySelector('.template-manager-modal');
            if (!modal) {
                modal = document.createElement('div');
                modal.className = 'template-manager-modal';
                modal.innerHTML = `
                    <div class="template-manager-content">
                        <div class="template-manager-header">
                            <h3 class="template-manager-title">Templates & Phrases Manager</h3>
                            <button class="template-manager-close">&times;</button>
                        </div>
                        <div class="template-manager-tabs">
                            <button class="tab-btn active" data-tab="templates">📝 Templates</button>
                            <button class="tab-btn" data-tab="phrases">💬 Phrases</button>
                        </div>
                        <div class="template-manager-body">
                            <div class="tab-content" id="templates-tab">
                                <div class="template-list" id="template-list">
                                    <!-- Templates will be populated here -->
                                </div>
                            </div>
                            <div class="tab-content" id="phrases-tab" style="display: none;">
                                <div class="template-list" id="phrase-list">
                                    <!-- Phrases will be populated here -->
                                </div>
                            </div>
                        </div>
                    </div>
                `;
                document.body.appendChild(modal);

                // Add tab switching functionality
                const tabBtns = modal.querySelectorAll('.tab-btn');
                const tabContents = modal.querySelectorAll('.tab-content');
                
                tabBtns.forEach(btn => {
                    btn.addEventListener('click', () => {
                        const tabName = btn.dataset.tab;
                        
                        // Update active tab button
                        tabBtns.forEach(b => b.classList.remove('active'));
                        btn.classList.add('active');
                        
                        // Show corresponding tab content
                        tabContents.forEach(content => {
                            if (content.id === `${tabName}-tab`) {
                                content.style.display = 'block';
                            } else {
                                content.style.display = 'none';
                            }
                        });
                    });
                });

                // Add event listeners
                const closeBtn = modal.querySelector('.template-manager-close');
                closeBtn.addEventListener('click', () => modal.classList.remove('show'));

                // Close modal when clicking outside
                modal.addEventListener('click', (e) => {
                    if (e.target === modal) {
                        modal.classList.remove('show');
                    }
                });
            }

            // Populate template list
            const templateList = modal.querySelector('#template-list');
            templateList.innerHTML = '';

            if (templates.length === 0) {
                templateList.innerHTML = '<div class="no-templates">No templates found. Create some templates to see them here.</div>';
            } else {
                templates.forEach(template => {
                    const templateItem = document.createElement('div');
                    templateItem.className = 'template-item';

                    const statusIcon = {
                        'synced': '🟢',
                        'pending': '🟡',
                        'failed': '🔴',
                        'none': '⚪'
                    }[template.syncStatus] || '⚪';

                    templateItem.innerHTML = `
                        <div class="template-info">
                            <div class="template-name">${statusIcon} ${template.name}</div>
                            <div class="template-preview">${template.text.substring(0, 100)}${template.text.length > 100 ? '...' : ''}</div>
                        </div>
                        <div class="template-actions">
                            <button class="template-btn template-insert-btn" title="Insert template">📝</button>
                            <button class="template-btn template-delete-btn" title="Delete template">🗑</button>
                        </div>
                    `;

                    // Add event listeners
                    const insertBtn = templateItem.querySelector('.template-insert-btn');
                    const deleteBtn = templateItem.querySelector('.template-delete-btn');

                    insertBtn.addEventListener('click', () => {
                        // Confirm if textbox is not empty and would overwrite
                        if (textarea.value && textarea.value !== template.text) {
                            if (!confirm('Replace current text with template "' + template.name + '"?')) {
                                return;
                            }
                        }
                        textarea.value = template.text;
                        if (template.height) textarea.style.height = template.height;
                        // Trigger input event for autosave
                        textarea.dispatchEvent(new Event('input', { bubbles: true }));
                        modal.classList.remove('show');
                    });

                    deleteBtn.addEventListener('click', async () => {
                        if (!confirm(`Delete template "${template.name}"?`)) return;

                        deleteBtn.disabled = true;
                        deleteBtn.textContent = '...';

                        try {
                            await removeTemplate(template.name);
                            // Remove the item from the list
                            templateItem.remove();
                            // Update the dropdown
                            refreshTemplateOptions();

                            // If no templates left, show the no templates message
                            if (templateList.children.length === 0) {
                                templateList.innerHTML = '<div class="no-templates">No templates found. Create some templates to see them here.</div>';
                            }
                        } catch (error) {
                            alert(`Failed to delete template: ${error.message}`);
                            deleteBtn.disabled = false;
                            deleteBtn.textContent = '🗑';
                        }
                    });

                    templateList.appendChild(templateItem);
                });
            }

            // Populate phrase list
            const phraseList = modal.querySelector('#phrase-list');
            phraseList.innerHTML = '';

            if (phrases.length === 0) {
                phraseList.innerHTML = '<div class="no-templates">No phrases found. Create some phrases to see them here.</div>';
            } else {
                phrases.forEach(phrase => {
                    const phraseItem = document.createElement('div');
                    phraseItem.className = 'template-item';

                    const statusIcon = {
                        'synced': '🟢',
                        'pending': '🟡',
                        'failed': '🔴',
                        'none': '⚪'
                    }[phrase.syncStatus] || '⚪';

                    phraseItem.innerHTML = `
                        <div class="template-info">
                            <div class="template-name">${statusIcon} ${phrase.name}</div>
                            <div class="template-preview">${phrase.text.substring(0, 100)}${phrase.text.length > 100 ? '...' : ''}</div>
                        </div>
                        <div class="template-actions">
                            <button class="template-btn template-insert-btn" title="Insert phrase">💬</button>
                            <button class="template-btn template-delete-btn" title="Delete phrase">🗑</button>
                        </div>
                    `;

                    // Add event listeners
                    const insertBtn = phraseItem.querySelector('.template-insert-btn');
                    const deleteBtn = phraseItem.querySelector('.template-delete-btn');

                    insertBtn.addEventListener('click', () => {
                        // Insert phrase at cursor position
                        const cursorPos = textarea.selectionStart;
                        const textBefore = textarea.value.substring(0, cursorPos);
                        const textAfter = textarea.value.substring(textarea.selectionEnd);
                        
                        textarea.value = textBefore + phrase.text + textAfter;
                        
                        // Move cursor to end of inserted phrase
                        const newCursorPos = cursorPos + phrase.text.length;
                        textarea.setSelectionRange(newCursorPos, newCursorPos);
                        
                        // Trigger input event for autosave
                        textarea.dispatchEvent(new Event('input', { bubbles: true }));
                        modal.classList.remove('show');
                        textarea.focus();
                    });

                    deleteBtn.addEventListener('click', async () => {
                        if (!confirm(`Delete phrase "${phrase.name}"?`)) return;

                        deleteBtn.disabled = true;
                        deleteBtn.textContent = '...';

                        try {
                            await removePhrase(phrase.name);
                            // Remove the item from the list
                            phraseItem.remove();
                            // Update the dropdown
                            refreshPhraseOptions();

                            // If no phrases left, show the no phrases message
                            if (phraseList.children.length === 0) {
                                phraseList.innerHTML = '<div class="no-templates">No phrases found. Create some phrases to see them here.</div>';
                            }
                        } catch (error) {
                            alert(`Failed to delete phrase: ${error.message}`);
                            deleteBtn.disabled = false;
                            deleteBtn.textContent = '🗑';
                        }
                    });

                    phraseList.appendChild(phraseItem);
                });
            }

            // Show modal
            modal.classList.add('show');
        }

        // Create Pastebin button
        const pastebinBtn = createPastebinButton();

        templateContainer.appendChild(phraseSelect);
        templateContainer.appendChild(templateSelect);
        templateContainer.appendChild(saveTemplateBtn);
        templateContainer.appendChild(deleteTemplateBtn);
        templateContainer.appendChild(pastebinBtn);
        toolbar.appendChild(templateContainer);

        // Button definitions
        const buttons = [
            { label: '<b>B</b>', style: 'bold', title: 'Bold Sans (𝗕)' },
            { label: '<i>I</i>', style: 'italic', title: 'Italic Sans (𝘪)' },
            { label: '<span style="font-family:serif">S</span>', style: 'serif', title: 'Serif (𝑠)' },
            { label: '<span style="font-family:cursive">C</span>', style: 'cursive', title: 'Cursive (𝓬)' },
            { label: '<sup>^</sup>', style: 'superscript', title: 'Superscript (ᵃ)' },
            { label: '<u>U</u>', style: 'underline', title: 'Underline (U͟)' },
            { label: '<s>S</s>', style: 'strikethrough', title: 'Strikethrough (S̶)' },
            { label: '<span style="font-family:monospace">M</span>', style: 'monospace', title: 'Monospace (𝙼)' },
            { label: '<span style="font-family:\'Arial Black\', Gadget, sans-serif">W</span>', style: 'wide', title: 'Wide (W)' },
            { label: '●', style: 'bullet', title: 'Bullet Points (➜)' },
            { label: '1.', style: 'number', title: 'Numbered List (1), 2)...)' }
        ];

        // State for toggling
        let activeStyles = new Set();
        const buttonElements = [];

        // State for bullet points and numbering
        let bulletMode = false;
        let numberMode = false;
        let bulletCount = 0;
        let numberCount = 0;
        let lastUsedNumber = 0; // Track the last used number for continuation

        // Helper function to remove specific style from text
        function removeStyleFromText(text, styleToRemove) {
            // First, detect what styles are currently applied to the text
            const currentStyles = detectAppliedStyles(text);

            // Remove the specific style we want to remove
            currentStyles.delete(styleToRemove);

            // Convert the text back to plain ASCII
            const plainText = convertToPlainText(text);

            // Reapply the remaining styles
            return stylize(plainText, currentStyles);
        }

        // Helper function to update button states based on selected text
        function updateButtonStatesFromSelection() {
            const cursorPos = textarea.selectionStart;
            const selectionEnd = textarea.selectionEnd;

            if (cursorPos !== selectionEnd) {
                // Get selected text
                const selected = textarea.value.slice(cursorPos, selectionEnd);
                const detectedStyles = detectAppliedStyles(selected);

                // Update activeStyles to match detected styles
                activeStyles.clear();
                detectedStyles.forEach(style => activeStyles.add(style));

                // Update button appearances
                buttonElements.forEach(({ element, style }) => {
                    if (style !== 'bullet' && style !== 'number') {
                        element.setAttribute('aria-pressed', activeStyles.has(style).toString());
                    }
                });
            }
        }

        // Helper function to check if current line already has a bullet
        function currentLineHasBullet() {
            const cursorPos = textarea.selectionStart;
            const textBefore = textarea.value.substring(0, cursorPos);
            const lineStart = textBefore.lastIndexOf('\n') + 1;
            const lineText = textBefore.substring(lineStart);
            return lineText.trim().startsWith('➜');
        }

        // Helper function to check if current line already has a number
        function currentLineHasNumber() {
            const cursorPos = textarea.selectionStart;
            const textBefore = textarea.value.substring(0, cursorPos);
            const lineStart = textBefore.lastIndexOf('\n') + 1;
            const lineText = textBefore.substring(lineStart);
            return /^\d+\)\s/.test(lineText.trim());
        }

        // Helper function to find the highest number in the document
        function findHighestNumberInDocument() {
            const text = textarea.value;
            const lines = text.split('\n');
            let highestNumber = 0;

            for (const line of lines) {
                const match = line.trim().match(/^(\d+)\)\s/);
                if (match) {
                    const number = parseInt(match[1], 10);
                    if (number > highestNumber) {
                        highestNumber = number;
                    }
                }
            }

            return highestNumber;
        }

        // Helper function to renumber the document when items are deleted
        function renumberDocument() {
            const text = textarea.value;
            const lines = text.split('\n');
            let newLines = [];
            let currentNumber = 1;

            for (const line of lines) {
                const trimmedLine = line.trim();
                const match = trimmedLine.match(/^(\d+)\)\s(.+)$/);

                if (match) {
                    // This is a numbered line, renumber it
                    const content = match[2];
                    newLines.push(`${currentNumber}) ${content}`);
                    currentNumber++;
                } else {
                    // This is not a numbered line, keep as is
                    newLines.push(line);
                }
            }

            // Update the textarea with renumbered content
            const newText = newLines.join('\n');
            if (newText !== text) {
                const cursorPos = textarea.selectionStart;
                const selectionEnd = textarea.selectionEnd;

                textarea.value = newText;

                // Try to maintain cursor position as much as possible
                const newCursorPos = Math.min(cursorPos, newText.length);
                const newSelectionEnd = Math.min(selectionEnd, newText.length);
                textarea.setSelectionRange(newCursorPos, newSelectionEnd);

                // Update the numbering state
                lastUsedNumber = currentNumber - 1;
                numberCount = lastUsedNumber;
            }
        }

        // Create buttons
        buttons.forEach(btn => {
            const button = document.createElement('button');
            button.innerHTML = btn.label;
            button.title = btn.title;
            button.type = 'button';
            button.style.fontSize = '1.1em';
            button.style.padding = '2px 8px';
            button.style.borderRadius = '4px';
            button.style.border = '1px solid #bbb';
            button.style.background = '#f8f8f8';
            button.style.cursor = 'pointer';
            button.style.transition = 'background 0.15s ease, color 0.15s ease, transform 0.1s ease';
            button.style.outline = 'none';
            button.style.userSelect = 'none';
            button.setAttribute('aria-pressed', 'false');

            // Store reference to button for efficient updates
            buttonElements.push({ element: button, style: btn.style });

            button.addEventListener('click', (e) => {
                e.preventDefault();
                e.stopPropagation();

                // Add immediate visual feedback
                button.style.transform = 'scale(0.95)';
                setTimeout(() => {
                    button.style.transform = '';
                }, 100);

                // Handle bullet and number modes
                if (btn.style === 'bullet') {
                    bulletMode = !bulletMode;
                    if (bulletMode) {
                        numberMode = false;
                        // Reset other modes
                        activeStyles.clear();
                        buttonElements.forEach(({ element, style }) => {
                            if (style !== 'bullet') {
                                element.setAttribute('aria-pressed', 'false');
                            }
                        });

                        // Check if current line already has a bullet
                        if (!currentLineHasBullet()) {
                            // Insert bullet at cursor position or before selected text
                            const cursorPos = textarea.selectionStart;
                            const selectionEnd = textarea.selectionEnd;
                            const textBefore = textarea.value.substring(0, cursorPos);
                            const selectedText = textarea.value.substring(cursorPos, selectionEnd);
                            const textAfter = textarea.value.substring(selectionEnd);

                            // Find the beginning of the current line
                            const lineStart = textBefore.lastIndexOf('\n') + 1;
                            const lineText = textBefore.substring(lineStart);

                            // If we're at the start of a line or the line is empty, insert bullet
                            if (lineStart === cursorPos || lineText.trim() === '') {
                                const bulletText = '➜ ';
                                textarea.value = textBefore + bulletText + selectedText + textAfter;
                                textarea.setSelectionRange(cursorPos + bulletText.length, cursorPos + bulletText.length + selectedText.length);
                            } else {
                                // Insert bullet at the beginning of the current line
                                const bulletText = '➜ ';
                                textarea.value = textBefore.substring(0, lineStart) + bulletText + textBefore.substring(lineStart) + selectedText + textAfter;
                                textarea.setSelectionRange(lineStart + bulletText.length, lineStart + bulletText.length + selectedText.length);
                            }
                        }
                        // If line already has bullet, just activate the mode without adding another
                    }
                    button.setAttribute('aria-pressed', bulletMode.toString());
                    return;
                }

                if (btn.style === 'number') {
                    numberMode = !numberMode;
                    if (numberMode) {
                        bulletMode = false;
                        // Reset other modes
                        activeStyles.clear();
                        buttonElements.forEach(({ element, style }) => {
                            if (style !== 'number') {
                                element.setAttribute('aria-pressed', 'false');
                            }
                        });

                        // Find the highest number in the document to continue from
                        const highestNumber = findHighestNumberInDocument();
                        // Always use the highest number found, regardless of previous lastUsedNumber
                        lastUsedNumber = highestNumber;
                        numberCount = lastUsedNumber;

                        // Check if current line already has a number
                        if (!currentLineHasNumber()) {
                            // Insert number at cursor position or before selected text
                            const cursorPos = textarea.selectionStart;
                            const selectionEnd = textarea.selectionEnd;
                            const textBefore = textarea.value.substring(0, cursorPos);
                            const selectedText = textarea.value.substring(cursorPos, selectionEnd);
                            const textAfter = textarea.value.substring(selectionEnd);

                            // Find the beginning of the current line
                            const lineStart = textBefore.lastIndexOf('\n') + 1;
                            const lineText = textBefore.substring(lineStart);

                            // If we're at the start of a line or the line is empty, insert number
                            if (lineStart === cursorPos || lineText.trim() === '') {
                                numberCount++;
                                lastUsedNumber = numberCount;
                                const numberText = `${numberCount}) `;
                                textarea.value = textBefore + numberText + selectedText + textAfter;
                                textarea.setSelectionRange(cursorPos + numberText.length, cursorPos + numberText.length + selectedText.length);
                            } else {
                                // Insert number at the beginning of the current line
                                numberCount++;
                                lastUsedNumber = numberCount;
                                const numberText = `${numberCount}) `;
                                textarea.value = textBefore.substring(0, lineStart) + numberText + textBefore.substring(lineStart) + selectedText + textAfter;
                                textarea.setSelectionRange(lineStart + numberText.length, lineStart + numberText.length + selectedText.length);
                            }
                        }
                        // If line already has number, just activate the mode without adding another
                    } else {
                        // Numbering mode is being turned off
                        // Clear the renumbering timeout if it exists
                        if (textarea.renumberTimeout) {
                            clearTimeout(textarea.renumberTimeout);
                        }
                    }
                    button.setAttribute('aria-pressed', numberMode.toString());
                    return;
                }

                // Toggle style for regular formatting buttons
                if (activeStyles.has(btn.style)) {
                    // Remove style from active styles
                    activeStyles.delete(btn.style);
                    button.setAttribute('aria-pressed', 'false');

                    // Remove this style from any selected text
                    const cursorPos = textarea.selectionStart;
                    const selectionEnd = textarea.selectionEnd;

                    if (cursorPos !== selectionEnd) {
                        // Remove style from selected text
                        const before = textarea.value.slice(0, cursorPos);
                        const selected = textarea.value.slice(cursorPos, selectionEnd);
                        const after = textarea.value.slice(selectionEnd);
                        const updated = removeStyleFromText(selected, btn.style);
                        textarea.value = before + updated + after;
                        textarea.setSelectionRange(cursorPos, cursorPos + updated.length);

                        // Update activeStyles to reflect what's actually applied to the text
                        const remainingStyles = detectAppliedStyles(updated);
                        activeStyles.clear();
                        remainingStyles.forEach(style => activeStyles.add(style));

                        // Update button states to match the remaining styles
                        buttonElements.forEach(({ element, style }) => {
                            if (style !== 'bullet' && style !== 'number') {
                                element.setAttribute('aria-pressed', activeStyles.has(style).toString());
                            }
                        });
                    } else {
                        // Remove style from current word
                        const text = textarea.value;
                        const beforeCursor = text.slice(0, cursorPos);
                        const afterCursor = text.slice(cursorPos);

                        const wordStart = beforeCursor.search(/\S+$/);
                        const wordEnd = afterCursor.search(/\s|$/);

                        if (wordStart !== -1) {
                            const start = cursorPos - (beforeCursor.length - wordStart);
                            const end = cursorPos + (wordEnd === -1 ? afterCursor.length : wordEnd);
                            const word = text.slice(start, end);
                            const updated = removeStyleFromText(word, btn.style);
                            textarea.value = text.slice(0, start) + updated + text.slice(end);
                            textarea.setSelectionRange(start, start + updated.length);

                            // Update activeStyles to reflect what's actually applied to the word
                            const remainingStyles = detectAppliedStyles(updated);
                            activeStyles.clear();
                            remainingStyles.forEach(style => activeStyles.add(style));

                            // Update button states to match the remaining styles
                            buttonElements.forEach(({ element, style }) => {
                                if (style !== 'bullet' && style !== 'number') {
                                    element.setAttribute('aria-pressed', activeStyles.has(style).toString());
                                }
                            });
                        }
                    }
                } else {
                    // Add style
                    // Superscript and other new styles are exclusive
                    if (btn.style === 'superscript' || btn.style === 'underline' || btn.style === 'strikethrough' || btn.style === 'monospace' || btn.style === 'wide') {
                        activeStyles.clear();
                        // Use stored references instead of querying DOM
                        buttonElements.forEach(({ element, style }) => {
                            element.setAttribute('aria-pressed', 'false');
                        });
                    }
                    activeStyles.add(btn.style);
                    button.setAttribute('aria-pressed', 'true');

                    // Apply formatting instantly to selected text or current word
                    const cursorPos = textarea.selectionStart;
                    const selectionEnd = textarea.selectionEnd;

                    if (cursorPos !== selectionEnd) {
                        // Apply to selected text
                        const before = textarea.value.slice(0, cursorPos);
                        const selected = textarea.value.slice(cursorPos, selectionEnd);
                        const after = textarea.value.slice(selectionEnd);

                        // Detect existing styles on the selected text
                        const existingStyles = detectAppliedStyles(selected);

                        // Combine existing styles with new active styles
                        const combinedStyles = new Set([...existingStyles, ...activeStyles]);

                        // Convert to plain text and reapply all styles
                        const plainText = convertToPlainText(selected);
                        const styled = stylize(plainText, combinedStyles);

                        textarea.value = before + styled + after;
                        textarea.setSelectionRange(cursorPos, cursorPos + styled.length);
                    } else {
                        // Apply to current word
                        const text = textarea.value;
                        const beforeCursor = text.slice(0, cursorPos);
                        const afterCursor = text.slice(cursorPos);

                        // Find word boundaries
                        const wordStart = beforeCursor.search(/\S+$/);
                        const wordEnd = afterCursor.search(/\s|$/);

                        if (wordStart !== -1) {
                            const start = cursorPos - (beforeCursor.length - wordStart);
                            const end = cursorPos + (wordEnd === -1 ? afterCursor.length : wordEnd);
                            const word = text.slice(start, end);

                            // Detect existing styles on the word
                            const existingStyles = detectAppliedStyles(word);

                            // Combine existing styles with new active styles
                            const combinedStyles = new Set([...existingStyles, ...activeStyles]);

                            // Convert to plain text and reapply all styles
                            const plainText = convertToPlainText(word);
                            const styled = stylize(plainText, combinedStyles);

                            textarea.value = text.slice(0, start) + styled + text.slice(end);
                            textarea.setSelectionRange(start, start + styled.length);
                        }
                    }
                }

                // Don't focus textarea - let user continue working without interruption
            });

            // Add hover effects
            button.addEventListener('mouseenter', () => {
                if (!activeStyles.has(btn.style)) {
                    button.style.background = '#e8e8e8';
                }
            });

            button.addEventListener('mouseleave', () => {
                if (!activeStyles.has(btn.style)) {
                    button.style.background = '#f8f8f8';
                }
            });

            toolbar.appendChild(button);
        });

        // Reset button
        const resetBtn = document.createElement('button');
        resetBtn.textContent = 'Clear styles';
        resetBtn.type = 'button';
        resetBtn.style.marginLeft = '6px';
        resetBtn.style.background = '#ffe0b2'; // More vibrant background
        resetBtn.style.border = '1px solid #ff9800';
        resetBtn.style.borderRadius = '4px';
        resetBtn.style.cursor = 'pointer';
        resetBtn.style.transition = 'background 0.15s ease, transform 0.1s ease';
        resetBtn.style.userSelect = 'none';
        resetBtn.style.color = '#b26a00'; // Stronger text color
        resetBtn.style.opacity = '1'; // Not faded
        resetBtn.title = 'Remove all Unicode styling from highlighted text';

        resetBtn.addEventListener('click', (e) => {
            e.preventDefault();
            e.stopPropagation();

            // Add immediate visual feedback
            resetBtn.style.transform = 'scale(0.95)';
            setTimeout(() => {
                resetBtn.style.transform = '';
            }, 100);

            const [start, end] = [textarea.selectionStart, textarea.selectionEnd];
            if (start === end) return;

            const before = textarea.value.slice(0, start);
            const selected = textarea.value.slice(start, end);
            const after = textarea.value.slice(end);

            // Remove all stylization (replace with plain ASCII)
            const plain = convertToPlainText(selected);

            textarea.value = before + plain + after;
            textarea.setSelectionRange(start, start + plain.length);
            textarea.focus();
        });

        // Add hover effects for reset button
        resetBtn.addEventListener('mouseenter', () => {
            resetBtn.style.background = '#ffe0b2';
        });

        resetBtn.addEventListener('mouseleave', () => {
            resetBtn.style.background = '#fff3e0';
        });

        toolbar.appendChild(resetBtn);

        // Reset numbering button
        const resetNumberingBtn = document.createElement('button');
        resetNumberingBtn.textContent = 'Reset Numbering';
        resetNumberingBtn.type = 'button';
        resetNumberingBtn.style.marginLeft = '6px';
        resetNumberingBtn.style.background = '#e3f2fd'; // More vibrant background
        resetNumberingBtn.style.border = '1px solid #2196f3';
        resetNumberingBtn.style.borderRadius = '4px';
        resetNumberingBtn.style.cursor = 'pointer';
        resetNumberingBtn.style.transition = 'background 0.15s ease, transform 0.1s ease';
        resetNumberingBtn.style.userSelect = 'none';
        resetNumberingBtn.style.color = '#1565c0'; // Stronger text color
        resetNumberingBtn.style.opacity = '1'; // Not faded
        resetNumberingBtn.title = 'Start a new numbered list from 1 at the current position';

        resetNumberingBtn.addEventListener('click', (e) => {
            e.preventDefault();
            e.stopPropagation();
            // Add immediate visual feedback
            resetNumberingBtn.style.transform = 'scale(0.95)';
            setTimeout(() => {
                resetNumberingBtn.style.transform = '';
            }, 100);
            // Reset the numbering counter so the next list starts at 1
            numberCount = 0;
            lastUsedNumber = 0;
        });

        // Add hover effects for reset numbering button
        resetNumberingBtn.addEventListener('mouseenter', () => {
            resetNumberingBtn.style.background = '#bbdefb';
        });
        resetNumberingBtn.addEventListener('mouseleave', () => {
            resetNumberingBtn.style.background = '#e3f2fd';
        });
        toolbar.appendChild(resetNumberingBtn);

        // Add keydown listener for bullet points and numbering
        textarea.addEventListener('keydown', (e) => {
            if (e.key === 'Enter') {
                // Handle bullet mode
                if (bulletMode) {
                    e.preventDefault();
                    const cursorPos = textarea.selectionStart;
                    const textBefore = textarea.value.substring(0, cursorPos);
                    const textAfter = textarea.value.substring(cursorPos);

                    // Find the beginning of the current line
                    const lineStart = textBefore.lastIndexOf('\n') + 1;
                    const lineText = textBefore.substring(lineStart);

                    // Check if current line is empty or only contains bullet
                    const isCurrentLineEmpty = lineText.trim() === '' || lineText.trim() === '➜';

                    if (isCurrentLineEmpty) {
                        // Delete the bullet and disable bullet mode
                        const newTextBefore = textBefore.substring(0, lineStart);
                        textarea.value = newTextBefore + textAfter;
                        textarea.setSelectionRange(lineStart, lineStart);

                        // Disable bullet mode
                        bulletMode = false;
                        buttonElements.forEach(({ element, style }) => {
                            if (style === 'bullet') {
                                element.setAttribute('aria-pressed', 'false');
                            }
                        });
                    } else {
                        // Insert new bullet on next line
                        const bulletText = '\n➜ ';
                        textarea.value = textBefore + bulletText + textAfter;
                        textarea.setSelectionRange(cursorPos + bulletText.length, cursorPos + bulletText.length);
                    }
                    return;
                }

                // Handle number mode
                if (numberMode) {
                    e.preventDefault();
                    const cursorPos = textarea.selectionStart;
                    const textBefore = textarea.value.substring(0, cursorPos);
                    const textAfter = textarea.value.substring(cursorPos);

                    // Find the beginning of the current line
                    const lineStart = textBefore.lastIndexOf('\n') + 1;
                    const lineText = textBefore.substring(lineStart);

                    // Check if current line is empty or only contains number
                    const numberPattern = /^\d+\)\s*$/;
                    const isCurrentLineEmpty = lineText.trim() === '' || numberPattern.test(lineText.trim());

                    if (isCurrentLineEmpty) {
                        // Delete the number and disable number mode
                        const newTextBefore = textBefore.substring(0, lineStart);
                        textarea.value = newTextBefore + textAfter;
                        textarea.setSelectionRange(lineStart, lineStart);

                        // Disable number mode
                        numberMode = false;
                        // Don't reset numberCount to preserve the sequence
                        buttonElements.forEach(({ element, style }) => {
                            if (style === 'number') {
                                element.setAttribute('aria-pressed', 'false');
                            }
                        });
                    } else {
                        // Insert new number on next line
                        numberCount++;
                        lastUsedNumber = numberCount;
                        const numberText = `\n${numberCount}) `;
                        textarea.value = textBefore + numberText + textAfter;
                        textarea.setSelectionRange(cursorPos + numberText.length, cursorPos + numberText.length);
                    }
                    return;
                }
            }
        });

        // Add event listeners to update button states when selection changes
        textarea.addEventListener('mouseup', updateButtonStatesFromSelection);
        textarea.addEventListener('keyup', updateButtonStatesFromSelection);
        textarea.addEventListener('input', (e) => {
            updateButtonStatesFromSelection();

            // If numbering mode is active, renumber the document when content changes
            if (numberMode) {
                // Use a debounced approach to avoid renumbering during typing
                clearTimeout(textarea.renumberTimeout);
                textarea.renumberTimeout = setTimeout(() => {
                    renumberDocument();
                }, 300); // Increased delay for better performance
            }
        });

        return toolbar;
    }

    // --- Auto-Save Review Draft Feature ---
    function getCurrentASIN() {
        // Try to get ASIN from URL (?asin=...)
        const params = new URLSearchParams(window.location.search);
        let asin = params.get('asin');
        // Fallback: extract from path or query string
        if (!asin && window.location.href.includes('/review/create-review')) {
            const asinMatch = window.location.href.match(/[?&]asin=([A-Z0-9]{10})/);
            if (asinMatch) asin = asinMatch[1];
        }
        return asin;
    }

    // Fetch product title from product page using ASIN
    async function fetchProductTitleFromASIN(asin) {
        try {
            const productUrl = `https://www.amazon.ca/dp/${asin}`;
            console.log(`Fetching product title from: ${productUrl}`);
            
            // Add timeout to the fetch request
            const controller = new AbortController();
            const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout
            
            const response = await fetch(productUrl, {
                signal: controller.signal,
                headers: {
                    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
                }
            });
            
            clearTimeout(timeoutId);
            
            if (!response.ok) {
                throw new Error(`HTTP ${response.status}: ${response.statusText}`);
            }
            
            const html = await response.text();
            
            // Try to find the product title in the HTML
            const titleSelectors = [
                '#productTitle',
                '.a-size-large.product-title-word-break',
                '.product-title-word-break',
                'h1[data-automation-id="title"]',
                '.a-size-large'
            ];
            
            for (const selector of titleSelectors) {
                const match = html.match(new RegExp(`<[^>]*id="${selector.replace('#', '')}"[^>]*>([^<]+)</[^>]*>`, 'i')) ||
                             html.match(new RegExp(`<[^>]*class="[^"]*${selector.replace('.', '')}[^"]*"[^>]*>([^<]+)</[^>]*>`, 'i'));
                
                if (match && match[1]) {
                    const title = match[1].trim();
                    if (title && title.length > 0) {
                        console.log(`Found product title using selector "${selector}": "${title}"`);
                        return title;
                    }
                }
            }
            
            console.log('No product title found in product page HTML');
            return null;
            
        } catch (error) {
            if (error.name === 'AbortError') {
                console.error('Fetching product title timed out after 10 seconds');
            } else {
                console.error('Error fetching product title:', error);
            }
            return null;
        }
    }

    // Get product title from the current page or fetch from product page
    async function getProductTitle() {
        // First try to get title from current page
        const titleElement = document.getElementById('productTitle');
        if (titleElement) {
            return titleElement.textContent.trim();
        }

        // Fallback: try to find title in other common selectors
        const selectors = [
            '.a-size-large.product-title-word-break',
            '.product-title-word-break',
            'h1[data-automation-id="title"]',
            '.a-size-large'
        ];

        for (const selector of selectors) {
            const element = document.querySelector(selector);
            if (element) {
                return element.textContent.trim();
            }
        }

        // If no title found on current page, try to fetch from product page using ASIN
        try {
            const asin = getCurrentASIN();
            if (asin) {
                console.log(`No product title found on current page, fetching from product page for ASIN: ${asin}`);
                const productTitle = await fetchProductTitleFromASIN(asin);
                if (productTitle) {
                    console.log(`Successfully fetched product title: "${productTitle}"`);
                    return productTitle;
                }
            }
        } catch (error) {
            console.error('Failed to fetch product title from product page:', error);
        }

        return 'Unknown';
    }

    // Create a review paste title with format: Amazon Product: [first 5 words] — REVIEW — [ASIN]
    function createReviewPasteTitle(productTitle, asin) {
        // Clean up the product title and limit to first 8 words for readability
        const cleanTitle = productTitle.replace(/[^\w\s]/g, '').trim();
        const words = cleanTitle.split(/\s+/).slice(0, 8).join(' ');
        return `Amazon Product: ${words} — REVIEW — ${asin}`;
    }

    // Find existing review paste for current ASIN
    async function findReviewPasteForASIN(asin) {
        if (!isPastebinConfigured() || !PASTEBIN_CONFIG.API_USER_KEY) {
            throw new Error('Pastebin API not configured or user key missing');
        }

        try {
            const pastes = await listUserPastes();
            const asinSuffix = ` — ${asin}`;

            console.log(`Looking for review paste with ASIN: ${asin}`);
            console.log(`Expected suffix: ${asinSuffix}`);
            console.log(`Found ${pastes.length} total pastes:`);
            pastes.forEach(paste => {
                console.log(`- ${paste.type}: "${paste.title}"`);
            });

            for (const paste of pastes) {
                // Only look at review pastes (not templates)
                if (paste.type === 'review' && paste.title && paste.title.endsWith(asinSuffix)) {
                    console.log(`Found matching review paste: "${paste.title}"`);
                    return paste;
                }
            }

            console.log('No matching review paste found');
            return null; // No matching paste found
        } catch (error) {
            console.error('Error finding review paste:', error);
            throw error;
        }
    }

    // Save current review to Pastebin
    async function saveReviewToCloud(textarea) {
        const asin = getCurrentASIN();
        if (!asin) {
            throw new Error('Could not determine ASIN from current page');
        }

        const productTitle = await getProductTitle();
        const pasteTitle = createReviewPasteTitle(productTitle, asin);
        const reviewContent = textarea.value;
        
        // Get review title if available
        const reviewTitleInput = document.getElementById('reviewTitle');
        const reviewTitle = reviewTitleInput ? reviewTitleInput.value.trim() : '';

        if (!reviewContent.trim()) {
            throw new Error('Review text is empty');
        }

        // Create JSON payload with both review body and title
        const reviewData = {
            reviewBody: reviewContent,
            reviewTitle: reviewTitle,
            asin: asin,
            productTitle: productTitle,
            savedAt: new Date().toISOString()
        };

        // Check if we already have a paste for this ASIN
        const existingPaste = await findReviewPasteForASIN(asin);

        if (existingPaste) {
            // Update existing paste (using delete + recreate since Pastebin doesn't support updates)
            try {
                // Delete old paste and create new one
                await deletePastebinPaste(existingPaste.key);
                const newPasteCode = await createPastebinPaste(pasteTitle, JSON.stringify(reviewData, null, 2), true);
                return {
                    success: true,
                    message: 'Review updated in cloud',
                    pasteKey: newPasteCode,
                    pasteUrl: `https://pastebin.com/${newPasteCode}`
                };
            } catch (error) {
                console.error('Failed to update review paste:', error);
                throw new Error('Failed to update review in cloud');
            }
        } else {
            // Create new paste
            try {
                const pasteCode = await createPastebinPaste(pasteTitle, JSON.stringify(reviewData, null, 2), true);
                return {
                    success: true,
                    message: 'Review saved to cloud',
                    pasteKey: pasteCode,
                    pasteUrl: `https://pastebin.com/${pasteCode}`
                };
            } catch (error) {
                console.error('Failed to create review paste:', error);
                throw new Error('Failed to save review to cloud');
            }
        }
    }

    // Fetch review from Pastebin
    async function fetchReviewFromCloud(textarea) {
        const asin = getCurrentASIN();
        if (!asin) {
            throw new Error('Could not determine ASIN from current page');
        }

        const existingPaste = await findReviewPasteForASIN(asin);

        if (!existingPaste) {
            throw new Error('No review found in cloud for this product');
        }

        try {
            const reviewContent = await getPastebinPaste(existingPaste.key);
            
            // Try to parse as JSON first (new format)
            let reviewData;
            try {
                reviewData = JSON.parse(reviewContent);
            } catch (parseError) {
                // Fallback to old format (plain text)
                console.log('Review is in old format (plain text), using as review body only');
                reviewData = { reviewBody: reviewContent };
            }

            // Set review body
            if (reviewData.reviewBody) {
                textarea.value = reviewData.reviewBody;
            } else {
                textarea.value = reviewContent; // Fallback to raw content
            }

            // Set review title if available
            if (reviewData.reviewTitle) {
                const reviewTitleInput = document.getElementById('reviewTitle');
                if (reviewTitleInput) {
                    reviewTitleInput.value = reviewData.reviewTitle;
                    // Trigger input event for title autosave
                    reviewTitleInput.dispatchEvent(new Event('input', { bubbles: true }));
                }
            }

            // Trigger input event to update any listeners
            textarea.dispatchEvent(new Event('input', { bubbles: true }));

            return {
                success: true,
                message: 'Review loaded from cloud',
                pasteKey: existingPaste.key,
                pasteUrl: `https://pastebin.com/${existingPaste.key}`
            };
        } catch (error) {
            console.error('Failed to fetch review paste:', error);
            throw new Error('Failed to load review from cloud');
        }
    }

    function getDraftKey(asin) {
        return asin ? `amazon_review_draft_${asin}` : null;
    }
    // --- NEW: Title draft key ---
    function getTitleDraftKey(asin) {
        return asin ? `amazon_review_title_draft_${asin}` : null;
    }

    function insertAutosaveStatusUI() {
        // Find the label container
        const label = document.querySelector('.in-context-ryp__field-label');
        if (!label) return null;
        let status = label.querySelector('.amazon-autosave-status');
        if (!status) {
            status = document.createElement('span');
            status.className = 'amazon-autosave-status';
            status.style.float = 'right';
            status.style.fontSize = '0.98em';
            status.style.color = '#888';
            status.style.marginLeft = '12px';
            status.style.fontWeight = '400';
            status.style.transition = 'color 0.2s';
            status.textContent = '';
            label.appendChild(status);
        }
        return status;
    }

    // --- NEW: Auto-Save for Review Title ---
    function attachTitleAutosave() {
        const titleInput = document.getElementById('reviewTitle');
        if (!titleInput || titleInput.dataset.amazonTitleAutosave) return;
        titleInput.dataset.amazonTitleAutosave = 'true';
        const asin = getCurrentASIN();
        const titleDraftKey = getTitleDraftKey(asin);
        // Find the label for the title
        const label = titleInput.closest('div').querySelector('.in-context-ryp__field-label');
        let statusUI = null;
        if (label) {
            statusUI = label.querySelector('.amazon-autosave-status-title');
            if (!statusUI) {
                statusUI = document.createElement('span');
                statusUI.className = 'amazon-autosave-status-title';
                statusUI.style.float = 'right';
                statusUI.style.fontSize = '0.98em';
                statusUI.style.color = '#888';
                statusUI.style.marginLeft = '12px';
                statusUI.style.fontWeight = '400';
                statusUI.style.transition = 'color 0.2s';
                statusUI.textContent = '';
                label.appendChild(statusUI);
            }
        }
        let saveTimeout = null;
        let lastSavedValue = '';
        // Restore draft if present
        if (titleDraftKey) {
            const saved = localStorage.getItem(titleDraftKey);
            if (saved && !titleInput.value) {
                titleInput.value = saved;
            }
        }
        // Save on input (debounced)
        function saveDraft() {
            if (!titleDraftKey) return;
            localStorage.setItem(titleDraftKey, titleInput.value);
            lastSavedValue = titleInput.value;
            if (statusUI) {
                statusUI.textContent = 'Saved.';
                statusUI.style.color = '#4caf50';
                setTimeout(() => {
                    if (statusUI.textContent === 'Saved.') statusUI.style.color = '#888';
                }, 1200);
            }
        }
        function onInput() {
            if (statusUI) statusUI.textContent = 'Saving...';
            if (saveTimeout) clearTimeout(saveTimeout);
            saveTimeout = setTimeout(saveDraft, 600);
        }
        titleInput.addEventListener('input', onInput);
        // Initial status
        if (statusUI) statusUI.textContent = '';
        // Clear draft on submit (if possible)
        function clearDraftOnSubmit() {
            if (!titleDraftKey) return;
            localStorage.removeItem(titleDraftKey);
            if (statusUI) statusUI.textContent = '';
        }
        // Try to detect submit button
        const form = titleInput.closest('form');
        if (form) {
            form.addEventListener('submit', clearDraftOnSubmit);
        } else {
            // Fallback: look for a submit button and listen for click
            const submitBtn = document.querySelector('button[type="submit"], input[type="submit"]');
            if (submitBtn) {
                submitBtn.addEventListener('click', clearDraftOnSubmit);
            }
        }
    }

    // --- Attach Toolbar to Review Textarea ---
    function attachToolbar() {
        const textarea = document.getElementById('reviewText');
        if (!textarea || textarea.dataset.unicodeToolbar) return;
        textarea.dataset.unicodeToolbar = 'true';
        const toolbar = createToolbar(textarea);
        textarea.parentNode.insertBefore(toolbar, textarea);

        // --- SWAP: Move template UI above label, autosave status into toolbar ---
        // 1. Move template UI above label
        const label = document.querySelector('.in-context-ryp__field-label');
        if (label) {
            // Find the template UI in the toolbar
            const templateContainer = toolbar.querySelector('div');
            if (templateContainer) {
                // Remove from toolbar and insert above label
                toolbar.removeChild(templateContainer);
                label.parentNode.insertBefore(templateContainer, label);
                templateContainer.style.marginLeft = '';
                templateContainer.style.justifyContent = 'flex-end';
                templateContainer.style.width = '100%';
            }
        }
        // 2. Move autosave status into toolbar, right-aligned
        let statusUI = document.querySelector('.amazon-autosave-status');
        if (statusUI) {
            // Remove from label and add to toolbar
            if (statusUI.parentNode) statusUI.parentNode.removeChild(statusUI);
            statusUI.style.float = '';
            statusUI.style.marginLeft = 'auto';
            statusUI.style.alignSelf = 'center';
            toolbar.appendChild(statusUI);
        } else {
            // If not present, create and add to toolbar
            statusUI = document.createElement('span');
            statusUI.className = 'amazon-autosave-status';
            statusUI.style.marginLeft = 'auto';
            statusUI.style.fontSize = '0.98em';
            statusUI.style.color = '#888';
            statusUI.style.fontWeight = '400';
            statusUI.style.transition = 'color 0.2s';
            statusUI.textContent = '';
            toolbar.appendChild(statusUI);
        }

        // --- AUTOSAVE LOGIC ---
        const asin = getCurrentASIN();
        const draftKey = getDraftKey(asin);
        let saveTimeout = null;
        let lastSavedValue = '';
        // Restore draft if present
        if (draftKey) {
            const saved = localStorage.getItem(draftKey);
            if (saved && !textarea.value) {
                textarea.value = saved;
            }
        }
        // Save on input (debounced)
        function saveDraft() {
            if (!draftKey) return;
            localStorage.setItem(draftKey, textarea.value);
            lastSavedValue = textarea.value;
            if (statusUI) {
                statusUI.textContent = 'Saved.';
                statusUI.style.color = '#4caf50';
                setTimeout(() => {
                    if (statusUI.textContent === 'Saved.') statusUI.style.color = '#888';
                }, 1200);
            }
        }
        function onInput() {
            if (statusUI) statusUI.textContent = 'Saving...';
            if (saveTimeout) clearTimeout(saveTimeout);
            saveTimeout = setTimeout(saveDraft, 600);
        }
        textarea.addEventListener('input', onInput);
        // Initial status
        if (statusUI) statusUI.textContent = '';
        // Clear draft on submit (if possible)
        function clearDraftOnSubmit() {
            if (!draftKey) return;
            localStorage.removeItem(draftKey);
            if (statusUI) statusUI.textContent = '';
        }
        // Try to detect submit button
        const form = textarea.closest('form');
        if (form) {
            form.addEventListener('submit', clearDraftOnSubmit);
        } else {
            // Fallback: look for a submit button and listen for click
            const submitBtn = document.querySelector('button[type="submit"], input[type="submit"]');
            if (submitBtn) {
                submitBtn.addEventListener('click', clearDraftOnSubmit);
            }
        }
        // Focus the textarea for better UX
        setTimeout(() => textarea.focus(), 100);
    }

    // --- Wait for textarea to appear ---
    function waitForTextarea() {
        const textarea = document.getElementById('reviewText');
        if (textarea) {
            attachToolbar();
        } else {
            setTimeout(waitForTextarea, 500);
        }
    }
    waitForTextarea();

    // --- Wait for review title to appear and attach autosave ---
    function waitForTitleInput() {
        const titleInput = document.getElementById('reviewTitle');
        if (titleInput) {
            attachTitleAutosave();
        } else {
            setTimeout(waitForTitleInput, 500);
        }
    }
    waitForTitleInput();

    // --- Drag-and-drop for media upload ---
    function enableMediaDragDrop() {
        const wrapper = document.querySelector('.in-context-ryp__form-field--mediaUploadInput--custom-wrapper');
        const fileInput = document.querySelector('input[type="file"]#media');
        if (!wrapper || !fileInput) return;

        // Create drag overlay text
        let dragText = document.createElement('div');
        dragText.textContent = 'Drag & drop files here';
        dragText.style.position = 'absolute';
        dragText.style.top = '50%';
        dragText.style.left = '50%';
        dragText.style.transform = 'translate(-50%, -50%)';
        dragText.style.fontSize = '1.2em';
        dragText.style.fontWeight = 'bold';
        dragText.style.color = '#1976d2';
        dragText.style.background = 'rgba(255,255,255,0.85)';
        dragText.style.padding = '12px 24px';
        dragText.style.borderRadius = '8px';
        dragText.style.boxShadow = '0 2px 8px rgba(33,150,243,0.08)';
        dragText.style.pointerEvents = 'none';
        dragText.style.zIndex = '100';
        dragText.style.display = 'none';
        dragText.className = 'amazon-dnd-dragtext';
        wrapper.style.position = 'relative';
        wrapper.appendChild(dragText);

        // Ensure Google Photos button exists
        let googleBtn = wrapper.querySelector('.google-photos-btn');
        if (!googleBtn) {
            googleBtn = document.createElement('a');
            googleBtn.href = 'https://photos.google.com/';
            googleBtn.target = '_blank';
            googleBtn.rel = 'noopener noreferrer';
            googleBtn.className = 'google-photos-btn';
            googleBtn.style.display = 'flex';
            googleBtn.style.alignItems = 'center';
            googleBtn.style.justifyContent = 'center';
            googleBtn.style.gap = '8px';
            googleBtn.style.margin = '18px 0 0 0';
            googleBtn.style.padding = '8px 16px';
            googleBtn.style.background = '#fff';
            googleBtn.style.border = '1px solid #dadce0';
            googleBtn.style.borderRadius = '6px 0 0 6px';
            googleBtn.style.boxShadow = '0 1px 2px rgba(60,64,67,.08)';
            googleBtn.style.fontSize = '1em';
            googleBtn.style.fontWeight = '500';
            googleBtn.style.color = '#444';
            googleBtn.style.cursor = 'pointer';
            googleBtn.style.textDecoration = 'none';
            googleBtn.style.width = 'fit-content';
            googleBtn.style.transition = 'background 0.15s, box-shadow 0.15s';
            googleBtn.innerHTML = `<img src="https://cdn.iconscout.com/icon/free/png-256/free-google-photos-logo-icon-download-in-svg-png-gif-file-formats--new-logos-pack-icons-2476486.png" alt="Google Photos" style="width: 22px; height: 22px; margin-right: 8px; vertical-align: middle;">Add from Google Photos...`;
            googleBtn.addEventListener('mouseenter', () => {
                googleBtn.style.background = '#f1f3f4';
                googleBtn.style.boxShadow = '0 2px 8px rgba(60,64,67,.13)';
            });
            googleBtn.addEventListener('mouseleave', () => {
                googleBtn.style.background = '#fff';
                googleBtn.style.boxShadow = '0 1px 2px rgba(60,64,67,.08)';
            });
            // Prevent file upload overlay from opening when clicking Google Photos
            googleBtn.addEventListener('click', (e) => {
                e.stopPropagation();
            });
        }

        // Create a Paste from Clipboard button
        let pasteBtn = wrapper.querySelector('.paste-clipboard-btn');
        if (!pasteBtn) {
            pasteBtn = document.createElement('button');
            pasteBtn.type = 'button';
            pasteBtn.className = 'paste-clipboard-btn';
            pasteBtn.style.display = 'flex';
            pasteBtn.style.alignItems = 'center';
            pasteBtn.style.justifyContent = 'center';
            pasteBtn.style.gap = '8px';
            pasteBtn.style.margin = '18px 0 0 0';
            pasteBtn.style.padding = '8px 16px';
            pasteBtn.style.background = '#fff';
            pasteBtn.style.border = '1px solid #dadce0';
            pasteBtn.style.borderLeft = 'none';
            pasteBtn.style.borderRadius = '0 6px 6px 0';
            pasteBtn.style.boxShadow = '0 1px 2px rgba(60,64,67,.08)';
            pasteBtn.style.fontSize = '1em';
            pasteBtn.style.fontWeight = '500';
            pasteBtn.style.color = '#444';
            pasteBtn.style.cursor = 'pointer';
            pasteBtn.style.textDecoration = 'none';
            pasteBtn.style.width = 'fit-content';
            pasteBtn.style.transition = 'background 0.15s, box-shadow 0.15s';
            pasteBtn.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#1976d2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right:8px;"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>Paste from Clipboard...`;
            pasteBtn.title = 'Paste image from clipboard';
            pasteBtn.addEventListener('mouseenter', () => {
                pasteBtn.style.background = '#f1f3f4';
                pasteBtn.style.boxShadow = '0 2px 8px rgba(60,64,67,.13)';
            });
            pasteBtn.addEventListener('mouseleave', () => {
                pasteBtn.style.background = '#fff';
                pasteBtn.style.boxShadow = '0 1px 2px rgba(60,64,67,.08)';
            });
            pasteBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                // Try to trigger a paste event on the wrapper
                // This will only work if the user has granted clipboard permissions
                navigator.clipboard.read().then(items => {
                    let foundImage = false;
                    for (const item of items) {
                        if (item.types.includes('image/png') || item.types.includes('image/jpeg')) {
                            foundImage = true;
                            item.getType(item.types.includes('image/png') ? 'image/png' : 'image/jpeg').then(blob => {
                                const file = new File([blob], 'clipboard-image.' + (item.types.includes('image/png') ? 'png' : 'jpg'), { type: blob.type });
                                const dt = new DataTransfer();
                                dt.items.add(file);
                                fileInput.files = dt.files;
                                fileInput.dispatchEvent(new Event('change', { bubbles: true }));
                                handleUploadUIUpdate();
                                // UI feedback: dim/blur area, hide buttons, show message
                                wrapper.classList.add('amazon-uploading');
                                wrapper.classList.remove('dragover');
                                let pasteText = wrapper.querySelector('.amazon-dnd-pastetext');
                                if (!pasteText) {
                                    pasteText = document.createElement('div');
                                    pasteText.className = 'amazon-dnd-pastetext';
                                    pasteText.textContent = 'Image pasted! Uploading...';
                                    pasteText.style.position = 'absolute';
                                    pasteText.style.top = '50%';
                                    pasteText.style.left = '50%';
                                    pasteText.style.transform = 'translate(-50%, -50%)';
                                    pasteText.style.fontSize = '1.2em';
                                    pasteText.style.fontWeight = 'bold';
                                    pasteText.style.color = '#388e3c';
                                    pasteText.style.background = 'rgba(255,255,255,0.98)';
                                    pasteText.style.padding = '16px 32px';
                                    pasteText.style.borderRadius = '12px';
                                    pasteText.style.boxShadow = '0 2px 12px rgba(56,142,60,0.10)';
                                    pasteText.style.pointerEvents = 'none';
                                    pasteText.style.zIndex = '101';
                                    pasteText.style.display = 'block';
                                    pasteText.style.textAlign = 'center';
                                    wrapper.appendChild(pasteText);
                                } else {
                                    pasteText.style.display = 'block';
                                }
                                setTimeout(() => {
                                    wrapper.classList.remove('amazon-uploading');
                                    if (pasteText) pasteText.style.display = 'none';
                                }, 2000);
                            }).catch(error => {
                                console.error('Error processing clipboard image:', error);
                                alert('Error processing clipboard image. Please try copying the image again.');
                            });
                            break;
                        }
                    }
                    if (!foundImage) {
                        alert('No image found in clipboard! Please copy an image first.');
                    }
                }).catch(error => {
                    console.error('Clipboard access error:', error);
                    if (error.name === 'NotAllowedError') {
                        alert('Clipboard access denied. Please grant clipboard permissions and try again.');
                    } else if (error.name === 'NotSupportedError') {
                        alert('Clipboard API not supported in this browser. Try using Ctrl+V instead.');
                    } else {
                        alert('Clipboard access failed. Please try using Ctrl+V to paste the image.');
                    }
                });
            });
        }

        // Find the outer upload container
        const mediaUploadInputWrapper = document.querySelector('.in-context-ryp__form-field--mediaUploadInput');

        // Ensure a container for both buttons, and insert both as a group
        let btnGroup = document.querySelector('.amazon-btn-group');
        if (!btnGroup) {
            btnGroup = document.createElement('div');
            btnGroup.className = 'amazon-btn-group';
            btnGroup.style.display = 'flex';
            btnGroup.style.flexDirection = 'row';
            btnGroup.style.gap = '0';
            btnGroup.style.margin = '24px auto 0 auto';
            btnGroup.style.width = 'fit-content';
            btnGroup.style.justifyContent = 'center';
        }
        // Ensure both buttons are in the group
        if (!btnGroup.contains(googleBtn)) btnGroup.appendChild(googleBtn);
        if (!btnGroup.contains(pasteBtn)) btnGroup.appendChild(pasteBtn);
        // Ensure group is in the correct place: after the upload area wrapper
        if (mediaUploadInputWrapper && mediaUploadInputWrapper.nextSibling !== btnGroup) {
            mediaUploadInputWrapper.parentNode.insertBefore(btnGroup, mediaUploadInputWrapper.nextSibling);
        }

        // Helper to always keep the button group after the upload area
        function repositionGooglePhotosBtn() {
            if (mediaUploadInputWrapper && mediaUploadInputWrapper.nextSibling !== btnGroup) {
                mediaUploadInputWrapper.parentNode.insertBefore(btnGroup, mediaUploadInputWrapper.nextSibling);
            }
        }

        // Call after each upload (drop or paste)
        function handleUploadUIUpdate() {
            setTimeout(repositionGooglePhotosBtn, 100); // Wait for DOM update
        }

        // Prevent default drag behaviors
        ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
            wrapper.addEventListener(eventName, e => e.preventDefault());
        });

        // Highlight on dragover
        wrapper.addEventListener('dragover', () => {
            wrapper.classList.add('dragover');
            dragText.style.display = 'block';
        });
        wrapper.addEventListener('dragenter', () => {
            wrapper.classList.add('dragover');
            dragText.style.display = 'block';
        });
        wrapper.addEventListener('dragleave', (e) => {
            if (!wrapper.contains(e.relatedTarget)) {
                wrapper.classList.remove('dragover');
                dragText.style.display = 'none';
            }
        });

        // Upload files one by one
        async function uploadFilesQueue(files) {
            for (let i = 0; i < files.length; i++) {
                try {
                    // Assign file to input
                    const dt = new DataTransfer();
                    dt.items.add(files[i]);
                    fileInput.files = dt.files;
                    fileInput.dispatchEvent(new Event('change', { bubbles: true }));

                    // Wait before uploading the next file
                    if (i < files.length - 1) {
                        await new Promise(res => setTimeout(res, 2000));
                    }
                } catch (error) {
                    console.error(`Error uploading file ${i + 1}:`, error);
                    // Continue with next file instead of stopping the entire queue
                }
            }
        }

        wrapper.addEventListener('drop', (e) => {
            wrapper.classList.remove('dragover');
            dragText.style.display = 'none';
            if (!e.dataTransfer || !e.dataTransfer.files || e.dataTransfer.files.length === 0) return;
            const files = Array.from(e.dataTransfer.files);
            if (files.length === 1) {
                // Single file: upload as normal
                const dt = new DataTransfer();
                dt.items.add(files[0]);
                fileInput.files = dt.files;
                fileInput.dispatchEvent(new Event('change', { bubbles: true }));
                handleUploadUIUpdate();
            } else {
                // Multiple files: upload one by one as a queue
                uploadFilesQueue(files).then(handleUploadUIUpdate);
            }
        });

        // --- Clipboard paste support for images ---
        wrapper.addEventListener('paste', (e) => {
            if (!e.clipboardData || !e.clipboardData.items) return;
            let foundImage = false;
            for (let i = 0; i < e.clipboardData.items.length; i++) {
                const item = e.clipboardData.items[i];
                if (item.type.startsWith('image/')) {
                    const file = item.getAsFile();
                    if (file) {
                        foundImage = true;
                        // Assign file to input and trigger upload
                        const dt = new DataTransfer();
                        dt.items.add(file);
                        fileInput.files = dt.files;
                        fileInput.dispatchEvent(new Event('change', { bubbles: true }));
                        e.preventDefault();
                        handleUploadUIUpdate();
                        break;
                    }
                }
            }
            if (foundImage) {
                // UI feedback: dim/blur area, hide buttons, show message
                wrapper.classList.add('amazon-uploading');
                wrapper.classList.remove('dragover');
                let pasteText = wrapper.querySelector('.amazon-dnd-pastetext');
                if (!pasteText) {
                    pasteText = document.createElement('div');
                    pasteText.className = 'amazon-dnd-pastetext';
                    pasteText.textContent = 'Image pasted! Uploading...';
                    pasteText.style.position = 'absolute';
                    pasteText.style.top = '50%';
                    pasteText.style.left = '50%';
                    pasteText.style.transform = 'translate(-50%, -50%)';
                    pasteText.style.fontSize = '1.2em';
                    pasteText.style.fontWeight = 'bold';
                    pasteText.style.color = '#388e3c';
                    pasteText.style.background = 'rgba(255,255,255,0.98)';
                    pasteText.style.padding = '16px 32px';
                    pasteText.style.borderRadius = '12px';
                    pasteText.style.boxShadow = '0 2px 12px rgba(56,142,60,0.10)';
                    pasteText.style.pointerEvents = 'none';
                    pasteText.style.zIndex = '101';
                    pasteText.style.display = 'block';
                    pasteText.style.textAlign = 'center';
                    wrapper.appendChild(pasteText);
                } else {
                    pasteText.style.display = 'block';
                }
                // Remove feedback after 2 seconds
                setTimeout(() => {
                    wrapper.classList.remove('amazon-uploading');
                    if (pasteText) pasteText.style.display = 'none';
                }, 2000);
            }
        });
    }

    // Wait for the media upload area to appear and enable drag-and-drop
    function waitForMediaUploadArea() {
        const wrapper = document.querySelector('.in-context-ryp__form-field--mediaUploadInput--custom-wrapper');
        const fileInput = document.querySelector('input[type="file"]#media');
        if (wrapper && fileInput) {
            // Prevent duplicate overlays
            if (!wrapper.querySelector('.amazon-dnd-dragtext')) {
                enableMediaDragDrop();
            }
        } else {
            setTimeout(waitForMediaUploadArea, 500);
        }
    }
    waitForMediaUploadArea();

    // --- Link all review candidate images to their product pages using ASIN from their review URLs ---
    function linkAllReviewCandidateImages() {
        const candidates = document.querySelectorAll('.ryp__review-candidate');
        candidates.forEach(candidate => {
            // Find the review link with ?asin=... - handle both URL patterns
            const reviewLink = candidate.querySelector('a[href*="/review/"]');
            if (!reviewLink) return;

            const url = new URL(reviewLink.href, window.location.origin);
            let asin = new URLSearchParams(url.search).get('asin');

            // If no ASIN in query params, try to extract from path (for create-review URLs)
            if (!asin && url.href.includes('/review/create-review')) {
                const asinMatch = url.href.match(/[?&]asin=([A-Z0-9]{10})/);
                if (asinMatch) {
                    asin = asinMatch[1];
                }
            }

            if (!asin) return;

            // Find the product image
            const img = candidate.querySelector('img.ryp__review-candidate__product-image');
            if (!img) return;

            // Check if already wrapped in a link to /dp/
            if (img.parentElement && img.parentElement.tagName === 'A' && img.parentElement.href.includes('/dp/')) return;

            // Create the product link
            const link = document.createElement('a');
            link.href = `https://www.amazon.ca/dp/${asin}`;
            link.target = '_blank';
            link.rel = 'noopener noreferrer';

            // Insert the image into the link
            img.parentNode.insertBefore(link, img);
            link.appendChild(img);
        });
    }
    // Wait for review candidate images to appear and link them
    function waitForReviewCandidateImages() {
        if (document.querySelector('.ryp__review-candidate__product-image')) {
            linkAllReviewCandidateImages();
        } else {
            setTimeout(waitForReviewCandidateImages, 500);
        }
    }
    waitForReviewCandidateImages();

    // --- Link review image to product page using ASIN from URL (main review image) ---
    function linkReviewImageToASIN() {
        // Only run on review pages
        if (!window.location.href.includes('/review/')) return;

        // Get ASIN from URL - handle both URL patterns
        const params = new URLSearchParams(window.location.search);
        let asin = params.get('asin');

        // If no ASIN in query params, try to extract from path (for create-review URLs)
        if (!asin && window.location.href.includes('/review/create-review')) {
            // Extract ASIN from URL like /review/create-review?encoding=UTF&asin=B0DTTHH7Y4
            const asinMatch = window.location.href.match(/[?&]asin=([A-Z0-9]{10})/);
            if (asinMatch) {
                asin = asinMatch[1];
            }
        }

        if (!asin) return;

        // Find the image element (first matching Amazon CDN image in review area)
        const img = document.querySelector('img[src*="m.media-amazon.com/images/I/"]');
        if (!img) return;

        // Check if already wrapped in a link
        if (img.parentElement && img.parentElement.tagName === 'A' && img.parentElement.href.includes('/dp/')) return;

        // Create the product link
        const link = document.createElement('a');
        link.href = `https://www.amazon.ca/dp/${asin}`;
        link.target = '_blank';
        link.rel = 'noopener noreferrer';

        // Insert the image into the link
        img.parentNode.insertBefore(link, img);
        link.appendChild(img);
    }
    // Wait for the review image to appear and link it
    function waitForReviewImageLink() {
        if (document.querySelector('img[src*="m.media-amazon.com/images/I/"]')) {
            linkReviewImageToASIN();
        } else {
            setTimeout(waitForReviewImageLink, 500);
        }
    }
    waitForReviewImageLink();
})();