/**
 * CollectionManager - Dynamic content collection management for .insertr-add elements
 * 
 * Handles:
 * - Template detection from existing children
 * - Add/remove/reorder UI controls
 * - Collection data management
 * - Integration with existing .insertr editing system
 */

import { InsertrFormRenderer } from './form-renderer.js';

export class CollectionManager {
    constructor(meta, apiClient, auth) {
        this.meta = meta;
        this.container = meta.element;
        this.apiClient = apiClient;
        this.auth = auth;
        
        // Collection state
        this.template = null;
        this.items = [];
        this.isActive = false;
        
        // UI elements
        this.addButton = null;
        this.itemControls = new Map(); // Map item element to its controls
        
        console.log('🔄 CollectionManager initialized for:', this.container);
    }
    
    /**
     * Initialize the collection manager
     */
    initialize() {
        if (this.isActive) return;
        
        console.log('🚀 Starting collection management for:', this.container.className);
        
        // Analyze existing content to detect template
        this.analyzeTemplate();
        
        // Add collection management UI only when in edit mode
        this.setupEditModeDetection();
        
        this.isActive = true;
    }
    
    /**
     * Set up detection for when edit mode is activated
     */
    setupEditModeDetection() {
        // Check current auth state
        if (this.auth.isAuthenticated() && this.auth.isEditMode()) {
            this.activateCollectionUI();
        }
        
        // Listen for auth state changes (assuming the auth object has events)
        // For now, we'll poll - in a real implementation we'd use events
        this.authCheckInterval = setInterval(() => {
            const shouldBeActive = this.auth.isAuthenticated() && this.auth.isEditMode();
            if (shouldBeActive && !this.hasCollectionUI()) {
                this.activateCollectionUI();
            } else if (!shouldBeActive && this.hasCollectionUI()) {
                this.deactivateCollectionUI();
            }
        }, 1000);
    }
    
    /**
     * Check if collection UI is currently active
     */
    hasCollectionUI() {
        return this.addButton && this.addButton.parentNode;
    }
    
    /**
     * Activate collection UI when in edit mode
     */
    activateCollectionUI() {
        console.log('✅ Activating collection UI');
        
        // Add visual indicator to container
        this.container.classList.add('insertr-collection-active');
        
        // Add the "+ Add" button (top right of container per spec)
        this.createAddButton();
        
        // Add control buttons to each existing item
        this.addControlsToExistingItems();
    }
    
    /**
     * Deactivate collection UI when not in edit mode
     */
    deactivateCollectionUI() {
        console.log('❌ Deactivating collection UI');
        
        // Remove visual indicator
        this.container.classList.remove('insertr-collection-active');
        
        // Remove add button
        if (this.addButton) {
            this.addButton.remove();
            this.addButton = null;
        }
        
        // Remove all item controls
        this.itemControls.forEach((controls, item) => {
            controls.remove();
        });
        this.itemControls.clear();
    }
    
    /**
     * Analyze existing children to detect template pattern
     */
    analyzeTemplate() {
        const children = Array.from(this.container.children);
        
        if (children.length === 0) {
            console.warn('⚠️ No children found for template analysis');
            return;
        }
        
        // Use first child as template baseline
        const firstChild = children[0];
        
        this.template = {
            structure: this.extractElementStructure(firstChild),
            editableFields: this.findEditableElements(firstChild),
            htmlTemplate: firstChild.outerHTML
        };
        
        console.log('📋 Template detected:', this.template);
        
        // Store reference to current items
        this.items = children.map((child, index) => ({
            element: child,
            index: index,
            id: this.generateItemId(index)
        }));
    }
    
    /**
     * Extract the structural pattern of an element
     */
    extractElementStructure(element) {
        return {
            tagName: element.tagName,
            classes: Array.from(element.classList),
            attributes: this.getRelevantAttributes(element),
            childStructure: this.analyzeChildStructure(element)
        };
    }
    
