import { modalManager } from './ModalManager.js';
import { LoadingManager } from './LoadingManager.js';
import { ImportStepManager } from './import/ImportStepManager.js';
import { ImageProcessor } from './import/ImageProcessor.js';
import { RecipeDataManager } from './import/RecipeDataManager.js';
import { DownloadManager } from './import/DownloadManager.js';
import { FolderTreeManager } from '../components/FolderTreeManager.js';
import { formatFileSize } from '../utils/formatters.js';
import { getStorageItem, setStorageItem } from '../utils/storageHelpers.js';
import { getModelApiClient } from '../api/modelApiFactory.js';
import { state } from '../state/index.js';
import { MODEL_TYPES } from '../api/apiConfig.js';
import { showToast } from '../utils/uiHelpers.js';
import { translate } from '../utils/i18nHelpers.js';

export class ImportManager {
    constructor() {
        // Core state properties
        this.recipeImage = null;
        this.recipeData = null;
        this.recipeName = '';
        this.recipeTags = [];
        this.missingLoras = [];
        this.initialized = false;
        this.selectedFolder = '';
        this.downloadableLoRAs = [];
        this.recipeId = null;
        this.importMode = null; // Set by input handlers: 'url' or 'upload'
        this.useDefaultPath = false;
        this.apiClient = null;

        // Initialize sub-managers
        this.loadingManager = new LoadingManager();
        this.stepManager = new ImportStepManager();
        this.imageProcessor = new ImageProcessor(this);
        this.recipeDataManager = new RecipeDataManager(this);
        this.downloadManager = new DownloadManager(this);
        this.folderTreeManager = new FolderTreeManager();

        // Bind methods
        this.formatFileSize = formatFileSize;
        this.updateTargetPath = this.updateTargetPath.bind(this);
        this.handleToggleDefaultPath = this.toggleDefaultPath.bind(this);
    }

    showImportModal(recipeData = null, recipeId = null) {
        if (!this.initialized) {
            const modal = document.getElementById('importModal');
            if (!modal) {
                console.error('Import modal element not found');
                return;
            }
            this.initializeEventHandlers();
            this.initialized = true;
        }

        // Get API client for LoRAs
        this.apiClient = getModelApiClient(MODEL_TYPES.LORA);

        // Reset state
        this.resetSteps();
        if (recipeData) {
            this.downloadableLoRAs = recipeData.loras;
            this.recipeId = recipeId;
        }

        // Show modal
        modalManager.showModal('importModal', null, () => {
            console.log('[RecipeImport] Import modal closed.');
            this.cleanupFolderBrowser();
            this.stepManager.removeInjectedStyles();
        });

        console.log(
            `[RecipeImport] Import modal opened (${recipeData ? 'download-missing-loras mode' : 'new import'}).`
        );

        // Verify visibility and focus on the URL input (primary mode)
        setTimeout(() => {
            const urlInput = document.getElementById('imageUrlInput');
            if (urlInput) {
                urlInput.focus();
            }
        }, 50);
    }

    initializeEventHandlers() {
        // Default path toggle handler
        const useDefaultPathToggle = document.getElementById('importUseDefaultPath');
        if (useDefaultPathToggle) {
            useDefaultPathToggle.addEventListener('change', this.handleToggleDefaultPath);
        }

        const modal = document.getElementById('importModal');
        const dropZone = document.getElementById('importDropZone');
        const fileInput = document.getElementById('recipeImageUpload');
        const urlInput = document.getElementById('imageUrlInput');

        // Submit URL with Enter
        if (urlInput) {
            urlInput.addEventListener('keydown', (event) => {
                if (event.key === 'Enter') {
                    event.preventDefault();
                    this.handleUrlInput();
                }
            });
        }

        if (dropZone && fileInput) {
            // Click or keyboard activation opens the file picker
            dropZone.addEventListener('click', () => fileInput.click());
            dropZone.addEventListener('keydown', (event) => {
                if (event.key === 'Enter' || event.key === ' ') {
                    event.preventDefault();
                    fileInput.click();
                }
            });

            // Drag & drop
            dropZone.addEventListener('dragover', (event) => {
                event.preventDefault();
                dropZone.classList.add('drag-over');
            });
            dropZone.addEventListener('dragleave', () => {
                dropZone.classList.remove('drag-over');
            });
            dropZone.addEventListener('drop', (event) => {
                event.preventDefault();
                dropZone.classList.remove('drag-over');
                const file = event.dataTransfer?.files?.[0];
                if (file) {
                    this.imageProcessor.handleDroppedFile(file);
                }
            });
        }

        // Paste an image from clipboard while the modal is open
        if (modal) {
            modal.addEventListener('paste', (event) => {
                if (this.stepManager.currentStep !== 'uploadStep') return;
                const file = Array.from(event.clipboardData?.files || [])
                    .find(f => f.type.startsWith('image/'));
                if (file) {
                    event.preventDefault();
                    this.imageProcessor.handleDroppedFile(file);
                }
            });
        }
    }

