/**
 * Public API Dropdown UI
 * 
 * Provides a dropdown menu for selecting pre-configured public APIs (no-auth).
 * When an API is selected, auto-creates layers with appropriate custom_api tokens.
 * 
 * @module public-api-ui
 * @since 5.2.0 - Custom API Content Block Phase 1
 */

import {
    LAYER_KIND_TOKEN_TEXT,
    LAYER_KIND_TOKEN_IMAGE,
    createTokenTextLayer,
    createTokenImageLayer
} from './layer-constants.js';

/**
 * Pre-configured public APIs (no authentication required)
 * Each API defines:
 * - name: Display name
 * - description: Brief description
 * - icon: Emoji icon
 * - api_url: The API endpoint
 * - refresh_interval: How often to refresh (seconds)
 * - layers: Array of layers to auto-create with token mappings
 * - field_mapping: JSONPath mappings for Roku to extract data
 */
const PUBLIC_API_TEMPLATES = {
    bitcoin_price: {
        name: 'Bitcoin Price',
        description: 'Live Bitcoin price from CoinGecko',
        icon: '💰',
        category: 'Finance',
        api_url: 'https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd',
        refresh_interval: 60,
        field_mapping: {
            number_value: 'bitcoin.usd'
        },
        display_options: {
            number_prefix: '$',
            number_suffix: ' USD'
        },
        layers: [
            { token: '{{custom_api.number}}', label: 'Bitcoin Price', y: 60, fontSize: 48, color: '#f7931a' }
        ]
    },
    random_joke: {
        name: 'Random Joke',
        description: 'Safe jokes from JokeAPI',
        icon: '😂',
        category: 'Entertainment',
        api_url: 'https://v2.jokeapi.dev/joke/Any?safe-mode&type=single',
        refresh_interval: 300,
        field_mapping: {
            primary_text: 'joke',
            secondary_text: 'category'
        },
        layers: [
            { token: '{{custom_api.secondary}}', label: 'Category', y: 20, fontSize: 16, color: '#888888' },
            { token: '{{custom_api.primary}}', label: 'Joke', y: 50, fontSize: 24 }
        ]
    },
    quotes: {
        name: 'Random Quote',
        description: 'Inspirational quotes from ZenQuotes',
        icon: '💬',
        category: 'Inspiration',
        api_url: 'https://zenquotes.io/api/random',
        refresh_interval: 300,
        data_path: {
            array_path: '',
            array_selection: 'first'
        },
        field_mapping: {
            primary_text: 'q',
            secondary_text: 'a'
        },
        layers: [
            { token: '{{custom_api.primary}}', label: 'Quote', y: 30, fontSize: 22 },
            { token: '{{custom_api.secondary}}', label: 'Author', y: 100, fontSize: 18, color: '#aaaaaa' }
        ]
    },
    trivia: {
        name: 'Trivia Question',
        description: 'Random trivia from Open Trivia DB',
        icon: '🎯',
        category: 'Entertainment',
        api_url: 'https://opentdb.com/api.php?amount=1&type=multiple',
        refresh_interval: 300,
        data_path: {
            array_path: 'results',
            array_selection: 'first'
        },
        field_mapping: {
            primary_text: 'question',
            secondary_text: 'category'
        },
        layers: [
            { token: '{{custom_api.secondary}}', label: 'Category', y: 20, fontSize: 16, color: '#ffcc00' },
            { token: '{{custom_api.primary}}', label: 'Question', y: 50, fontSize: 22 }
        ]
    },
    cat_facts: {
        name: 'Cat Facts',
        description: 'Random cat facts',
        icon: '🐱',
        category: 'Fun',
        api_url: 'https://catfact.ninja/fact',
        refresh_interval: 300,
        field_mapping: {
            primary_text: 'fact'
        },
        layers: [
            { token: '{{custom_api.primary}}', label: 'Cat Fact', y: 40, fontSize: 22 }
        ]
    },
    dog_facts: {
        name: 'Dog Facts',
        description: 'Random dog facts',
        icon: '🐕',
        category: 'Fun',
        api_url: 'https://dogapi.dog/api/v2/facts',
        refresh_interval: 300,
        data_path: {
            array_path: 'data',
            array_selection: 'first'
        },
        field_mapping: {
            primary_text: 'attributes.body'
        },
        layers: [
            { token: '{{custom_api.primary}}', label: 'Dog Fact', y: 40, fontSize: 22 }
        ]
    },
    space_nasa: {
        name: 'NASA Astronomy Picture',
        description: 'Astronomy Picture of the Day',
        icon: '🚀',
        category: 'Science',
        api_url: 'https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY',
        refresh_interval: 3600,
        field_mapping: {
            primary_text: 'title',
            secondary_text: 'explanation',
            image_url: 'url',
            date_value: 'date'
        },
        layers: [
            { token: '{{custom_api.image}}', label: 'Image', type: 'image', y: 20, width: 300, height: 200 },
            { token: '{{custom_api.primary}}', label: 'Title', y: 230, fontSize: 24 },
            { token: '{{custom_api.date}}', label: 'Date', y: 270, fontSize: 14, color: '#888888' }
        ]
    },
    useless_facts: {
        name: 'Useless Facts',
        description: 'Random useless facts',
        icon: '🤓',
        category: 'Fun',
        api_url: 'https://uselessfacts.jsph.pl/api/v2/facts/random',
        refresh_interval: 300,
        field_mapping: {
            primary_text: 'text',
            secondary_text: 'source'
        },
        layers: [
            { token: '{{custom_api.primary}}', label: 'Fact', y: 40, fontSize: 22 },
            { token: '{{custom_api.secondary}}', label: 'Source', y: 100, fontSize: 14, color: '#666666' }
        ]
    },
    advice: {
        name: 'Random Advice',
        description: 'Life advice from Advice Slip',
        icon: '🎓',
        category: 'Inspiration',
        api_url: 'https://api.adviceslip.com/advice',
        refresh_interval: 300,
        field_mapping: {
            primary_text: 'slip.advice'
        },
        layers: [
            { token: '{{custom_api.primary}}', label: 'Advice', y: 50, fontSize: 24 }
        ]
    },
    chuck_norris: {
        name: 'Chuck Norris Jokes',
        description: 'Random Chuck Norris facts',
        icon: '👊',
        category: 'Entertainment',
        api_url: 'https://api.chucknorris.io/jokes/random',
        refresh_interval: 300,
        field_mapping: {
            primary_text: 'value',
            image_url: 'icon_url'
        },
        layers: [
            { token: '{{custom_api.image}}', label: 'Icon', type: 'image', x: 20, y: 20, width: 80, height: 80 },
            { token: '{{custom_api.primary}}', label: 'Joke', x: 120, y: 40, fontSize: 20, width: 500 }
        ]
    },
    
    // ═══════════════════════════════════════════════════════════════
    // EXPANDED API LIST - Additional No-Auth APIs
    // ═══════════════════════════════════════════════════════════════
    
    // 🐾 Animals
    random_fox: {
        name: 'Random Fox Image',
        description: 'Adorable fox photos',
        icon: '🦊',
        category: 'Animals',
        api_url: 'https://randomfox.ca/floof/',
        refresh_interval: 300,
        field_mapping: {
            image_url: 'image'
        },
        layers: [
            { token: '{{custom_api.image}}', label: 'Fox Photo', type: 'image', x: 40, y: 20, width: 400, height: 300 }
        ]
    },
    random_dog: {
        name: 'Random Dog Image',
        description: 'Dog photos from Dog CEO',
        icon: '🐕',
        category: 'Animals',
        api_url: 'https://dog.ceo/api/breeds/image/random',
        refresh_interval: 300,
        field_mapping: {
            image_url: 'message'
        },
        layers: [
            { token: '{{custom_api.image}}', label: 'Dog Photo', type: 'image', x: 40, y: 20, width: 400, height: 300 }
        ]
    },
    random_duck: {
        name: 'Random Duck Image',
        description: 'Quacking duck photos',
        icon: '🦆',
        category: 'Animals',
        api_url: 'https://random-d.uk/api/random',
        refresh_interval: 300,
        field_mapping: {
            image_url: 'url'
        },
        layers: [
            { token: '{{custom_api.image}}', label: 'Duck Photo', type: 'image', x: 40, y: 20, width: 400, height: 300 }
        ]
    },
    
    // 💱 Finance
    exchange_rates: {
        name: 'USD Exchange Rates',
        description: 'Live currency exchange rates',
        icon: '💱',
        category: 'Finance',
        api_url: 'https://open.er-api.com/v6/latest/USD',
        refresh_interval: 3600,
        field_mapping: {
            number_value: 'rates.EUR',
            secondary_text: 'time_last_update_utc'
        },
        display_options: {
            number_prefix: '€',
            number_suffix: ''
        },
        layers: [
            { token: '{{custom_api.number}}', label: 'EUR Rate', y: 50, fontSize: 48, color: '#0052cc' },
            { token: '{{custom_api.secondary}}', label: 'Updated', y: 110, fontSize: 14, color: '#666666' }
        ]
    },
    
    // 🚀 Space
    iss_location: {
        name: 'ISS Location',
        description: 'Current position of the International Space Station',
        icon: '🛸',
        category: 'Space',
        api_url: 'http://api.open-notify.org/iss-now.json',
        refresh_interval: 30,
        field_mapping: {
            primary_text: 'iss_position.latitude',
            secondary_text: 'iss_position.longitude'
        },
        layers: [
            { token: '{{custom_api.primary}}', label: 'Latitude', y: 40, fontSize: 32, color: '#00d4ff' },
            { token: '{{custom_api.secondary}}', label: 'Longitude', y: 90, fontSize: 32, color: '#00d4ff' }
        ]
    },
    people_in_space: {
        name: 'People in Space',
        description: 'Current astronauts in space',
        icon: '👨‍🚀',
        category: 'Space',
        api_url: 'http://api.open-notify.org/astros.json',
        refresh_interval: 3600,
        field_mapping: {
            number_value: 'number'
        },
        layers: [
            { token: '{{custom_api.number}}', label: 'Astronauts in Space', y: 60, fontSize: 64, color: '#6366f1' }
        ]
    },
    spacex_latest: {
        name: 'SpaceX Latest Launch',
        description: 'Most recent SpaceX mission',
        icon: '🚀',
        category: 'Space',
        api_url: 'https://api.spacexdata.com/v5/launches/latest',
        refresh_interval: 3600,
        field_mapping: {
            primary_text: 'name',
            secondary_text: 'date_utc',
            image_url: 'links.patch.small'
        },
        layers: [
            { token: '{{custom_api.image}}', label: 'Mission Patch', type: 'image', x: 20, y: 20, width: 100, height: 100 },
            { token: '{{custom_api.primary}}', label: 'Mission Name', x: 140, y: 40, fontSize: 24 },
            { token: '{{custom_api.secondary}}', label: 'Launch Date', x: 140, y: 80, fontSize: 14, color: '#888888' }
        ]
    },
    
    // 👤 Random Data
    random_user: {
        name: 'Random User',
        description: 'Generate random user profiles',
        icon: '👤',
        category: 'Random',
        api_url: 'https://randomuser.me/api/',
        refresh_interval: 300,
        data_path: {
            array_path: 'results',
            array_selection: 'first'
        },
        field_mapping: {
            primary_text: 'name.first',
            secondary_text: 'location.city',
            image_url: 'picture.large'
        },
        layers: [
            { token: '{{custom_api.image}}', label: 'Photo', type: 'image', x: 20, y: 20, width: 100, height: 100 },
            { token: '{{custom_api.primary}}', label: 'Name', x: 140, y: 40, fontSize: 28 },
            { token: '{{custom_api.secondary}}', label: 'City', x: 140, y: 80, fontSize: 16, color: '#888888' }
        ]
    },
    random_photo: {
        name: 'Random Photo',
        description: 'Beautiful stock photos from Picsum',
        icon: '📷',
        category: 'Images',
        api_url: 'https://picsum.photos/id/0/info',
        refresh_interval: 300,
        field_mapping: {
            primary_text: 'author',
            image_url: 'download_url'
        },
        layers: [
            { token: '{{custom_api.image}}', label: 'Photo', type: 'image', x: 20, y: 20, width: 400, height: 280 },
            { token: '{{custom_api.primary}}', label: 'Photographer', y: 320, fontSize: 14, color: '#888888' }
        ]
    },
    
    // 🎤 More Entertainment
    kanye_quotes: {
        name: 'Kanye West Quotes',
        description: 'Random Kanye quotes',
        icon: '🎤',
        category: 'Entertainment',
        api_url: 'https://api.kanye.rest',
        refresh_interval: 300,
        field_mapping: {
            primary_text: 'quote'
        },
        layers: [
            { token: '{{custom_api.primary}}', label: 'Quote', y: 50, fontSize: 22 }
        ]
    },
    dad_jokes: {
        name: 'Dad Jokes',
        description: 'Groan-worthy dad jokes',
        icon: '👴',
        category: 'Entertainment',
        api_url: 'https://icanhazdadjoke.com/',
        refresh_interval: 300,
        headers: { 'Accept': 'application/json' },
        field_mapping: {
            primary_text: 'joke'
        },
        layers: [
            { token: '{{custom_api.primary}}', label: 'Dad Joke', y: 50, fontSize: 24 }
        ]
    },
    bored_activity: {
        name: 'Activity Suggestion',
        description: 'Get ideas when bored',
        icon: '🎲',
        category: 'Lifestyle',
        api_url: 'https://bored-api.appbrewery.com/random',
        refresh_interval: 600,
        field_mapping: {
            primary_text: 'activity',
            secondary_text: 'type'
        },
        layers: [
            { token: '{{custom_api.secondary}}', label: 'Type', y: 20, fontSize: 16, color: '#ff6b6b' },
            { token: '{{custom_api.primary}}', label: 'Activity', y: 50, fontSize: 24 }
        ]
    },
    
    // 🍸 Food & Drink
    random_cocktail: {
        name: 'Random Cocktail',
        description: 'Cocktail recipes',
        icon: '🍸',
        category: 'Food & Drink',
        api_url: 'https://www.thecocktaildb.com/api/json/v1/1/random.php',
        refresh_interval: 300,
        data_path: {
            array_path: 'drinks',
            array_selection: 'first'
        },
        field_mapping: {
            primary_text: 'strDrink',
            secondary_text: 'strCategory',
            image_url: 'strDrinkThumb'
        },
        layers: [
            { token: '{{custom_api.image}}', label: 'Cocktail', type: 'image', x: 20, y: 20, width: 200, height: 200 },
            { token: '{{custom_api.primary}}', label: 'Name', x: 240, y: 40, fontSize: 28 },
            { token: '{{custom_api.secondary}}', label: 'Category', x: 240, y: 80, fontSize: 16, color: '#888888' }
        ]
    },
    random_meal: {
        name: 'Random Meal',
        description: 'Meal recipes from around the world',
        icon: '🍽️',
        category: 'Food & Drink',
        api_url: 'https://www.themealdb.com/api/json/v1/1/random.php',
        refresh_interval: 300,
        data_path: {
            array_path: 'meals',
            array_selection: 'first'
        },
        field_mapping: {
            primary_text: 'strMeal',
            secondary_text: 'strArea',
            image_url: 'strMealThumb'
        },
        layers: [
            { token: '{{custom_api.image}}', label: 'Meal', type: 'image', x: 20, y: 20, width: 200, height: 200 },
            { token: '{{custom_api.primary}}', label: 'Dish Name', x: 240, y: 40, fontSize: 24 },
            { token: '{{custom_api.secondary}}', label: 'Cuisine', x: 240, y: 80, fontSize: 16, color: '#888888' }
        ]
    },
    
    // 🎮 Gaming
    pokemon: {
        name: 'Pikachu Stats',
        description: 'Pokemon data from PokeAPI',
        icon: '⚡',
        category: 'Gaming',
        api_url: 'https://pokeapi.co/api/v2/pokemon/pikachu',
        refresh_interval: 86400,
        field_mapping: {
            primary_text: 'name',
            number_value: 'base_experience',
            image_url: 'sprites.front_default'
        },
        layers: [
            { token: '{{custom_api.image}}', label: 'Sprite', type: 'image', x: 20, y: 20, width: 96, height: 96 },
            { token: '{{custom_api.primary}}', label: 'Name', x: 130, y: 40, fontSize: 28 },
            { token: '{{custom_api.number}}', label: 'XP', x: 130, y: 80, fontSize: 18, color: '#fbbf24' }
        ]
    },
    
    // 🌍 Location/IP
    ip_geolocation: {
        name: 'IP Geolocation',
        description: 'Your public IP and location',
        icon: '🌍',
        category: 'Utility',
        api_url: 'http://ip-api.com/json/',
        refresh_interval: 3600,
        field_mapping: {
            primary_text: 'city',
            secondary_text: 'country',
            tertiary_text: 'query'
        },
        layers: [
            { token: '{{custom_api.primary}}', label: 'City', y: 30, fontSize: 32 },
            { token: '{{custom_api.secondary}}', label: 'Country', y: 70, fontSize: 20, color: '#888888' },
            { token: '{{custom_api.tertiary}}', label: 'IP Address', y: 110, fontSize: 14, color: '#666666' }
        ]
    },
    
    // 🔮 Name Analysis
    age_guesser: {
        name: 'Age Guesser',
        description: 'Guess age from name (try changing URL param)',
        icon: '🔮',
        category: 'Fun',
        api_url: 'https://api.agify.io?name=Michael',
        refresh_interval: 86400,
        field_mapping: {
            primary_text: 'name',
            number_value: 'age'
        },
        layers: [
            { token: '{{custom_api.primary}}', label: 'Name', y: 30, fontSize: 24 },
            { token: '{{custom_api.number}}', label: 'Predicted Age', y: 80, fontSize: 48, color: '#8b5cf6' }
        ]
    },
    gender_guesser: {
        name: 'Gender Guesser',
        description: 'Guess gender from name',
        icon: '🎭',
        category: 'Fun',
        api_url: 'https://api.genderize.io?name=Emily',
        refresh_interval: 86400,
        field_mapping: {
            primary_text: 'name',
            secondary_text: 'gender',
            number_value: 'probability'
        },
        layers: [
            { token: '{{custom_api.primary}}', label: 'Name', y: 30, fontSize: 24 },
            { token: '{{custom_api.secondary}}', label: 'Gender', y: 70, fontSize: 32, color: '#ec4899' }
        ]
    }
};

