/**
 * Behavior Tree Editor Module
 * 行为树编辑器模块
 */

import type { ServiceContainer } from '@esengine/ecs-framework';
import { TransformComponent } from '@esengine/ecs-components';
import {
    type IEditorModuleLoader,
    type IPluginLoader,
    type PanelDescriptor,
    type EntityCreationTemplate,
    type FileCreationTemplate,
    type FileActionHandler,
    PanelPosition,
    CompilerRegistry,
    ICompilerRegistry,
    InspectorRegistry,
    IInspectorRegistry,
    MessageHub,
    IMessageHub,
    FileActionRegistry,
    IDialogService,
    IFileSystemService,
    type IDialog,
    type IFileSystem,
    createLogger,
    PluginAPI,
} from '@esengine/editor-runtime';

// Runtime imports (relative paths since we're in the same package)
import { BehaviorTreeRuntimeComponent } from '../execution/BehaviorTreeRuntimeComponent';

// Editor components and services
import { BehaviorTreeService } from './services/BehaviorTreeService';
import { FileSystemService } from './services/FileSystemService';
import { BehaviorTreeCompiler } from './compiler/BehaviorTreeCompiler';
import { BehaviorTreeNodeInspectorProvider } from './providers/BehaviorTreeNodeInspectorProvider';
import { BehaviorTreeEditorPanel } from './components/panels/BehaviorTreeEditorPanel';
import { useBehaviorTreeDataStore } from './stores';
import { createRootNode } from './domain/constants/RootNode';
import { PluginContext } from './PluginContext';

// Import descriptor from local file, runtime module from main module
import { descriptor } from './BehaviorTreePlugin';
import { BehaviorTreeRuntimeModule } from '../BehaviorTreeRuntimeModule';

// 导入编辑器 CSS 样式（会被 vite 自动处理并注入到 DOM）
// Import editor CSS styles (automatically handled and injected by vite)
import './styles/BehaviorTreeNode.css';
import './components/panels/BehaviorTreeEditorPanel.css';

const logger = createLogger('BehaviorTreeEditorModule');

/**
 * Behavior Tree Editor Module
 * 行为树编辑器模块加载器
 */
export class BehaviorTreeEditorModule implements IEditorModuleLoader {
    private services?: ServiceContainer;
    private unsubscribers: Array<() => void> = [];

    async install(services: ServiceContainer): Promise<void> {
        this.services = services;

        // 设置插件上下文
        PluginContext.setServices(services);

        // 注册服务
        this.registerServices(services);

        // 注册编译器
        this.registerCompilers(services);

        // 注册节点检视器
        this.registerInspectorProviders(services);

        // 注册资产创建消息映射
        this.registerAssetCreationMappings(services);

        // 订阅创建资产消息
        this.subscribeToMessages(services);

        logger.info('BehaviorTree editor module installed');
    }

    private registerAssetCreationMappings(services: ServiceContainer): void {
        try {
            const fileActionRegistry = services.resolve(FileActionRegistry);
            if (fileActionRegistry) {
                fileActionRegistry.registerAssetCreationMapping({
                    extension: '.btree',
                    createMessage: 'behavior-tree:create-asset'
                });
            }
        } catch (error) {
            logger.warn('FileActionRegistry not available:', error);
        }
    }

    private subscribeToMessages(services: ServiceContainer): void {
        try {
            const messageHub = services.resolve<MessageHub>(IMessageHub);
            if (messageHub) {
                const unsubscribe = messageHub.subscribe('behavior-tree:create-asset', async (payload: {
                    entityId?: string;
                    onChange?: (value: string | null) => void;
                }) => {
                    await this.handleCreateBehaviorTreeAsset(services, payload);
                });
                this.unsubscribers.push(unsubscribe);
            }
        } catch (error) {
            logger.warn('MessageHub not available:', error);
        }
    }

