/**
 * @fileoverview Manages the file view functionality for the room interface.
 * This file handles:
 * - Grid and list view rendering
 * - File sorting and organization
 * - Breadcrumb navigation
 * - File action buttons
 * - Multi-select functionality
 */

/**
 * @class ViewManager
 * @classdesc Manages the visual representation and interaction of files in the room interface.
 * Handles view switching, file rendering, sorting, and UI updates.
 */
import { FilePreview } from '../components/filePreview.js';

export class ViewManager {
    /**
     * Creates a new ViewManager instance.
     * @param {RoomManager} roomManager - The parent RoomManager instance
     */
    constructor(roomManager) {
        console.log('[ViewManager] Initializing...');
        this.roomManager = roomManager;
        this.currentView = 'grid';
        this.sortColumn = 'name';
        this.sortDirection = 'asc';
        this.filePreview = new FilePreview({
            containerId: 'filePreviewModal',
            onClose: () => {
                // Clean up any resources if needed
            }
        });
        console.log('[ViewManager] Initialized with roomManager:', roomManager);
    }
    
    /**
     * Initializes the view with user preferences.
     * Fetches and applies the user's preferred view type.
     * @async
     */
    async initializeView() {
        console.log('[ViewManager] Initializing view...');
        try {
            const response = await fetch('/api/user/preferred_view');
            console.log('[ViewManager] Preferences response status:', response.status);
            
            if (response.ok) {
                const data = await response.json();
                console.log('[ViewManager] User preferences:', data);
                this.currentView = data.preferred_view || 'grid';
            }
            
            this.toggleView(this.currentView);
            console.log('[ViewManager] View initialized with:', this.currentView);
        } catch (error) {
            console.error('[ViewManager] Error initializing view:', error);
            this.currentView = 'grid';
            this.toggleView('grid');
        }
    }
    