/**
 * Get all available public API templates
 * @returns {Object} Template configurations keyed by ID
 */
export function getPublicApiTemplates() {
    return PUBLIC_API_TEMPLATES;
}

/**
 * Get template by ID
 * @param {string} templateId 
 * @returns {Object|null}
 */
export function getPublicApiTemplate(templateId) {
    return PUBLIC_API_TEMPLATES[templateId] || null;
}

/**
 * Attach Public API dropdown to canvas editor
 * 
 * @param {Object} editor - Canvas editor instance
 */
export function attachPublicApiDropdown(editor) {
    const mainButton = document.getElementById('ccve-public-api-btn');
    if (!mainButton) {
        console.warn('[Public API UI] Button #ccve-public-api-btn not found');
        return;
    }
    
    // Create dropdown container wrapper
    const dropdownContainer = document.createElement('div');
    dropdownContainer.className = 'ccve-public-api-dropdown';
    dropdownContainer.style.position = 'relative';
    dropdownContainer.style.display = 'inline-block';
    
    // Wrap the existing button
    mainButton.parentNode.insertBefore(dropdownContainer, mainButton);
    dropdownContainer.appendChild(mainButton);
    
    // Create dropdown menu
    const dropdown = document.createElement('div');
    dropdown.className = 'ccve-public-api-menu';
    dropdown.style.cssText = `
        position: absolute;
        top: 100%;
        left: 0;
        margin-top: 4px;
        background: white;
        border: 1px solid #d1d5db;
        border-radius: 8px;
        box-shadow: 0 10px 25px -5px rgba(0,0,0,0.15), 0 4px 6px -2px rgba(0,0,0,0.05);
        min-width: 320px;
        max-height: 480px;
        overflow-y: auto;
        z-index: 1000;
        display: none;
    `;
    
    // Build menu structure
    dropdown.innerHTML = buildPublicApiMenu();
    
    // Toggle dropdown on button click
    mainButton.addEventListener('click', (e) => {
        e.stopPropagation();
        const isVisible = dropdown.style.display === 'block';
        dropdown.style.display = isVisible ? 'none' : 'block';
    });
    
    // Close dropdown when clicking outside
    document.addEventListener('click', (e) => {
        if (!dropdownContainer.contains(e.target)) {
            dropdown.style.display = 'none';
        }
    });
    
    // Handle menu item clicks
    dropdown.addEventListener('click', (e) => {
        const menuItem = e.target.closest('.ccve-api-menu-item');
        if (!menuItem) return;
        
        const templateId = menuItem.dataset.templateId;
        if (templateId) {
            handlePublicApiSelection(editor, templateId);
            dropdown.style.display = 'none';
        }
    });
    
    dropdownContainer.appendChild(dropdown);
    
    // Store reference on editor
    editor._publicApiDropdown = dropdownContainer;
    
    console.log('[Public API UI] Dropdown attached successfully');
}