    private async handleCreateBehaviorTreeAsset(
        services: ServiceContainer,
        payload: { entityId?: string; onChange?: (value: string | null) => void }
    ): Promise<void> {
        try {
            const dialog = services.resolve<IDialog>(IDialogService);
            const fileSystem = services.resolve<IFileSystem>(IFileSystemService);
            const messageHub = services.resolve<MessageHub>(IMessageHub);

            if (!dialog || !fileSystem) {
                logger.error('Dialog or FileSystem service not available');
                return;
            }

            const filePath = await dialog.saveDialog({
                title: 'Create Behavior Tree Asset',
                filters: [{ name: 'Behavior Tree', extensions: ['btree'] }],
                defaultPath: 'new-behavior-tree.btree'
            });

            if (!filePath) {
                return;
            }

            // 获取默认行为树内容
            const templates = this.getFileCreationTemplates();
            const btreeTemplate = templates.find(t => t.extension === 'btree');
            const content = btreeTemplate
                ? await btreeTemplate.getContent(filePath.split(/[\\/]/).pop() || 'new-behavior-tree.btree')
                : '{}';

            await fileSystem.writeFile(filePath, content);

            if (payload.onChange) {
                payload.onChange(filePath);
            }

            // 打开行为树编辑器
            if (messageHub) {
                messageHub.publish('dynamic-panel:open', {
                    panelId: 'behavior-tree-editor',
                    title: `Behavior Tree - ${filePath.split(/[\\/]/).pop()}`
                });
            }

            logger.info('Created behavior tree asset:', filePath);
        } catch (error) {
            logger.error('Failed to create behavior tree asset:', error);
        }
    }

    async uninstall(): Promise<void> {
        // 清理订阅
        this.unsubscribers.forEach(unsub => unsub());
        this.unsubscribers = [];

        if (this.services) {
            this.services.unregister(FileSystemService);
            this.services.unregister(BehaviorTreeService);
        }

        useBehaviorTreeDataStore.getState().reset();
        PluginContext.clear();
        this.services = undefined;

        logger.info('BehaviorTree editor module uninstalled');
    }

    private registerServices(services: ServiceContainer): void {
        // FileSystemService (BehaviorTreeService depends on it)
        if (services.isRegistered(FileSystemService)) {
            services.unregister(FileSystemService);
        }
        services.registerSingleton(FileSystemService);

        // BehaviorTreeService
        if (services.isRegistered(BehaviorTreeService)) {
            services.unregister(BehaviorTreeService);
        }
        services.registerSingleton(BehaviorTreeService);
    }

    private registerCompilers(services: ServiceContainer): void {
        try {
            const compilerRegistry = services.resolve<CompilerRegistry>(ICompilerRegistry);
            const compiler = new BehaviorTreeCompiler();
            compilerRegistry.register(compiler);
            logger.info('BehaviorTreeCompiler registered');
        } catch (error) {
            logger.error('Failed to register compiler:', error);
        }
    }

    private registerInspectorProviders(services: ServiceContainer): void {
        try {
            const inspectorRegistry = services.resolve<InspectorRegistry>(IInspectorRegistry);
            if (!inspectorRegistry) {
                logger.error('InspectorRegistry not found in services');
                return;
            }

            // 使用 Symbol 解析 MessageHub（跨包访问需要使用 Symbol）
            const messageHub = services.resolve<MessageHub>(IMessageHub);
            if (!messageHub) {
                logger.error('MessageHub not found in services');
                return;
            }

            const provider = new BehaviorTreeNodeInspectorProvider();
            provider.setMessageHub(messageHub);

            inspectorRegistry.register(provider);
            logger.info('BehaviorTreeNodeInspectorProvider registered');
        } catch (error) {
            logger.error('Failed to register inspector provider:', error);
        }
    }

    getPanels(): PanelDescriptor[] {
        return [
            {
                id: 'behavior-tree-editor',
                title: 'Behavior Tree Editor',
                position: PanelPosition.Center,
                closable: true,
                component: BehaviorTreeEditorPanel,
                order: 100,
                isDynamic: true
            }
        ];
    }

