/**
 * VTK.js Point Cloud Preview Widget
 * For SAM3DObjects and other point cloud visualization nodes
 */

import { app } from "../../../scripts/app.js";
import { EXTENSION_FOLDER, getViewerUrl } from "./utils/extensionFolder.js";
import { createContainer, createIframe, createInfoPanel, createWidgetOptions } from "./utils/uiComponents.js";
import { createViewerManager, createErrorHandler, buildViewUrl } from "./utils/postMessage.js";

app.registerExtension({
    name: "comfy3d.pointcloud.vtk",

    async beforeRegisterNodeDef(nodeType, nodeData, app) {
        if (nodeData.name === "SAM3D_PreviewPointCloud") {

            const onNodeCreated = nodeType.prototype.onNodeCreated;
            nodeType.prototype.onNodeCreated = function() {
                const r = onNodeCreated ? onNodeCreated.apply(this, arguments) : undefined;

                // Create container for viewer + info panel
                const container = createContainer();

                // Create iframe for VTK.js viewer
                const iframe = createIframe(getViewerUrl("viewer_vtk"));

                // Create info panel
                const infoPanel = createInfoPanel("Point cloud will appear after execution");

                // Add iframe and info panel to container
                container.appendChild(iframe);
                container.appendChild(infoPanel);

                // Add widget
                const widget = this.addDOMWidget("preview_vtk", "POINTCLOUD_PREVIEW_VTK", container, createWidgetOptions());
                widget.computeSize = () => [512, 580];

                // Store references
                this._vtkIframe = iframe;
                this._infoPanel = infoPanel;

                // Create viewer manager
                const viewerManager = createViewerManager(iframe, "[PointCloud VTK]");

                // Listen for error messages
                window.addEventListener('message', createErrorHandler(infoPanel, "[PointCloud VTK]"));

                // Set initial node size
                this.setSize([512, 580]);

                return r;
            };

            // Handle execution
            const onExecuted = nodeType.prototype.onExecuted;
            nodeType.prototype.onExecuted = function(message) {
                onExecuted?.apply(this, arguments);

                // Get file path from ui.file_path
                let filePath = null;
                if (message?.ui?.file_path) {
                    filePath = Array.isArray(message.ui.file_path) ? message.ui.file_path[0] : message.ui.file_path;
                } else if (message?.file_path) {
                    filePath = Array.isArray(message.file_path) ? message.file_path[0] : message.file_path;
                }

                if (filePath && filePath.trim() !== '') {
                    // Normalize path
                    filePath = filePath.replace(/\\/g, '/').trim();

                    // Build URL for ComfyUI view endpoint
                    const outputMatch = filePath.match(/(?:^|\/)(output|input)\/(.+)$/);
                    let url;
                    if (outputMatch) {
                        const [, type, relativePath] = outputMatch;
                        const pathParts = relativePath.split('/');
                        const filename = pathParts.pop();
                        const subfolder = pathParts.join('/');
                        url = `/view?filename=${encodeURIComponent(filename)}&type=${type}&subfolder=${encodeURIComponent(subfolder)}`;
                    } else {
                        const filename = filePath.split('/').pop();
                        url = `/view?filename=${encodeURIComponent(filename)}&type=output&subfolder=`;
                    }

                    // Update info panel
                    if (this._infoPanel) {
                        const filename = filePath.split('/').pop();
                        this._infoPanel.innerHTML = `<strong>File:</strong> ${filename}`;
                    }

                    // Send message to iframe
                    if (this._vtkIframe?.contentWindow) {
                        const sendMessage = () => {
                            this._vtkIframe.contentWindow.postMessage({
                                type: 'loadPointCloud',
                                url: url
                            }, '*');
                        };

                        if (this._vtkIframe.contentDocument?.readyState === 'complete') {
                            sendMessage();
                        } else {
                            this._vtkIframe.addEventListener('load', () => setTimeout(sendMessage, 100), { once: true });
                        }
                    }
                }
            };
        }
    }
});