    /**
     * Get relevant attributes (excluding data-content-id which will be unique)
     */
    getRelevantAttributes(element) {
        const relevantAttrs = {};
        for (const attr of element.attributes) {
            if (attr.name !== 'data-content-id') {
                relevantAttrs[attr.name] = attr.value;
            }
        }
        return relevantAttrs;
    }
    
    /**
     * Analyze child structure for template replication
     */
    analyzeChildStructure(element) {
        return Array.from(element.children).map(child => ({
            tagName: child.tagName,
            classes: Array.from(child.classList),
            hasInsertrClass: child.classList.contains('insertr'),
            content: child.classList.contains('insertr') ? '' : child.textContent
        }));
    }
    
    /**
     * Find editable elements within a container
     */
    findEditableElements(container) {
        return Array.from(container.querySelectorAll('.insertr')).map(el => ({
            selector: this.generateRelativeSelector(el, container),
            type: this.determineFieldType(el),
            placeholder: this.generatePlaceholder(el)
        }));
    }
    
    /**
     * Generate a relative selector for an element within a container
     */
    generateRelativeSelector(element, container) {
        // Simple approach: use tag name and classes
        const tagName = element.tagName.toLowerCase();
        const classes = Array.from(element.classList).join('.');
        return classes ? `${tagName}.${classes}` : tagName;
    }
    
    /**
     * Determine the type of field for editing
     */
    determineFieldType(element) {
        const tagName = element.tagName.toLowerCase();
        if (tagName === 'a') return 'link';
        if (tagName === 'img') return 'image';
        return 'text';
    }
    
    /**
     * Generate placeholder text for empty fields
     */
    generatePlaceholder(element) {
        const tagName = element.tagName.toLowerCase();
        if (tagName === 'h1' || tagName === 'h2') return 'Enter heading...';
        if (tagName === 'blockquote') return 'Enter quote...';
        if (tagName === 'cite') return 'Enter author...';
        return 'Enter text...';
    }
    
    /**
     * Generate unique ID for new items
     */
    generateItemId(index) {
        return `item-${Date.now()}-${index}`;
    }
    
    /**
     * Create the "+ Add" button positioned in top right of container
     */
    createAddButton() {
        if (this.addButton) return; // Already exists
        
        this.addButton = document.createElement('button');
        this.addButton.className = 'insertr-add-btn';
        this.addButton.innerHTML = '+ Add Item';
        this.addButton.title = 'Add new item to collection';
        
        // Position in top right of container as per spec
        this.container.style.position = 'relative';
        
        this.addButton.addEventListener('click', (e) => {
            e.preventDefault();
            e.stopPropagation();
            this.addNewItem();
        });
        
        this.container.appendChild(this.addButton);
        console.log('➕ Add button created');
    }
    
    /**
     * Add control buttons to all existing items
     */
    addControlsToExistingItems() {
        this.items.forEach((item, index) => {
            this.addItemControls(item.element, index);
        });
    }
    
    /**
     * Add management controls to an item (remove, reorder)
     */
    addItemControls(itemElement, index) {
        if (this.itemControls.has(itemElement)) return; // Already has controls
        
        const controls = document.createElement('div');
        controls.className = 'insertr-item-controls';
        
        // Remove button (always present)
        const removeBtn = this.createControlButton('×', 'Remove item', () => 
            this.removeItem(itemElement)
        );
        
        // Move up button (if not first item)
        if (index > 0) {
            const upBtn = this.createControlButton('↑', 'Move up', () => 
                this.moveItem(itemElement, 'up')
            );
            controls.appendChild(upBtn);
        }
        
        // Move down button (if not last item)
        if (index < this.items.length - 1) {
            const downBtn = this.createControlButton('↓', 'Move down', () => 
                this.moveItem(itemElement, 'down')
            );
            controls.appendChild(downBtn);
        }
        
        controls.appendChild(removeBtn);
        
        // Position in top right corner of item as per spec
        itemElement.style.position = 'relative';
        itemElement.appendChild(controls);
        
        // Store reference
        this.itemControls.set(itemElement, controls);
        
        // Add hover behavior
        this.setupItemHoverBehavior(itemElement, controls);
    }
    
