import jQuery from 'jquery';
import jstree from 'jstree';
import 'jstree/dist/themes/default/style.min.css';

( function ( $, jstree, wdceoJSTree ) {
	'use strict';

	// Constants
	const TREE_CONTAINER = '#treejs-container';

	/**
	 * Initialize when DOM is ready
	 */
	$( function () {
		if ( typeof wdceoJSTree === 'undefined' ) {
			return;
		}

		const tree = $( TREE_CONTAINER )
			.jstree( {
				core: {
					data: wdceoJSTree.treeData,
					themes: {
						responsive: true,
						variant: 'large',
					},
					check_callback: true,
					force_text: true,
				},
				plugins: [ 'contextmenu', 'types' ],
				types: {
					folder: {
						icon: 'jstree-folder',
					},
					file: {
						icon: 'jstree-file',
						valid_children: [],
					},
				},
				contextmenu: {
					items: function ( node ) {
						const isFolder = node.type === 'folder';
						const tree = $( TREE_CONTAINER ).jstree( true );
						const isRoot = node.id === 'root';
						const hasChildren =
							tree.get_node( node ).children.length > 0;

						if ( ! isFolder ) return {};

						if ( isRoot ) {
							return {
								select: {
									label: wdceoJSTree.strings.select_folder,
									action: function () {
										selectFolder( node.id, node.text );
									},
								},
								create: {
									label: wdceoJSTree.strings.create_folder,
									action: function () {
										createFolder(
											node.id,
											wdceoJSTree.strings.create_folder
										);
									},
								},
							};
						}

						return {
							select: {
								label: wdceoJSTree.strings.select_folder,
								action: function () {
									selectFolder( node.id, node.text );
								},
							},
							create: {
								label: wdceoJSTree.strings.create_folder,
								action: function () {
									createFolder(
										node.id,
										wdceoJSTree.strings.create_folder
									);
								},
							},
							rename: {
								label: wdceoJSTree.strings.rename_folder,
								action: function () {
									tree.edit( node );
								},
							},
							delete: {
								label: wdceoJSTree.strings.delete_folder,
								action: function () {
									if (
										confirm(
											wdceoJSTree.strings.delete_confirm
										)
									) {
										deleteFolder( node.id );
									}
								},
								_disabled: hasChildren,
							},
						};
					},
				},
			} )
			.on( 'ready.jstree', function () {
				tree.jstree( 'open_all' );
				if ( wdceoJSTree.selectedFolderId ) {
					const selectedNode = tree
						.jstree( true )
						.get_node( wdceoJSTree.selectedFolderId );
					if ( selectedNode ) {
						markNodeAsSelected( selectedNode );
					}
				}
				const treeInstance = $( TREE_CONTAINER ).jstree( true );
				treeInstance.open_all();

				// Mark the initially selected folder on load
				if ( wdceoJSTree.selectedFolderId ) {
					const selectedNode = treeInstance.get_node(
						wdceoJSTree.selectedFolderId
					);
					if ( selectedNode ) {
						markNodeAsSelected( selectedNode );
					}
				}
			} )
			.on( 'click', '.jstree-anchor', function ( e ) {
				e.preventDefault();
			} )
			.on( 'rename_node.jstree', function ( e, data ) {
				if ( data.node.type === 'folder' && data.old !== data.text ) {
					renameFolder( data.node.id, data.text, data.old );
				}
			} );

		/**
		 * Mark a node as selected in the tree
		 * @param {Object} node - The node to mark as selected
		 */
		function markNodeAsSelected( node ) {
			$( TREE_CONTAINER )
				.find( '.jstree-anchor' )
				.removeClass( 'wdevs-coe-selected-folder' );

			const tree = $( TREE_CONTAINER ).jstree( true );
			const nodeElement = tree.get_node( node, true );
			if ( nodeElement ) {
				$( nodeElement )
					.find( ' > .jstree-anchor' )
					.addClass( 'wdevs-coe-selected-folder' );
			}
		}

		/**
		 * Create a new folder via AJAX
		 *
		 * @param {string} parentId - The parent folder ID
		 * @param {string} folderName - The folder name
		 */
		function createFolder( parentId, folderName ) {
			const tree = $( TREE_CONTAINER ).jstree( true );

			const tempNodeId = 'temp_' + Date.now();
			const tempNode = tree.create_node( parentId, {
				id: tempNodeId,
				text: folderName,
				type: 'folder',
			} );

			tree.edit( tempNode, folderName );

			$( TREE_CONTAINER ).one(
				'rename_node.jstree',
				function ( e, data ) {
					if ( data.node.id === tempNodeId ) {
						// User finished editing, now make AJAX call
						performCreateFolder( parentId, data.text, tempNodeId );
					}
				}
			);
		}

		/**
		 * Perform the actual AJAX call to create folder
		 */
		function performCreateFolder( parentId, folderName, tempNodeId ) {
			const tree = $( TREE_CONTAINER ).jstree( true );

			setNodeLoading( tempNodeId, true );

			folderOperation(
				'create',
				{
					parent_id: parentId,
					folder_name: folderName,
				},
				function ( response ) {
					if ( response.success && response.data.folder_id ) {
						setNodeLoading( tempNodeId, false );

						const node = tree.get_node( tempNodeId );
						node.id = response.data.folder_id;
						tree.redraw_node( node );
						showNotification(
							'success',
							response.data.message || 'Folder created'
						);
					} else {
						setNodeLoading( tempNodeId, false );
						tree.delete_node( tempNodeId );
						showNotification(
							'error',
							response.data.message || 'Failed to create folder'
						);
					}
				},
				function ( error ) {
					setNodeLoading( tempNodeId, false );
					tree.delete_node( tempNodeId );
					showNotification( 'error', 'AJAX error: ' + error );
				}
			);
		}

		/**
		 * Rename a folder via AJAX
		 *
		 * @param {string} folderId - The folder ID to rename
		 * @param {string} newName - The new folder name
		 * @param {string} oldName - The old folder name (for rollback)
		 */
		function renameFolder( folderId, newName, oldName ) {
			const tree = $( TREE_CONTAINER ).jstree( true );

			if ( folderId.startsWith( 'temp_' ) ) {
				return;
			}

			setNodeLoading( folderId, true );

			folderOperation(
				'rename',
				{
					folder_id: folderId,
					new_name: newName,
				},
				function ( response ) {
					if ( response.success ) {
						showNotification(
							'success',
							response.data.message || 'Folder renamed'
						);
					} else {
						// Rollback to old name
						tree.rename_node( folderId, oldName );
						showNotification(
							'error',
							response.data.message || 'Failed to rename folder'
						);
					}
					setNodeLoading( folderId, false );
				},
				function ( error ) {
					// Rollback to old name
					tree.rename_node( folderId, oldName );
					showNotification( 'error', 'AJAX error: ' + error );
					setNodeLoading( folderId, false );
				}
			);
		}

		/**
		 * Delete a folder via AJAX
		 *
		 * @param {string} folderId - The folder ID to delete
		 */
		function deleteFolder( folderId ) {
			const tree = $( TREE_CONTAINER ).jstree( true );

			setNodeLoading( folderId, true );

			folderOperation(
				'delete',
				{
					folder_id: folderId,
				},
				function ( response ) {
					if ( response.success ) {
						tree.delete_node( folderId );
						showNotification(
							'success',
							response.data.message || 'Folder deleted'
						);
					} else {
						showNotification(
							'error',
							response.data.message || 'Failed to delete folder'
						);
					}
					setNodeLoading( folderId, false );
				},
				function ( error ) {
					showNotification( 'error', 'AJAX error: ' + error );
					setNodeLoading( folderId, false );
				}
			);
		}

		/**
		 * Generic folder operation AJAX function
		 *
		 * @param {string} operation - The operation (create/rename/delete)
		 * @param {Object} params - Operation-specific parameters
		 * @param {Function} successCallback - Success callback function
		 * @param {Function} errorCallback - Error callback function
		 */
		function folderOperation(
			operation,
			params,
			successCallback,
			errorCallback
		) {
			const data = {
				action: wdceoJSTree.ajaxAction,
				operation: operation,
				nonce: wdceoJSTree.nonce,
				channel_slug: wdceoJSTree.channelSlug,
				...params,
			};

			$.ajax( {
				url: wdceoJSTree.ajaxUrl,
				type: 'POST',
				data: data,
				success: successCallback,
				error: function ( xhr, status, error ) {
					errorCallback( error );
				},
			} );
		}

		/**
		 * Select a folder and provide visual feedback
		 *
		 * @param {string} folderId - The folder ID to select
		 * @param {string} folderName - The folder name for display
		 */
		function selectFolder( folderId, folderName ) {
			const tree = $( TREE_CONTAINER ).jstree( true );

			const selectedNode = tree.get_node( folderId );
			if ( selectedNode ) {
				markNodeAsSelected( selectedNode );
			}

			folderOperation(
				'select',
				{
					folder_id: folderId,
					folder_name: folderName,
				},
				function ( response ) {
					if ( response.success ) {
						showNotification(
							'success',
							wdceoJSTree.strings.folder_selected.replace(
								'{folder_name}',
								folderName
							)
						);

						const nameField = $(
							'input[name="google_drive_folder_name"]'
						);

						if ( nameField.length ) {
							nameField.val( folderName );
						}
					} else {
						showNotification(
							'error',
							response.data.message ||
								'Failed to save folder selection'
						);
					}
				},
				function ( error ) {
					showNotification(
						'error',
						'Failed to save folder selection: ' + error
					);
				}
			);
		}

		/**
		 * Set loading state for a node
		 *
		 * @param {string} nodeId - The node ID
		 * @param {boolean} loading - Whether to show or hide loading
		 */
		function setNodeLoading( nodeId, loading ) {
			const tree = $( TREE_CONTAINER ).jstree( true );
			const node = tree.get_node( nodeId );

			if ( node && node.a_attr ) {
				if ( loading ) {
					// Disable the node during loading
					node.a_attr.style = 'opacity: 0.5; pointer-events: none;';
					tree.set_text( node, node.text + ' (loading...)' );
				} else {
					// Re-enable the node
					node.a_attr.style = '';
					// Remove loading text if it exists
					const text = node.text.replace( ' (loading...)', '' );
					tree.set_text( node, text );
				}
				tree.redraw_node( node );
			}
		}

		/**
		 * Show notification to user
		 *
		 * @param {string} type - 'success' or 'error'
		 * @param {string} message - The message to show
		 */
		function showNotification( type, message ) {
			const messagesContainer =
				document.getElementById( 'treejs-messages' );

			if ( ! messagesContainer ) {
				return;
			}

			let messageClass;

			if ( type === 'success' ) {
				messageClass = 'woocommerce-message';
			} else if ( type === 'error' ) {
				messageClass = 'woocommerce-error';
			} else {
				messageClass = 'woocommerce-info';
			}

			let messageElement = document.createElement( 'div' );
			messagesContainer.innerHTML = '';
			messagesContainer.appendChild( messageElement );

			messageElement.className = messageClass;
			messageElement.textContent = message;
			messageElement.setAttribute( 'role', 'alert' );

			messagesContainer.style.display = 'block';
		}
	} );
} )( jQuery, jstree, window.wdceoJSTree );