    resetSteps() {
        // Clear UI state
        this.stepManager.removeInjectedStyles();
        this.stepManager.showStep('uploadStep');

        // Reset form inputs
        const fileInput = document.getElementById('recipeImageUpload');
        if (fileInput) fileInput.value = '';

        const urlInput = document.getElementById('imageUrlInput');
        if (urlInput) urlInput.value = '';

        const uploadError = document.getElementById('uploadError');
        if (uploadError) uploadError.textContent = '';

        const importUrlError = document.getElementById('importUrlError');
        if (importUrlError) importUrlError.textContent = '';

        const recipeName = document.getElementById('recipeName');
        if (recipeName) recipeName.value = '';

        const tagsContainer = document.getElementById('tagsContainer');
        if (tagsContainer) tagsContainer.innerHTML = `<div class="empty-tags">${translate('recipes.controls.import.noTagsAdded', {}, 'No tags added')}</div>`;

        // Clear folder path input
        const folderPathInput = document.getElementById('importFolderPath');
        if (folderPathInput) {
            folderPathInput.value = '';
        }

        // Reset state variables
        this.recipeImage = null;
        this.recipeData = null;
        this.recipeName = '';
        this.recipeTags = [];
        this.missingLoras = [];
        this.downloadableLoRAs = [];
        this.selectedFolder = '';

        // Import mode is set by the input handlers ('url' or 'upload')
        this.importMode = null;

        // Reset drop zone filename feedback
        this.updateSelectedFileName(null);

        // Clear folder tree selection
        if (this.folderTreeManager) {
            this.folderTreeManager.clearSelection();
        }

        // Reset default path toggle
        this.loadDefaultPathSetting();

        // Reset duplicate related properties
        this.duplicateRecipes = [];

        // Reset button visibility in location step
        this.resetLocationStepButtons();
    }

    resetLocationStepButtons() {
        // Reset buttons to default state
        const locationStep = document.getElementById('locationStep');
        if (!locationStep) return;
        
        const backBtn = locationStep.querySelector('.secondary-btn');
        const primaryBtn = locationStep.querySelector('.primary-btn');
        
        // Back button - show
        if (backBtn) {
            backBtn.style.display = 'inline-block';
        }
        
        // Primary button - reset text
        if (primaryBtn) {
            primaryBtn.textContent = translate('recipes.controls.import.downloadAndSaveRecipe', {}, 'Download & Save Recipe');
        }
    }

    /**
     * Show the selected file name in the drop zone, or restore the default
     * hint text when called with null.
     */
    updateSelectedFileName(fileName) {
        const nameEl = document.getElementById('selectedFileName');
        const hintEl = document.getElementById('dropZonePrimaryText');
        if (!nameEl || !hintEl) return;

        if (fileName) {
            nameEl.textContent = fileName;
            nameEl.style.display = 'block';
            hintEl.style.display = 'none';
        } else {
            nameEl.textContent = '';
            nameEl.style.display = 'none';
            hintEl.style.display = '';
        }
    }

    handleImageUpload(event) {
        this.imageProcessor.handleFileUpload(event);
    }

    async handleUrlInput() {
        await this.imageProcessor.handleUrlInput();
    }

    async uploadAndAnalyzeImage() {
        await this.imageProcessor.uploadAndAnalyzeImage();
    }

    showRecipeDetailsStep() {
        this.recipeDataManager.showRecipeDetailsStep();
    }

    handleRecipeNameChange(event) {
        this.recipeName = event.target.value.trim();
    }

    addTag() {
        this.recipeDataManager.addTag();
    }

    removeTag(tag) {
        this.recipeDataManager.removeTag(tag);
    }

    proceedFromDetails() {
        this.recipeDataManager.proceedFromDetails();
    }