    /**
     * Create a control button
     */
    createControlButton(text, title, onClick) {
        const button = document.createElement('button');
        button.className = 'insertr-control-btn';
        button.textContent = text;
        button.title = title;
        button.addEventListener('click', (e) => {
            e.preventDefault();
            e.stopPropagation();
            onClick();
        });
        return button;
    }
    
    /**
     * Set up hover behavior for item controls
     */
    setupItemHoverBehavior(itemElement, controls) {
        itemElement.addEventListener('mouseenter', () => {
            controls.style.opacity = '1';
        });
        
        itemElement.addEventListener('mouseleave', () => {
            controls.style.opacity = '0';
        });
    }
    
    /**
     * Add a new item to the collection
     */
    addNewItem() {
        console.log('➕ Adding new item to collection');
        
        if (!this.template) {
            console.error('❌ No template available for creating new items');
            return;
        }
        
        // Create new item from template
        const newItem = this.createItemFromTemplate();
        
        // Add to DOM
        this.container.insertBefore(newItem, this.addButton);
        
        // Update items array
        const newItemData = {
            element: newItem,
            index: this.items.length,
            id: this.generateItemId(this.items.length)
        };
        this.items.push(newItemData);
        
        // Add controls to new item
        this.addItemControls(newItem, this.items.length - 1);
        
        // Re-initialize any .insertr elements in the new item
        // This allows the existing editor system to handle individual field editing
        this.initializeInsertrElements(newItem);
        
        // Update all item controls (indices may have changed)
        this.updateAllItemControls();
        
        console.log('✅ New item added successfully');
    }
    
    /**
     * Create a new item from the template
     */
    createItemFromTemplate() {
        // Create element from template HTML
        const tempContainer = document.createElement('div');
        tempContainer.innerHTML = this.template.htmlTemplate;
        const newItem = tempContainer.firstElementChild;
        
        // Clear content from editable fields
        this.template.editableFields.forEach(field => {
            const element = newItem.querySelector(field.selector);
            if (element) {
                this.clearElementContent(element, field.type);
                // Add placeholder text
                if (field.type === 'text') {
                    element.textContent = field.placeholder;
                    element.style.color = '#999';
                    element.style.fontStyle = 'italic';
                    
                    // Remove placeholder styling when user starts editing
                    element.addEventListener('focus', () => {
                        if (element.textContent === field.placeholder) {
                            element.textContent = '';
                            element.style.color = '';
                            element.style.fontStyle = '';
                        }
                    });
                }
            }
        });
        
        // Generate unique data-content-id for the item
        newItem.setAttribute('data-content-id', this.generateItemId(Date.now()));
        
        return newItem;
    }
    
    /**
     * Clear content from an element based on its type
     */
    clearElementContent(element, type) {
        if (type === 'link') {
            element.textContent = '';
            element.removeAttribute('href');
        } else if (type === 'image') {
            element.removeAttribute('src');
            element.removeAttribute('alt');
        } else {
            element.textContent = '';
        }
    }
    
    /**
     * Initialize .insertr elements within a new item
     * This integrates with the existing editing system
     */
    initializeInsertrElements(container) {
        const insertrElements = container.querySelectorAll('.insertr');
        insertrElements.forEach(element => {
            // Add click handler for editing (same as existing system)
            element.addEventListener('click', (e) => {
                // Only allow editing if authenticated and in edit mode
                if (!this.auth.isAuthenticated() || !this.auth.isEditMode()) {
                    return;
                }
                
                e.preventDefault();
                e.stopPropagation();
                
                // Use the existing form renderer
                const formRenderer = new InsertrFormRenderer(this.apiClient);
                const meta = {
                    contentId: element.getAttribute('data-content-id'),
                    element: element,
                    htmlMarkup: element.outerHTML
                };
                const currentContent = this.extractCurrentContent(element);
                
                formRenderer.showEditForm(
                    meta,
                    currentContent,
                    (formData) => this.handleItemSave(meta, formData),
                    () => formRenderer.closeForm()
                );
            });
        });
    }
    