/**
 * Build the dropdown menu HTML organized by category
 * @returns {string}
 */
function buildPublicApiMenu() {
    // Group templates by category
    const categories = {};
    for (const [id, template] of Object.entries(PUBLIC_API_TEMPLATES)) {
        const cat = template.category || 'Other';
        if (!categories[cat]) categories[cat] = [];
        categories[cat].push({ id, ...template });
    }
    
    let html = `
        <div style="padding: 12px 16px; border-bottom: 1px solid #e5e7eb;">
            <div style="font-weight: 600; font-size: 14px; color: #374151;">🌐 Public APIs</div>
            <div style="font-size: 11px; color: #6b7280; margin-top: 2px;">No API key required • Auto-creates layers</div>
        </div>
    `;
    
    for (const [category, templates] of Object.entries(categories)) {
        html += `
            <div class="ccve-api-category">
                <div style="padding: 8px 16px; font-size: 11px; font-weight: 600; color: #9ca3af; text-transform: uppercase; letter-spacing: 0.5px; background: #f9fafb;">
                    ${category}
                </div>
        `;
        
        for (const template of templates) {
            const layerCount = template.layers ? template.layers.length : 0;
            html += `
                <div class="ccve-api-menu-item" data-template-id="${template.id}" style="
                    padding: 10px 16px;
                    cursor: pointer;
                    display: flex;
                    align-items: center;
                    gap: 12px;
                    transition: background 0.15s;
                " onmouseover="this.style.background='#f3f4f6'" onmouseout="this.style.background='transparent'">
                    <span style="font-size: 24px; width: 32px; text-align: center;">${template.icon}</span>
                    <div style="flex: 1; min-width: 0;">
                        <div style="font-weight: 500; font-size: 13px; color: #111827;">${template.name}</div>
                        <div style="font-size: 11px; color: #6b7280; margin-top: 1px;">${template.description}</div>
                    </div>
                    <div style="font-size: 10px; color: #9ca3af; background: #f3f4f6; padding: 2px 6px; border-radius: 4px;">
                        ${layerCount} layer${layerCount !== 1 ? 's' : ''}
                    </div>
                </div>
            `;
        }
        
        html += '</div>';
    }
    
    html += `
        <div style="padding: 10px 16px; border-top: 1px solid #e5e7eb; background: #f9fafb;">
            <div class="ccve-api-menu-item" data-template-id="__custom_url__" style="
                padding: 10px 12px;
                cursor: pointer;
                display: flex;
                align-items: center;
                gap: 12px;
                background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
                border-radius: 6px;
                margin-bottom: 8px;
            " onmouseover="this.style.opacity='0.9'" onmouseout="this.style.opacity='1'">
                <span style="font-size: 20px; width: 28px; text-align: center;">🔗</span>
                <div style="flex: 1;">
                    <div style="font-weight: 600; font-size: 13px; color: #fff;">Custom API URL</div>
                    <div style="font-size: 10px; color: rgba(255,255,255,0.8);">Enter any JSON API endpoint • Auto-detects fields</div>
                </div>
            </div>
            <div style="font-size: 11px; color: #6b7280;">
                💡 Tip: Double-click any layer to adjust position, size, and styling
            </div>
        </div>
    `;
    
    return html;
}