    async proceedToLocation() {
        this.stepManager.showStep('locationStep');

        try {
            // Fetch LoRA roots
            const rootsData = await this.apiClient.fetchModelRoots();
            const loraRoot = document.getElementById('importLoraRoot');
            loraRoot.innerHTML = rootsData.roots.map(root =>
                `<option value="${root}">${root}</option>`
            ).join('');

            // Set default root if available
            const defaultRootKey = 'default_lora_root';
            const defaultRoot = state.global.settings[defaultRootKey];
            if (defaultRoot && rootsData.roots.includes(defaultRoot)) {
                loraRoot.value = defaultRoot;
            }

            // Set autocomplete="off" on folderPath input
            const folderPathInput = document.getElementById('importFolderPath');
            if (folderPathInput) {
                folderPathInput.setAttribute('autocomplete', 'off');
            }

            // Setup folder tree manager
            this.folderTreeManager.init({
                elementsPrefix: 'import',
                onPathChange: (path) => {
                    this.selectedFolder = path;
                    this.updateTargetPath();
                }
            });

            // Initialize folder tree
            await this.initializeFolderTree();

            // Setup lora root change handler
            loraRoot.addEventListener('change', async () => {
                await this.initializeFolderTree();
                this.updateTargetPath();
            });

            // Load default path setting for LoRAs
            this.loadDefaultPathSetting();

            this.updateTargetPath();

            // Update download button with missing LoRA count (if any)
            if (this.missingLoras && this.missingLoras.length > 0) {
                this.updateDownloadButtonCount();
                this.updateImportButtonsVisibility(true);
            } else {
                this.updateImportButtonsVisibility(false);
            }
        } catch (error) {
            showToast('toast.recipes.importFailed', { message: error.message }, 'error');
        }
    }

    updateImportButtonsVisibility(hasMissingLoras) {
        // Update primary button text based on whether there are missing LoRAs
        const locationStep = document.getElementById('locationStep');
        if (!locationStep) return;
        
        const backBtn = locationStep.querySelector('.secondary-btn');
        const primaryBtn = locationStep.querySelector('.primary-btn');
        
        // Back button - always show
        if (backBtn) {
            backBtn.style.display = 'inline-block';
        }
        
        // Update primary button text
        if (primaryBtn) {
            const downloadCountSpan = locationStep.querySelector('#downloadLoraCount');
            if (hasMissingLoras) {
                // Rebuild button content to ensure proper structure
                const buttonText = translate('recipes.controls.import.importAndDownload', {}, 'Import & Download');
                primaryBtn.innerHTML = `${buttonText} <span id="downloadLoraCount"></span>`;
            } else {
                primaryBtn.textContent = translate('recipes.controls.import.downloadAndSaveRecipe', {}, 'Download & Save Recipe');
            }
        }
    }

    updateDownloadButtonCount() {
        // Update the download count badge on the primary button
        const locationStep = document.getElementById('locationStep');
        if (!locationStep) return;
        
        const downloadCountSpan = locationStep.querySelector('#downloadLoraCount');
        if (downloadCountSpan) {
            const missingCount = this.missingLoras?.length || 0;
            downloadCountSpan.textContent = missingCount > 0 ? `(${missingCount})` : '';
        }
    }

    backToUpload() {
        this.stepManager.showStep('uploadStep');

        // Reset file input
        const fileInput = document.getElementById('recipeImageUpload');
        if (fileInput) fileInput.value = '';

        // Reset URL input
        const urlInput = document.getElementById('imageUrlInput');
        if (urlInput) urlInput.value = '';

        // Reset drop zone filename feedback
        this.updateSelectedFileName(null);

        // Clear error messages
        const uploadError = document.getElementById('uploadError');
        if (uploadError) uploadError.textContent = '';

        const importUrlError = document.getElementById('importUrlError');
        if (importUrlError) importUrlError.textContent = '';
    }

    backToDetails() {
        this.stepManager.showStep('detailsStep');
    }

    async saveRecipe() {
        await this.downloadManager.saveRecipe();
    }

    loadDefaultPathSetting() {
        const storageKey = 'use_default_path_loras';
        this.useDefaultPath = getStorageItem(storageKey, false);

        const toggleInput = document.getElementById('importUseDefaultPath');
        if (toggleInput) {
            toggleInput.checked = this.useDefaultPath;
            this.updatePathSelectionUI();
        }
    }

    toggleDefaultPath(event) {
        this.useDefaultPath = event.target.checked;

        // Save to localStorage for LoRAs
        const storageKey = 'use_default_path_loras';
        setStorageItem(storageKey, this.useDefaultPath);

        this.updatePathSelectionUI();
        this.updateTargetPath();
    }

    updatePathSelectionUI() {
        const manualSelection = document.getElementById('importManualPathSelection');

        // Always show manual path selection, but disable/enable based on useDefaultPath
        if (manualSelection) {
            manualSelection.style.display = 'block';
            if (this.useDefaultPath) {
                manualSelection.classList.add('disabled');
                // Disable all inputs and buttons inside manualSelection
                manualSelection.querySelectorAll('input, select, button').forEach(el => {
                    el.disabled = true;
                    el.tabIndex = -1;
                });
            } else {
                manualSelection.classList.remove('disabled');
                manualSelection.querySelectorAll('input, select, button').forEach(el => {
                    el.disabled = false;
                    el.tabIndex = 0;
                });
            }
        }

        // Always update the main path display
        this.updateTargetPath();
    }

