import type { EditorState } from '../richTextTypes'
import { createCommandExecutor, createCommandRegistry } from '../utils/commands'

export function useCommands(state: EditorState, debug?: { logCommand: (command: string, value?: string) => void }) {
	const commands = createCommandRegistry(state)
	const executor = createCommandExecutor(state, commands)

	return {
		execute: (command: string, value?: string) => {
			console.log(`[useCommands] Executing command: ${command}`, value ? `with value: ${value}` : '')

			if (!state.doc) {
				console.log('[useCommands] No document available, skipping command')
				return
			}

			// Log command if debug is enabled
			debug?.logCommand(command, value)

			// Handle view state commands directly
			if (['splitView', 'codeView', 'fullScreen'].includes(command)) {
				console.log(`[useCommands] Handling view state command: ${command}`)
				switch (command) {
					case 'splitView':
						state.isSplitView = !state.isSplitView
						return
					case 'codeView':
						state.isCodeView = !state.isCodeView
						return
					case 'fullScreen':
						state.isFullscreen = !state.isFullscreen
						return
				}
			}

			// Focus the editor before executing command
			try {
				state.doc.body.focus()
				console.log('[useCommands] Editor focused')
			} catch (e) {
				console.error('[useCommands] Error focusing editor:', e)
			}

			// Execute the command
			try {
				console.log('[useCommands] Executing command via executor')
				executor.execute(command, value)
				console.log('[useCommands] Command execution completed')
			} catch (e) {
				console.error('[useCommands] Error during command execution:', e)
			}

			// Update content state only if it has changed
			const newContent = state.doc.body.innerHTML
			if (newContent !== state.content) {
				console.log('[useCommands] Content changed, updating state')
				state.content = newContent
			}

			// Update selection state if needed
			const selection = state.doc.getSelection()
			if (selection?.rangeCount) {
				const hasSelectionChanged = !state.selection
					|| state.selection !== selection
					|| state.rangeCount !== selection.rangeCount

				if (hasSelectionChanged) {
					console.log('[useCommands] Selection changed, updating state')
					state.selection = selection
					state.range = selection.getRangeAt(0).cloneRange()
					state.rangeCount = selection.rangeCount
				}
			}
		},
		isActive: executor.isActive,
		getValue: executor.getValue
	}
}