/**
 * Handle public API template selection
 * Creates a new Custom API content block and auto-generates layers
 * 
 * @param {Object} editor - Canvas editor instance
 * @param {string} templateId - Selected template ID
 */
async function handlePublicApiSelection(editor, templateId) {
    // Handle custom URL entry
    if (templateId === '__custom_url__') {
        await handleCustomUrlEntry(editor);
        return;
    }
    
    const template = PUBLIC_API_TEMPLATES[templateId];
    if (!template) {
        console.error('[Public API UI] Template not found:', templateId);
        return;
    }
    
    console.log('[Public API UI] Selected template:', templateId, template);
    
    // Show loading notification
    if (editor.showNotification) {
        editor.showNotification(`Creating ${template.name} block...`, 'info');
    }
    
    try {
        // Step 1: Create a new Custom API content block via REST
        const blockName = prompt(`Name for your ${template.name} content block:`, `${template.name} Block`);
        if (!blockName) return; // User cancelled
        
        const dataConfig = {
            api_config: {
                api_url: template.api_url,
                refresh_interval: template.refresh_interval,
                http_method: 'GET',
                timeout: 10,
                cache_duration: template.refresh_interval * 2
            },
            data_path: template.data_path || {},
            field_mapping: template.field_mapping || {},
            display_options: template.display_options || {},
            api_templates: { template: templateId }
        };
        
        const resp = await fetch(`${castconductorCanvasAjax.rest_url}castconductor/v5/content-blocks`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-WP-Nonce': castconductorCanvasAjax.nonce
            },
            body: JSON.stringify({
                name: blockName,
                type: 'custom_api',
                enabled: true,
                data_config: dataConfig,
                visual_config: {}
            })
        });
        
        if (!resp.ok) {
            throw new Error(`HTTP ${resp.status}`);
        }
        
        const data = await resp.json();
        const blockId = data.id || data.data?.id;
        
        if (!blockId) {
            throw new Error('No block ID returned');
        }
        
        console.log('[Public API UI] Created block:', blockId);
        
        // Step 2: Generate layers based on template
        const layers = generateLayersFromTemplate(template);
        
        // Step 3: Save visual_config with the layers
        const visualConfig = {
            layers: layers,
            background: {
                type: 'solid',
                color: '#1a1a2e'
            }
        };
        
        // Update block with visual config
        await fetch(`${castconductorCanvasAjax.rest_url}castconductor/v5/content-blocks/${blockId}`, {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json',
                'X-WP-Nonce': castconductorCanvasAjax.nonce
            },
            body: JSON.stringify({
                visual_config: visualConfig
            })
        });
        
        // Step 4: Reload content blocks list and load the new block
        if (editor.loadLiveContentBlocks) {
            await editor.loadLiveContentBlocks();
        }
        
        if (editor.loadContentBlock) {
            await editor.loadContentBlock(blockId);
        }
        
        if (editor.showNotification) {
            editor.showNotification(`✅ ${template.name} block created with ${layers.length} layers!`, 'success');
        }
        
    } catch (error) {
        console.error('[Public API UI] Error creating block:', error);
        if (editor.showNotification) {
            editor.showNotification(`Failed to create block: ${error.message}`, 'error');
        }
    }
}