    getFileCreationTemplates(): FileCreationTemplate[] {
        return [{
            id: 'behavior-tree',
            label: 'Behavior Tree',
            extension: 'btree',
            icon: 'GitBranch',
            getContent: (fileName: string) => {
                const rootNode = createRootNode();
                const rootNodeData = {
                    id: rootNode.id,
                    type: rootNode.template.type,
                    displayName: rootNode.template.displayName,
                    data: rootNode.data,
                    position: {
                        x: rootNode.position.x,
                        y: rootNode.position.y
                    },
                    children: []
                };

                const emptyTree = {
                    name: fileName.replace('.btree', ''),
                    nodes: [rootNodeData],
                    connections: [],
                    variables: {}
                };

                return JSON.stringify(emptyTree, null, 2);
            }
        }];
    }

    getFileActionHandlers(): FileActionHandler[] {
        return [{
            extensions: ['btree'],
            onDoubleClick: async (filePath: string) => {
                if (this.services) {
                    const service = this.services.resolve(BehaviorTreeService);
                    if (service) {
                        await service.loadFromFile(filePath);
                    }
                }
            }
        }];
    }

    getEntityCreationTemplates(): EntityCreationTemplate[] {
        return [{
            id: 'behavior-tree-entity',
            label: 'AI Entity',
            icon: 'GitBranch',
            category: 'other',
            order: 100,
            create: (_parentEntityId?: number): number => {
                const scene = PluginAPI.scene;
                const entityStore = PluginAPI.entityStore;
                const messageHub = PluginAPI.messageHub;

                // 统计现有 AI Entity 数量
                const aiEntityCount = entityStore.getAllEntities()
                    .filter((e: any) => e.name.startsWith('AI Entity')).length;
                const entityName = `AI Entity ${aiEntityCount + 1}`;

                // 创建实体
                const entity = scene.createEntity(entityName);

                // 添加 Transform 组件
                entity.addComponent(new TransformComponent());

                // 添加行为树运行时组件
                const btComponent = new BehaviorTreeRuntimeComponent();
                btComponent.autoStart = true;
                entity.addComponent(btComponent);

                // 注册到实体存储
                entityStore.addEntity(entity);

                // 发送通知
                messageHub.publish('entity:added', { entity });
                messageHub.publish('scene:modified', {});

                // 选中新创建的实体
                entityStore.selectEntity(entity);

                logger.info(`Created AI Entity: ${entity.id}`);
                return entity.id;
            }
        }];
    }
}

// Create the complete plugin with editor module
export const BehaviorTreePlugin: IPluginLoader = {
    descriptor,
    runtimeModule: new BehaviorTreeRuntimeModule(),
    editorModule: new BehaviorTreeEditorModule(),
};

export { BehaviorTreeRuntimeModule };

// Re-exports for editor functionality
export { PluginContext } from './PluginContext';
export { BehaviorTreeEditorPanel } from './components/panels/BehaviorTreeEditorPanel';
export * from './services/BehaviorTreeService';
export * from './providers/BehaviorTreeNodeInspectorProvider';

export * from './domain';
export * from './application/commands/tree';
export * from './application/use-cases';
export * from './application/services/BlackboardManager';
export * from './application/services/ExecutionController';
export * from './application/services/GlobalBlackboardService';
export * from './application/interfaces/IExecutionHooks';
export * from './application/state/BehaviorTreeDataStore';
export * from './hooks';
export * from './stores';
export type { EditorConfig } from './types';
export * from './infrastructure/factories/NodeFactory';
export * from './infrastructure/serialization/BehaviorTreeSerializer';
export * from './infrastructure/validation/BehaviorTreeValidator';
export * from './infrastructure/events/EditorEventBus';
export * from './infrastructure/services/NodeRegistryService';
export * from './utils/BehaviorTreeExecutor';
export * from './utils/DOMCache';
export * from './utils/portUtils';
export * from './utils/RuntimeLoader';
export * from './compiler/BehaviorTreeCompiler';
export {
    ICON_MAP,
    ROOT_NODE_TEMPLATE,
    DEFAULT_EDITOR_CONFIG
} from './config/editorConstants';
export * from './interfaces/IEditorExtensions';