    /**
     * Toggles between grid and list views.
     * Updates UI and saves user preference.
     * @async
     * @param {string} view - The view type to switch to ('grid' or 'list')
     */
    async toggleView(view) {
        console.log('[ViewManager] Toggling view to:', view);
        this.currentView = view;
        
        // Update UI
        document.getElementById('gridViewBtn').classList.toggle('active', view === 'grid');
        document.getElementById('listViewBtn').classList.toggle('active', view === 'list');
        document.getElementById('fileGrid').classList.toggle('list-view', view === 'list');
        
        // Save preference
        try {
            const response = await fetch('/api/user/preferred_view', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
                },
                body: JSON.stringify({ preferred_view: view })
            });
            console.log('[ViewManager] Save preferences response status:', response.status);
        } catch (error) {
            console.error('[ViewManager] Error saving view preference:', error);
        }
        
        // Re-render files if we have any
        if (this.roomManager.fileManager.currentFiles.length > 0) {
            console.log('[ViewManager] Re-rendering files with new view');
            await this.renderFiles(this.roomManager.fileManager.currentFiles);
        }
    }
    
    /**
     * Renders the file list in the current view mode.
     * @async
     * @param {Array<Object>} files - Array of file objects to render
     */
    async renderFiles(files) {
        console.log('[ViewManager] Rendering files:', files);
        const fileGrid = document.getElementById('fileGrid');
        
        if (!files || files.length === 0) {
            console.log('[ViewManager] No files to render');
            fileGrid.innerHTML = '<div class="col"><div class="text-muted">No files in this folder</div></div>';
            return;
        }

        // Sort files
        const sortedFiles = this.sortFiles(files);
        console.log('[ViewManager] Sorted files:', sortedFiles);

        if (this.currentView === 'list') {
            console.log('[ViewManager] Rendering list view');
            await this.renderListView(sortedFiles);
        } else {
            console.log('[ViewManager] Rendering grid view');
            await this.renderGridView(sortedFiles);
        }
    }
    
    /**
     * Renders the breadcrumb navigation.
     * Shows the current path and provides navigation controls.
     */
    renderBreadcrumb() {
        console.log('[ViewManager] Rendering breadcrumb');
        const breadcrumb = document.getElementById('breadcrumb');
        const upBtn = document.getElementById('upBtn');
        const path = this.roomManager.currentPath;
        
        // Always show the root node
        let html = `
            <span class="d-flex align-items-center">
                <a href="?path=" class="text-decoration-none" style="color: var(--primary-color);">
                    <i class="fas fa-home"></i>
                </a>
            </span>
        `;

        if (!path) {
            console.log('[ViewManager] No path, showing only root');
            breadcrumb.innerHTML = html;
            upBtn.style.display = 'none';
            return;
        }

        console.log('[ViewManager] Building breadcrumb for path:', path);
        const parts = path.split('/').filter(Boolean);
        let currentPath = '';

        parts.forEach((part, index) => {
            currentPath += '/' + part;
            html += `
                <span class="d-flex align-items-center">
                    <i class="fas fa-chevron-right mx-2" style="color: var(--secondary-color);"></i>
                    <a href="?path=${encodeURIComponent(currentPath)}" class="text-decoration-none" 
                       style="color: var(--primary-color);"
                       onmouseover="this.style.color='var(--primary-light)'"
                       onmouseout="this.style.color='var(--primary-color)'">
                        ${part}
                    </a>
                </span>
            `;
        });

        breadcrumb.innerHTML = html;
        upBtn.style.display = 'inline-block';
        upBtn.onclick = () => this.roomManager.navigateToParent();
        upBtn.style.color = 'var(--primary-color)';
        upBtn.style.borderColor = 'var(--primary-color)';
        upBtn.onmouseover = () => {
            upBtn.style.backgroundColor = 'var(--primary-color)';
            upBtn.style.color = 'white';
        };
        upBtn.onmouseout = () => {
            upBtn.style.backgroundColor = 'transparent';
            upBtn.style.color = 'var(--primary-color)';
        };
        console.log('[ViewManager] Breadcrumb rendered');
    }
    
    /**
     * Renders the file list in list view mode.
     * @async
     * @param {Array<Object>} files - Array of file objects to render
     */
    async renderListView(files) {
        console.log('[ViewManager] Rendering list view');
        const fileGrid = document.getElementById('fileGrid');
        
        // Create table structure
        let html = `
            <table class="table table-hover">
                <thead>
                    <tr>
                        <th style="width: 40px;">
                            <input type="checkbox" class="form-check-input select-all-checkbox" style="margin: 0;">
                        </th>
                        <th style="width: 40px;"></th>
                        <th>Name</th>
                        <th>Size</th>
                        <th>Modified</th>
                        <th style="width: 100px;">Actions</th>
                    </tr>
                </thead>
                <tbody>
        `;

        files.forEach((file, index) => {
            console.log('[ViewManager] Rendering list item:', file);
            html += this.renderFileRow(file, index);
        });

        html += '</tbody></table>';
        fileGrid.innerHTML = html;
        console.log('[ViewManager] List view rendered');
    }
    
    /**
     * Renders the file list in grid view mode.
     * @async
     * @param {Array<Object>} files - Array of file objects to render
     */
    async renderGridView(files) {
        console.log('[ViewManager] Rendering grid view');
        const fileGrid = document.getElementById('fileGrid');
        let html = `
            <div class="col-12 mb-3">
                <div class="d-flex align-items-center">
                    <input type="checkbox" class="form-check-input select-all-checkbox me-2" style="margin: 0;">
                    <span class="text-muted">Select All</span>
                </div>
            </div>
        `;

        files.forEach((file, index) => {
            console.log('[ViewManager] Rendering grid item:', file);
            html += this.renderFileCard(file, index);
        });

        fileGrid.innerHTML = html;
        console.log('[ViewManager] Grid view rendered');
    }
    
    /**
     * Renders a single file row for list view.
     * @param {Object} file - The file object to render
     * @param {number} index - The index of the file in the list
     * @returns {string} HTML string for the file row
     */
    renderFileRow(file, index) {
        console.log('[ViewManager] Rendering file row:', { file, index });
        const isFolder = file.type === 'folder';
        const icon = isFolder ? 'fa-folder' : this.getFileIcon(file.name);
        const size = isFolder ? '-' : this.formatFileSize(file.size);
        const modified = new Date(file.modified).toLocaleString();

        // Create file name element
        const name = document.createElement('span');
        name.className = 'file-name';
        name.textContent = file.displayName || file.name;

        return `
            <tr data-index="${index}" class="file-row" style="cursor: pointer;" 
                onclick="window.roomManager.fileManager.updateSelection(${index}, event)"
                ondblclick="${isFolder ? `window.roomManager.navigateToFolder('${file.name}')` : ''}">
                <td>
                    <input type="checkbox" class="form-check-input select-item-checkbox" 
                           data-index="${index}" style="margin: 0;"
                           onclick="event.stopPropagation(); window.roomManager.fileManager.updateSelection(${index}, event)">
                </td>
                <td>
                    <i class="fas ${icon}" style="font-size:1.5rem;color:${isFolder ? 'var(--primary-color)' : 'var(--secondary-color)'}"></i>
                </td>
                <td>
                    ${name.outerHTML}
                </td>
                <td class="text-muted">${size}</td>
                <td class="text-muted">${modified}</td>
                <td>
                    <div class="d-flex justify-content-end gap-1">
                        ${this.renderFileActions(file, index)}
                    </div>
                </td>
            </tr>
        `;
    }
    
    /**
     * Renders a single file card for grid view.
     * @param {Object} file - The file object to render
     * @param {number} index - The index of the file in the list
     * @returns {string} HTML string for the file card
     */
    renderFileCard(file, index) {
        console.log('[ViewManager] Rendering file card:', { file, index });
        const isFolder = file.type === 'folder';
        const icon = isFolder ? 'fa-folder' : this.getFileIcon(file.name);
        const size = isFolder ? '-' : this.formatFileSize(file.size);
        const modified = new Date(file.modified).toLocaleString();

        // Create file name element
        const name = document.createElement('span');
        name.className = 'file-name';
        name.textContent = file.displayName || file.name;

        return `
            <div class="col-12 col-sm-6 col-md-4 col-lg-3 mb-3">
                <div class="card file-card h-100 border-0 shadow-sm position-relative" 
                     data-index="${index}" 
                     onclick="window.roomManager.fileManager.updateSelection(${index}, event)"
                     ondblclick="${isFolder ? `window.roomManager.navigateToFolder('${file.name}')` : ''}">
                    <div class="card-body d-flex flex-column align-items-center justify-content-center text-center p-4">
                        <div class="mb-2 w-100 d-flex justify-content-start">
                            <input type="checkbox" class="form-check-input select-item-checkbox" 
                                   data-index="${index}" style="margin: 0;"
                                   onclick="event.stopPropagation(); window.roomManager.fileManager.updateSelection(${index}, event)">
                        </div>
                        <div class="mb-2">
                            <i class="fas ${icon}" style="font-size:2.5rem;color:${isFolder ? 'var(--primary-color)' : 'var(--secondary-color)'};"></i>
                        </div>
                        <div class="fw-bold file-name-ellipsis mb-1" title="${file.name}">${name.outerHTML}</div>
                        <div class="text-muted" style="font-size:0.85rem;">${modified}</div>
                        <div class="text-muted mb-2" style="font-size:0.85rem;">${size}</div>
                    </div>
                    <div class="card-footer bg-white border-0 d-flex justify-content-center gap-2">
                        ${this.renderFileActions(file, index)}
                    </div>
                </div>
            </div>
        `;
    }
    
    /**
     * Renders the action buttons for a file.
     * @param {Object} file - The file object
     * @param {number} index - The index of the file in the list
     * @returns {string} HTML string for the action buttons
     */
    renderFileActions(file, index) {
        const actions = [];

        // Check if file can be previewed
        const extension = file.name.split('.').pop().toLowerCase();
        const previewableExtensions = [
            'pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx',
            'txt', 'md', 'csv', 'py', 'js', 'html', 'css', 'json', 'xml', 'sql', 'sh', 'bat',
            'jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'webp', 'tiff',
            'mp3', 'mp4', 'webm', 'avi', 'mov', 'wmv', 'flv', 'mkv'
        ];

        if (previewableExtensions.includes(extension)) {
            // Add preview button for previewable files
            actions.push(`
                <button class="btn btn-sm file-action-btn" title="Preview" onclick="window.roomManager.viewManager.previewFile(${index})"
                    style="background-color:var(--primary-opacity-8);color:var(--primary-color);">
                    <i class="fas fa-eye"></i>
                </button>
            `);
        } else {
            // Add details button for non-previewable files
            actions.push(`
                <button class="btn btn-sm file-action-btn" title="Details" onclick="window.roomManager.modalManager.showDetailsModal('${file.name}', '${file.path || ''}')"
                    style="background-color:var(--primary-opacity-8);color:var(--primary-color);">
                    <i class="fas fa-info-circle"></i>
                </button>
            `);
        }

        // Add download button if user has permission
        if (this.roomManager.canDownload) {
            actions.push(`
                <button class="btn btn-sm file-action-btn" title="Download" onclick="window.roomManager.fileManager.downloadFile('${file.name}', '${file.path || ''}')"
                    style="background-color:var(--primary-opacity-8);color:var(--primary-color);">
                    <i class="fas fa-download"></i>
                </button>
            `);
        }

        // Add rename button if user has permission
        if (this.roomManager.canRename) {
            actions.push(`
                <button class="btn btn-sm file-action-btn" title="Rename" onclick="window.roomManager.modalManager.showRenameModal('${file.name}', '${file.path || ''}')"
                    style="background-color:var(--primary-opacity-8);color:var(--primary-color);">
                    <i class="fas fa-pen"></i>
                </button>
            `);
        }

        // Add move button if user has permission
        if (this.roomManager.canMove) {
            actions.push(`
                <button class="btn btn-sm file-action-btn" title="Move" onclick="window.roomManager.modalManager.showMoveModal('${file.name}', '${file.path || ''}')"
                    style="background-color:var(--primary-opacity-8);color:var(--primary-color);">
                    <i class="fas fa-arrows-alt"></i>
                </button>
            `);
        }

        // Add star button
        actions.push(`
            <button class="btn btn-sm file-action-btn" title="${file.starred ? 'Unstar' : 'Star'}" 
                onclick="window.roomManager.fileManager.toggleStar('${file.name}', '${file.path || ''}')"
                style="background-color:${file.starred ? 'var(--warning-opacity-15)' : 'var(--primary-opacity-8)'};color:${file.starred ? 'var(--warning-color)' : 'var(--primary-color)'};">
                <i class="fas fa-star"></i>
            </button>
        `);

        // Add delete button if user has permission
        if (this.roomManager.canDelete) {
            actions.push(`
                <button class="btn btn-sm file-action-btn" title="Delete" onclick="window.roomManager.modalManager.showDeleteModal('${file.name}', '${file.path || ''}')"
                    style="background-color:var(--danger-opacity-15);color:var(--danger-color);">
                    <i class="fas fa-trash"></i>
                </button>
            `);
        }

        return actions.join('');
    }
    
    /**
     * Sorts the file list based on current sort settings.
     * @param {Array<Object>} files - Array of file objects to sort
     * @returns {Array<Object>} Sorted array of file objects
     */
    sortFiles(files) {
        console.log('[ViewManager] Sorting files:', { 
            column: this.sortColumn, 
            direction: this.sortDirection 
        });
        
        return [...files].sort((a, b) => {
            let comparison = 0;
            
            if (this.sortColumn === 'name') {
                comparison = a.name.localeCompare(b.name);
            } else if (this.sortColumn === 'size') {
                comparison = (a.size || 0) - (b.size || 0);
            } else if (this.sortColumn === 'modified') {
                comparison = new Date(a.modified) - new Date(b.modified);
            }
            
            return this.sortDirection === 'asc' ? comparison : -comparison;
        });
    }
    
    /**
     * Gets the appropriate icon class for a file based on its extension.
     * @param {string} filename - The name of the file
     * @returns {string} Font Awesome icon class name
     */
    getFileIcon(filename) {
        const extension = filename.split('.').pop().toLowerCase();
        console.log('[ViewManager] Getting icon for file:', { filename, extension });
        
        const iconMap = {
            pdf: 'fa-file-pdf',
            doc: 'fa-file-word',
            docx: 'fa-file-word',
            xls: 'fa-file-excel',
            xlsx: 'fa-file-excel',
            ppt: 'fa-file-powerpoint',
            pptx: 'fa-file-powerpoint',
            txt: 'fa-file-alt',
            jpg: 'fa-file-image',
            jpeg: 'fa-file-image',
            png: 'fa-file-image',
            gif: 'fa-file-image',
            zip: 'fa-file-archive',
            rar: 'fa-file-archive',
            mp3: 'fa-file-audio',
            mp4: 'fa-file-video'
        };
        
        return iconMap[extension] || 'fa-file';
    }
    
    /**
     * Formats a file size in bytes to a human-readable string.
     * @param {number} bytes - The file size in bytes
     * @returns {string} Formatted file size string
     */
    formatFileSize(bytes) {
        if (!bytes) return '0 B';
        
        const units = ['B', 'KB', 'MB', 'GB', 'TB'];
        let size = bytes;
        let unitIndex = 0;
        
        while (size >= 1024 && unitIndex < units.length - 1) {
            size /= 1024;
            unitIndex++;
        }
        
        return `${size.toFixed(1)} ${units[unitIndex]}`;
    }
    
    /**
     * Updates the multi-select UI based on current selection state.
     */
    updateMultiSelectUI() {
        console.log('[ViewManager] Updating multi-select UI');
        const selectedItems = this.roomManager.fileManager.getSelectedItems();
        const hasSelection = selectedItems.length > 0;
        
        document.getElementById('downloadSelectedBtn').style.display = 
            hasSelection && this.roomManager.canDownload ? 'flex' : 'none';
        document.getElementById('deleteSelectedBtn').style.display = 
            hasSelection && this.roomManager.canDelete ? 'flex' : 'none';
            
        console.log('[ViewManager] Multi-select UI updated:', { 
            hasSelection, 
            selectedCount: selectedItems.length 
        });
    }

    async previewFile(index) {
        const file = this.roomManager.fileManager.currentFiles[index];
        if (!file) return;

        const fileUrl = `/api/rooms/${this.roomManager.roomId}/files/${encodeURIComponent(file.name)}?path=${encodeURIComponent(file.path || '')}&preview=true`;
        
        await this.filePreview.previewFile({
            name: file.name,
            url: fileUrl
        });
    }
} 