// ComfyUI extension to track model usage statistics
import { app } from "../../scripts/app.js";
import { api } from "../../scripts/api.js";
import { showToast } from "./utils.js";
import { getAutoPathCorrectionPreference, getUsageStatisticsPreference } from "./settings.js";

// Define target nodes and their widget configurations
const PATH_CORRECTION_TARGETS = [
    { comfyClass: "CheckpointLoaderSimple", widgetName: "ckpt_name", modelType: "checkpoints" },
    { comfyClass: "Checkpoint Loader with Name (Image Saver)", widgetName: "ckpt_name", modelType: "checkpoints" },
    { comfyClass: "UNETLoader", widgetName: "unet_name", modelType: "checkpoints" },
    { comfyClass: "easy comfyLoader", widgetName: "ckpt_name", modelType: "checkpoints" },
    { comfyClass: "CheckpointLoader|pysssss", widgetName: "ckpt_name", modelType: "checkpoints" },
    { comfyClass: "Efficient Loader", widgetName: "ckpt_name", modelType: "checkpoints" },
    { comfyClass: "UnetLoaderGGUF", widgetName: "unet_name", modelType: "checkpoints" },
    { comfyClass: "UnetLoaderGGUFAdvanced", widgetName: "unet_name", modelType: "checkpoints" },
    { comfyClass: "LoraLoader", widgetName: "lora_name", modelType: "loras" },
    { comfyClass: "easy loraStack", widgetNamePattern: "lora_\\d+_name", modelType: "loras" }
];

// Register the extension
app.registerExtension({
    name: "LoraManager.UsageStats",
    
    setup() {
        // Listen for successful executions
        api.addEventListener("execution_success", ({ detail }) => {
            // Skip if usage statistics is disabled
            if (!getUsageStatisticsPreference()) {
                return;
            }

            if (detail && detail.prompt_id) {
                this.updateUsageStats(detail.prompt_id);
            }
        });

    },

    async updateUsageStats(promptId) {
        try {
            // Call backend endpoint with the prompt_id
            const response = await fetch(`/api/lm/update-usage-stats`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ prompt_id: promptId }),
            });
            
            if (!response.ok) {
                console.warn("Failed to update usage statistics:", response.statusText);
            }
        } catch (error) {
            console.error("Error updating usage statistics:", error);
        }
    },

    async loadedGraphNode(node) {
        if (!getAutoPathCorrectionPreference()) {
            return;
        }

        // Check if this node type needs path correction
        const target = PATH_CORRECTION_TARGETS.find(t => t.comfyClass === node.comfyClass);
        if (!target) {
            return;
        }
        
        await this.correctNodePaths(node, target);
    },
    
    async correctNodePaths(node, target) {
        try {
            if (target.widgetNamePattern) {
                // Handle pattern-based widget names (like lora_1_name, lora_2_name, etc.)
                const pattern = new RegExp(target.widgetNamePattern);
                const widgetIndexes = [];
                
                if (node.widgets) {
                    node.widgets.forEach((widget, index) => {
                        if (pattern.test(widget.name)) {
                            widgetIndexes.push(index);
                        }
                    });
                }
                
                // Process each matching widget
                for (const widgetIndex of widgetIndexes) {
                    await this.correctWidgetPath(node, widgetIndex, target.modelType);
                }
            } else {
                // Handle single widget name
                if (node.widgets) {
                    const widgetIndex = node.widgets.findIndex(w => w.name === target.widgetName);
                    if (widgetIndex !== -1) {
                        await this.correctWidgetPath(node, widgetIndex, target.modelType);
                    }
                }
            }
        } catch (error) {
            console.error("Error correcting node paths:", error);
        }
    },
    
    async correctWidgetPath(node, widgetIndex, modelType) {
        if (!node.widgets_values || !node.widgets_values[widgetIndex]) {
            return;
        }
        
        const currentPath = node.widgets_values[widgetIndex];
        if (!currentPath || typeof currentPath !== 'string') {
            return;
        }
        
        // Extract filename from path (after last separator)
        const fileName = currentPath.split(/[/\\]/).pop();
        if (!fileName) {
            return;
        }
        
        try {
            // Search for current relative path
            const response = await api.fetchApi(`/lm/${modelType}/relative-paths?search=${encodeURIComponent(fileName)}&limit=2`);
            const data = await response.json();
            
            if (!data.success || !data.relative_paths || data.relative_paths.length === 0) {
                return;
            }
            
            const foundPaths = data.relative_paths;
            const firstPath = foundPaths[0];
            
            // Check if we need to update the path
            if (firstPath !== currentPath) {
                // Update the widget value
                // node.widgets_values[widgetIndex] = firstPath;
                node.widgets[widgetIndex].value = firstPath;
                
                if (foundPaths.length === 1) {
                    // Single match found - success
                    showToast({
                        severity: 'info',
                        summary: 'LoRA Manager Path Correction',
                        detail: `Updated path for ${fileName}: ${firstPath}`,
                        life: 5000
                    });
                } else {
                    // Multiple matches found - warning
                    showToast({
                        severity: 'warn',
                        summary: 'LoRA Manager Path Correction',
                        detail: `Multiple paths found for ${fileName}, using: ${firstPath}`,
                        life: 5000
                    });
                }
                
                // Mark node as modified
                if (node.setDirtyCanvas) {
                    node.setDirtyCanvas(true);
                }
            }
        } catch (error) {
            console.error(`Error correcting path for ${fileName}:`, error);
        }
    }
});