    async initializeFolderTree() {
        try {
            // Fetch unified folder tree
            const treeData = await this.apiClient.fetchUnifiedFolderTree();

            if (treeData.success) {
                // Load tree data into folder tree manager
                await this.folderTreeManager.loadTree(treeData.tree);
            } else {
                console.error('Failed to fetch folder tree:', treeData.error);
                showToast('toast.recipes.folderTreeFailed', {}, 'error');
            }
        } catch (error) {
            console.error('Error initializing folder tree:', error);
            showToast('toast.recipes.folderTreeError', {}, 'error');
        }
    }

    cleanupFolderBrowser() {
        if (this.folderTreeManager) {
            this.folderTreeManager.destroy();
        }
    }

    updateTargetPath() {
        const pathDisplay = document.getElementById('importTargetPathDisplay');
        const loraRoot = document.getElementById('importLoraRoot').value;

        let fullPath = loraRoot || translate('recipes.controls.import.selectLoraRoot', {}, 'Select a LoRA root directory'); if (loraRoot) {
            if (this.useDefaultPath) {
                // Show actual template path
                try {
                    const templates = state.global.settings.download_path_templates;
                    const template = templates.lora;
                    fullPath += `/${template}`;
                } catch (error) {
                    console.error('Failed to fetch template:', error);
                    fullPath += '/[Auto-organized by path template]';
                }
            } else {
                // Show manual path selection
                const selectedPath = this.folderTreeManager ? this.folderTreeManager.getSelectedPath() : '';
                if (selectedPath) {
                    fullPath += '/' + selectedPath;
                }
            }
        }

        if (pathDisplay) {
            pathDisplay.innerHTML = `<span class="path-text">${fullPath}</span>`;
        }
    }

    /**
     * NOTE: This function is no longer needed with the simplified duplicates flow.
     * We're keeping it as a no-op stub to avoid breaking existing code that might call it.
     */
    markDuplicateForDeletion(recipeId, buttonElement) {
        // This functionality has been removed
        console.log('markDuplicateForDeletion is deprecated');
    }

    /**
     * NOTE: This function is no longer needed with the simplified duplicates flow.
     * We're keeping it as a no-op stub to avoid breaking existing code that might call it.
     */
    importRecipeAnyway() {
        // This functionality has been simplified
        // Just proceed with normal flow
        this.proceedFromDetails();
    }

    downloadMissingLoras(recipeData, recipeId) {
        // Store the recipe data and ID
        this.recipeData = recipeData;
        this.recipeId = recipeId;

        // Show the modal and go to location step
        this.showImportModal(recipeData, recipeId);
        this.proceedToLocation();

        // Update the modal title
        const modalTitle = document.querySelector('#importModal h2');
        if (modalTitle) modalTitle.textContent = translate('recipes.controls.import.downloadMissingLoras', {}, 'Download Missing LoRAs');

        // Update button texts and show download count
        const locationStep = document.getElementById('locationStep');
        if (!locationStep) return;
        
        const primaryBtn = locationStep.querySelector('.primary-btn');
        const backBtn = locationStep.querySelector('.secondary-btn');
        
        // primaryBtn should be the "Import & Download" button
        if (primaryBtn) {
            const buttonText = translate('recipes.controls.import.importAndDownload', {}, 'Import & Download');
            primaryBtn.innerHTML = `${buttonText} <span id="downloadLoraCount">(${recipeData.loras?.length || 0})</span>`;
        }
        
        // Hide the "Back" button in download-only mode
        if (backBtn) {
            backBtn.style.display = 'none';
        }
    }

    saveRecipeWithoutDownload() {
        // Call save recipe with skip download flag
        return this.downloadManager.saveRecipe(true);
    }

    async saveRecipeOnlyFromDetails() {
        // Validate recipe name first
        if (!this.recipeName) {
            showToast('toast.recipes.enterRecipeName', {}, 'error');
            return;
        }

        // Mark deleted LoRAs as excluded
        if (this.recipeData && this.recipeData.loras) {
            this.recipeData.loras.forEach(lora => {
                if (lora.isDeleted) {
                    lora.exclude = true;
                }
            });
        }

        // Update missing LoRAs list
        this.missingLoras = this.recipeData.loras.filter(lora =>
            !lora.existsLocally && !lora.isDeleted);
        
        // For import only, we don't need downloadableLoRAs
        this.downloadableLoRAs = [];

        // Save recipe without downloading
        await this.downloadManager.saveRecipe(true);
    }
}