/**
 * Handle custom URL entry with auto-test and field detection
 * Shows a modal with URL input and optional authentication fields
 */
async function handleCustomUrlEntry(editor) {
    // Remove any existing modal
    const existingModal = document.getElementById('ccve-custom-api-modal');
    if (existingModal) existingModal.remove();
    
    // Create modal
    const modal = document.createElement('div');
    modal.id = 'ccve-custom-api-modal';
    modal.style.cssText = `
        position: fixed;
        top: 0; left: 0; right: 0; bottom: 0;
        background: rgba(0,0,0,0.5);
        display: flex;
        align-items: center;
        justify-content: center;
        z-index: 100000;
    `;
    
    modal.innerHTML = `
        <div style="background: #1f2937; border-radius: 12px; padding: 24px; width: 480px; max-height: 90vh; overflow-y: auto; color: #fff; font-family: system-ui, sans-serif;">
            <h3 style="margin: 0 0 16px 0; font-size: 18px;">🔗 Custom API Configuration</h3>
            
            <div style="margin-bottom: 16px;">
                <label style="display: block; margin-bottom: 4px; font-size: 13px; color: #94a3b8;">API URL *</label>
                <input type="text" id="ccve-api-url" placeholder="https://api.example.com/data" style="width: 100%; padding: 10px 12px; border: 1px solid #374151; border-radius: 6px; background: #111827; color: #fff; font-size: 14px;" />
                <div style="font-size: 11px; color: #64748b; margin-top: 4px;">Enter the full API endpoint URL</div>
            </div>
            
            <div style="margin-bottom: 16px;">
                <label style="display: block; margin-bottom: 4px; font-size: 13px; color: #94a3b8;">Authentication Type</label>
                <select id="ccve-auth-type" style="width: 100%; padding: 10px 12px; border: 1px solid #374151; border-radius: 6px; background: #111827; color: #fff; font-size: 14px;">
                    <option value="none">No Authentication</option>
                    <option value="header">API Key in Header</option>
                    <option value="query">API Key in Query Parameter</option>
                    <option value="bearer">Bearer Token</option>
                    <option value="basic">Basic Auth (username:password)</option>
                </select>
            </div>
            
            <div id="ccve-auth-fields" style="display: none;">
                <div id="ccve-auth-key-name-row" style="margin-bottom: 12px;">
                    <label style="display: block; margin-bottom: 4px; font-size: 13px; color: #94a3b8;">Header/Parameter Name</label>
                    <input type="text" id="ccve-auth-key-name" placeholder="X-API-Key or api_key" style="width: 100%; padding: 10px 12px; border: 1px solid #374151; border-radius: 6px; background: #111827; color: #fff; font-size: 14px;" />
                </div>
                
                <div style="margin-bottom: 12px;">
                    <label style="display: block; margin-bottom: 4px; font-size: 13px; color: #94a3b8;">API Key / Token *</label>
                    <input type="password" id="ccve-auth-key" placeholder="Your API key or token" style="width: 100%; padding: 10px 12px; border: 1px solid #374151; border-radius: 6px; background: #111827; color: #fff; font-size: 14px;" />
                    <div style="font-size: 11px; color: #64748b; margin-top: 4px;">🔒 Stored securely in the database</div>
                </div>
                
                <div id="ccve-auth-secret-row" style="margin-bottom: 12px; display: none;">
                    <label style="display: block; margin-bottom: 4px; font-size: 13px; color: #94a3b8;">API Secret (if required)</label>
                    <input type="password" id="ccve-auth-secret" placeholder="Your API secret" style="width: 100%; padding: 10px 12px; border: 1px solid #374151; border-radius: 6px; background: #111827; color: #fff; font-size: 14px;" />
                </div>
            </div>
            
            <div style="margin-bottom: 16px; padding: 12px; background: #111827; border-radius: 8px;">
                <div style="font-size: 12px; color: #94a3b8; margin-bottom: 8px;">📡 Connection Status</div>
                <div id="ccve-api-status" style="font-size: 13px; color: #64748b;">Enter a URL and test the connection</div>
            </div>
            
            <div style="display: flex; gap: 8px; justify-content: flex-end;">
                <button type="button" id="ccve-api-test" style="padding: 10px 16px; background: #374151; border: none; border-radius: 6px; color: #fff; cursor: pointer; font-size: 13px;">🧪 Test Connection</button>
                <button type="button" id="ccve-api-cancel" style="padding: 10px 16px; background: #374151; border: none; border-radius: 6px; color: #fff; cursor: pointer; font-size: 13px;">Cancel</button>
                <button type="button" id="ccve-api-create" disabled style="padding: 10px 16px; background: #6366f1; border: none; border-radius: 6px; color: #fff; cursor: pointer; font-size: 13px; opacity: 0.5;">Create Block</button>
            </div>
        </div>
    `;
    
    document.body.appendChild(modal);
    
    // Get elements
    const urlInput = modal.querySelector('#ccve-api-url');
    const authTypeSelect = modal.querySelector('#ccve-auth-type');
    const authFields = modal.querySelector('#ccve-auth-fields');
    const authKeyNameRow = modal.querySelector('#ccve-auth-key-name-row');
    const authKeyNameInput = modal.querySelector('#ccve-auth-key-name');
    const authKeyInput = modal.querySelector('#ccve-auth-key');
    const authSecretRow = modal.querySelector('#ccve-auth-secret-row');
    const authSecretInput = modal.querySelector('#ccve-auth-secret');
    const statusDiv = modal.querySelector('#ccve-api-status');
    const testBtn = modal.querySelector('#ccve-api-test');
    const cancelBtn = modal.querySelector('#ccve-api-cancel');
    const createBtn = modal.querySelector('#ccve-api-create');
    
    let lastTestData = null;
    let lastTestFields = null;
    
    // Show/hide auth fields based on type
    authTypeSelect.addEventListener('change', () => {
        const authType = authTypeSelect.value;
        authFields.style.display = authType === 'none' ? 'none' : 'block';
        authKeyNameRow.style.display = (authType === 'header' || authType === 'query') ? 'block' : 'none';
        authSecretRow.style.display = authType === 'basic' ? 'block' : 'none';
        
        // Set placeholder based on type
        if (authType === 'bearer') {
            authKeyInput.placeholder = 'Bearer token (without "Bearer " prefix)';
        } else if (authType === 'basic') {
            authKeyInput.placeholder = 'Username';
            authSecretInput.placeholder = 'Password';
        } else {
            authKeyInput.placeholder = 'Your API key';
        }
    });
    
    // Test connection
    testBtn.addEventListener('click', async () => {
        const apiUrl = urlInput.value.trim();
        if (!apiUrl) {
            statusDiv.innerHTML = '<span style="color: #f87171;">Please enter a URL</span>';
            return;
        }
        
        try {
            new URL(apiUrl);
        } catch (e) {
            statusDiv.innerHTML = '<span style="color: #f87171;">Invalid URL format</span>';
            return;
        }
        
        statusDiv.innerHTML = '<span style="color: #60a5fa;">⏳ Testing connection...</span>';
        createBtn.disabled = true;
        createBtn.style.opacity = '0.5';
        
        try {
            // Build auth config
            const authType = authTypeSelect.value;
            const authConfig = { type: authType };
            
            if (authType !== 'none') {
                authConfig.key_name = authKeyNameInput.value.trim();
                authConfig.key_value = authKeyInput.value.trim();
                if (authType === 'basic') {
                    authConfig.secret = authSecretInput.value.trim();
                }
            }
            
            // Test via proxy
            const testResp = await fetch(`${castconductorCanvasAjax.rest_url}castconductor/v5/proxy/fetch`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-WP-Nonce': castconductorCanvasAjax.nonce
                },
                body: JSON.stringify({ url: apiUrl, auth: authConfig })
            });
            
            if (!testResp.ok) {
                const errText = await testResp.text();
                throw new Error(`HTTP ${testResp.status}: ${errText.substring(0, 100)}`);
            }
            
            lastTestData = await testResp.json();
            lastTestFields = detectApiFields(lastTestData);
            
            if (lastTestFields.length === 0) {
                statusDiv.innerHTML = '<span style="color: #fbbf24;">⚠️ Connected but no usable fields detected</span>';
            } else {
                statusDiv.innerHTML = `<span style="color: #34d399;">✅ Success! Found ${lastTestFields.length} fields (${lastTestFields.filter(f=>f.type==='text').length} text, ${lastTestFields.filter(f=>f.type==='image').length} image)</span>`;
                createBtn.disabled = false;
                createBtn.style.opacity = '1';
            }
            
        } catch (error) {
            console.error('[Custom API] Test failed:', error);
            statusDiv.innerHTML = `<span style="color: #f87171;">❌ ${error.message}</span>`;
            lastTestData = null;
            lastTestFields = null;
        }
    });
    
    // Cancel
    cancelBtn.addEventListener('click', () => modal.remove());
    modal.addEventListener('click', (e) => { if (e.target === modal) modal.remove(); });
    
    // Create block
    createBtn.addEventListener('click', async () => {
        if (!lastTestFields || lastTestFields.length === 0) {
            alert('Please test the connection first');
            return;
        }
        
        const blockName = prompt('Name for your content block:', 'Custom API Block');
        if (!blockName) return;
        
        const apiUrl = urlInput.value.trim();
        const authType = authTypeSelect.value;
        
        // Build auth config for storage
        const authConfig = { type: authType };
        if (authType !== 'none') {
            authConfig.key_name = authKeyNameInput.value.trim();
            authConfig.key_value = authKeyInput.value.trim();
            if (authType === 'basic') {
                authConfig.secret = authSecretInput.value.trim();
            }
        }
        
        // Build layers from detected fields
        const { fieldMapping, layers } = buildAutoConfig(lastTestFields);
        
        const dataConfig = {
            api_config: {
                api_url: apiUrl,
                auth: authConfig,
                refresh_interval: 300,
                http_method: 'GET',
                timeout: 10,
                cache_duration: 600
            },
            field_mapping: fieldMapping
        };
        
        try {
            const resp = await fetch(`${castconductorCanvasAjax.rest_url}castconductor/v5/content-blocks`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-WP-Nonce': castconductorCanvasAjax.nonce
                },
                body: JSON.stringify({
                    name: blockName,
                    type: 'custom_api',
                    enabled: true,
                    data_config: dataConfig,
                    visual_config: { layers, background: { type: 'solid', color: '#1a1a2e' } }
                })
            });
            
            if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
            
            const data = await resp.json();
            const blockId = data.id || data.data?.id;
            
            modal.remove();
            
            if (editor.loadLiveContentBlocks) await editor.loadLiveContentBlocks();
            if (editor.loadContentBlock) await editor.loadContentBlock(blockId);
            
            if (editor.showNotification) {
                editor.showNotification(`✅ Custom API block created with ${layers.length} layers!`, 'success');
            }
            
        } catch (error) {
            console.error('[Custom API] Create failed:', error);
            alert(`Failed to create block: ${error.message}`);
        }
    });
    
    // Focus URL input
    urlInput.focus();
}