    /**
     * Extract current content (simplified version of editor.js method)
     */
    extractCurrentContent(element) {
        if (element.tagName.toLowerCase() === 'a') {
            return {
                text: element.textContent.trim(),
                url: element.getAttribute('href') || ''
            };
        }
        return element.textContent.trim();
    }
    
    /**
     * Handle saving of individual item content
     */
    async handleItemSave(meta, formData) {
        console.log('💾 Saving item content:', meta.contentId, formData);
        
        try {
            let contentValue;
            if (typeof formData === 'string') {
                contentValue = formData;
            } else if (formData.content) {
                contentValue = formData.content;
            } else if (formData.text) {
                contentValue = formData.text;
            } else {
                contentValue = formData;
            }
            
            let result;
            if (meta.contentId) {
                result = await this.apiClient.updateContent(meta.contentId, contentValue);
            } else {
                result = await this.apiClient.createContent(contentValue, meta.htmlMarkup);
            }
            
            if (result) {
                meta.element.setAttribute('data-content-id', result.id);
                console.log(`✅ Item content saved: ${result.id}`);
            } else {
                console.error('❌ Failed to save item content to server');
            }
            
        } catch (error) {
            console.error('❌ Error saving item content:', error);
        }
    }
    
    /**
     * Remove an item from the collection
     */
    removeItem(itemElement) {
        if (!confirm('Are you sure you want to remove this item?')) {
            return;
        }
        
        console.log('🗑️ Removing item from collection');
        
        // Remove controls
        const controls = this.itemControls.get(itemElement);
        if (controls) {
            controls.remove();
            this.itemControls.delete(itemElement);
        }
        
        // Remove from items array
        this.items = this.items.filter(item => item.element !== itemElement);
        
        // Remove from DOM
        itemElement.remove();
        
        // Update all item controls (indices changed)
        this.updateAllItemControls();
        
        console.log('✅ Item removed successfully');
    }
    
    /**
     * Move an item up or down in the collection
     */
    moveItem(itemElement, direction) {
        console.log(`🔄 Moving item ${direction}`);
        
        const currentIndex = this.items.findIndex(item => item.element === itemElement);
        if (currentIndex === -1) return;
        
        let newIndex;
        if (direction === 'up' && currentIndex > 0) {
            newIndex = currentIndex - 1;
        } else if (direction === 'down' && currentIndex < this.items.length - 1) {
            newIndex = currentIndex + 1;
        } else {
            return; // Can't move in that direction
        }
        
        // Get the target position in DOM
        const targetItem = this.items[newIndex];
        
        // Move in DOM
        if (direction === 'up') {
            this.container.insertBefore(itemElement, targetItem.element);
        } else {
            this.container.insertBefore(itemElement, targetItem.element.nextSibling);
        }
        
        // Update items array
        [this.items[currentIndex], this.items[newIndex]] = [this.items[newIndex], this.items[currentIndex]];
        this.items[currentIndex].index = currentIndex;
        this.items[newIndex].index = newIndex;
        
        // Update all item controls
        this.updateAllItemControls();
        
        console.log('✅ Item moved successfully');
    }
    
    /**
     * Update controls for all items (called after reordering)
     */
    updateAllItemControls() {
        // Remove all existing controls
        this.itemControls.forEach((controls, item) => {
            controls.remove();
        });
        this.itemControls.clear();
        
        // Re-add controls with correct up/down button states
        this.items.forEach((item, index) => {
            this.addItemControls(item.element, index);
        });
    }
    
    /**
     * Cleanup when the collection manager is destroyed
     */
    destroy() {
        if (this.authCheckInterval) {
            clearInterval(this.authCheckInterval);
        }
        
        this.deactivateCollectionUI();
        this.isActive = false;
        
        console.log('🧹 CollectionManager destroyed');
    }
}