/**
 * Detect usable fields from API response
 */
function detectApiFields(data, prefix = '', depth = 0) {
    const fields = [];
    if (depth > 3) return fields; // Limit depth
    
    // Handle arrays - use first element
    if (Array.isArray(data)) {
        if (data.length > 0) {
            return detectApiFields(data[0], prefix, depth);
        }
        return fields;
    }
    
    // Handle objects
    if (data && typeof data === 'object') {
        for (const [key, value] of Object.entries(data)) {
            const path = prefix ? `${prefix}.${key}` : key;
            
            if (typeof value === 'string') {
                // Detect if it's likely an image URL
                const isImage = /\.(jpg|jpeg|png|gif|webp|svg)(\?|$)/i.test(value) || 
                               /^https?:\/\/.*\/(image|img|photo|picture)/i.test(value);
                
                fields.push({
                    path,
                    type: isImage ? 'image' : 'text',
                    sample: value.substring(0, 100)
                });
            } else if (typeof value === 'number') {
                fields.push({ path, type: 'number', sample: String(value) });
            } else if (value && typeof value === 'object') {
                fields.push(...detectApiFields(value, path, depth + 1));
            }
        }
    }
    
    return fields;
}

/**
 * Build auto-config from detected fields
 */
function buildAutoConfig(fields) {
    const fieldMapping = {};
    const layers = [];
    let yPos = 30;
    let zIndex = 10;
    
    // Prioritize certain field names
    const textFields = fields.filter(f => f.type === 'text' || f.type === 'number');
    const imageFields = fields.filter(f => f.type === 'image');
    
    // Add first image if found
    if (imageFields.length > 0) {
        const img = imageFields[0];
        fieldMapping.image_url = img.path;
        layers.push({
            id: `layer_${Date.now()}_${zIndex}`,
            kind: LAYER_KIND_TOKEN_IMAGE,
            name: img.path.split('.').pop() || 'Image',
            visible: true,
            locked: false,
            token: 'custom_api.image',
            x: 50, y: yPos, width: 300, height: 200,
            z_index: zIndex
        });
        yPos += 220;
        zIndex += 10;
    }
    
    // Add up to 3 text fields
    const textLabels = ['primary_text', 'secondary_text', 'tertiary_text'];
    const tokenLabels = ['primary', 'secondary', 'tertiary'];
    
    for (let i = 0; i < Math.min(3, textFields.length); i++) {
        const field = textFields[i];
        fieldMapping[textLabels[i]] = field.path;
        
        layers.push({
            id: `layer_${Date.now()}_${zIndex}`,
            kind: LAYER_KIND_TOKEN_TEXT,
            name: field.path.split('.').pop() || `Text ${i + 1}`,
            visible: true,
            locked: false,
            templateText: `{{custom_api.${tokenLabels[i]}}}`,
            x: 50, y: yPos,
            width: 600, height: 40,
            font_size: i === 0 ? 28 : (i === 1 ? 20 : 16),
            font_color: i === 0 ? '#ffffff' : '#aaaaaa',
            font_weight: i === 0 ? '600' : '400',
            text_align: 'left',
            z_index: zIndex
        });
        yPos += 50;
        zIndex += 10;
    }
    
    return { fieldMapping, layers };
}

/**
 * Generate layer configurations from a template
 * 
 * @param {Object} template - API template configuration
 * @returns {Array} Array of layer objects
 */
function generateLayersFromTemplate(template) {
    const layers = [];
    let zIndex = 10;
    
    for (const layerDef of (template.layers || [])) {
        const isImage = layerDef.type === 'image';
        
        if (isImage) {
            // Create token image layer
            // Note: 'token' should be WITHOUT braces (e.g., "custom_api.image")
            // Strip {{ and }} if present in the template definition
            let tokenValue = layerDef.token || '';
            tokenValue = tokenValue.replace(/^\{\{\s*/, '').replace(/\s*\}\}$/, '');
            
            layers.push({
                id: `layer_${Date.now()}_${zIndex}`,
                kind: LAYER_KIND_TOKEN_IMAGE,
                name: layerDef.label || 'API Image',
                visible: true,
                locked: false,
                token: tokenValue,  // e.g., "custom_api.image" (without braces)
                x: layerDef.x || 50,
                y: layerDef.y || 50,
                width: layerDef.width || 200,
                height: layerDef.height || 150,
                z_index: zIndex
            });
        } else {
            // Create token text layer
            layers.push({
                id: `layer_${Date.now()}_${zIndex}`,
                kind: LAYER_KIND_TOKEN_TEXT,
                name: layerDef.label || 'API Text',
                visible: true,
                locked: false,
                templateText: layerDef.token,
                x: layerDef.x || 50,
                y: layerDef.y || 50,
                width: layerDef.width || 600,
                height: layerDef.height || 50,
                font_size: layerDef.fontSize || 24,
                font_color: layerDef.color || '#ffffff',
                font_weight: layerDef.fontWeight || '400',
                text_align: layerDef.textAlign || 'left',
                z_index: zIndex
            });
        }
        
        zIndex += 10;
    }
    
    return layers;
}

// Export for use in canvas-editor.js
export default {
    attachPublicApiDropdown,
    getPublicApiTemplates,
    getPublicApiTemplate
};
