"""
数据库表创建节点

根据数据库设计配置实际创建Schema和表
"""
import logging
from typing import Any, Dict, List

from core.database_connection.resolver import ConnectionResolver
from core.database_manager.ddl_builder import (
    build_create_schema_sql,
    build_create_table_ddl,
    normalize_db_type,
)

from ..base import BaseNode, NodeContext, NodeResult
from ..registry import NodeRegistry
from ..utils.config_utils import resolve_object_config

logger = logging.getLogger(__name__)


@NodeRegistry.register
class FormDatabaseCreateNode(BaseNode):
    """
    数据库表创建节点

    根据数据库设计配置实际创建Schema和表
    """

    node_type = 'form_database_create'
    node_name = '数据库表创建'
    node_category = 'form'
    node_icon = 'database-zap'
    node_description = '根据设计配置实际创建数据库Schema和表'

    inputs = [
        {
            'name': 'database_design',
            'type': 'object',
            'description': '数据库设计配置',
            'required': True,
        },
        {
            'name': 'if_exists',
            'type': 'string',
            'description': '表已存在时的处理方式',
            'required': False,
        },
        {
            'name': 'create_schema_if_not_exists',
            'type': 'boolean',
            'description': '自动创建Schema',
            'required': False,
        },
    ]

    outputs = [
        {
            'name': 'creation_result',
            'type': 'object',
            'description': '创建结果',
        },
        {
            'name': 'all_tables_ready',
            'type': 'boolean',
            'description': '所有表是否就绪',
        },
    ]

    def execute(self, context: NodeContext) -> NodeResult:
        """执行节点（同步方法，通过运行异步方法实现）"""
        import asyncio

        loop = asyncio.get_event_loop()
        if loop.is_running():
            import concurrent.futures
            with concurrent.futures.ThreadPoolExecutor() as executor:
                future = executor.submit(asyncio.run, self.execute_async(context))
                return future.result()
        return loop.run_until_complete(self.execute_async(context))

    async def _resolve_db_type(self, db_name: str, meta_db_type: str, context: NodeContext) -> str:
        configured = normalize_db_type(meta_db_type or 'postgresql')
        try:
            conn_info = await ConnectionResolver.resolve(db_name, context.db_session)
            resolved = normalize_db_type(conn_info.db_type)
            if configured != resolved:
                logger.warning(
                    'FormDatabaseCreateNode - db_type 不一致: meta=%s, 连接 %s 解析为 %s，以连接为准',
                    configured,
                    db_name,
                    resolved,
                )
            return resolved
        except Exception as exc:
            logger.warning(
                'FormDatabaseCreateNode - 无法解析连接 %s 的 db_type: %s，使用 meta.dbType=%s',
                db_name,
                exc,
                configured,
            )
            return configured

    async def execute_async(self, context: NodeContext) -> NodeResult:
        """异步执行节点"""
        try:
            database_design = resolve_object_config(
                context, self.config.get('database_design', '')
            )
            if_exists = context.resolve_template(self.config.get('if_exists', 'skip'))
            create_schema = self.config.get('create_schema_if_not_exists', True)

            node_schema_raw = self.config.get('db_schema', '')
            node_schema = context.resolve_template(node_schema_raw)
            node_database_raw = self.config.get('db_database', '')
            node_database = context.resolve_template(node_database_raw)
            logger.info(
                'FormDatabaseCreateNode - database: raw=%s resolved=%s schema: raw=%s resolved=%s',
                node_database_raw,
                node_database,
                node_schema_raw,
                node_schema,
            )

            if database_design is None:
                return NodeResult(
                    success=False,
                    error='数据库设计配置不能为空或解析失败',
                )

            design_type = database_design.get('type', '')
            db_config = database_design.get('dbConfig', 'default')

            if design_type in ['main', 'sub']:
                table_info = database_design.get('table', {})
                if not table_info:
                    return NodeResult(
                        success=False,
                        error='数据库设计配置中缺少 table 信息',
                    )
                all_tables = [table_info]
                main_table = table_info
            elif database_design.get('mainTable'):
                main_table = database_design.get('mainTable', {})
                sub_tables = database_design.get('subTables', [])
                all_tables = [main_table] + sub_tables
            else:
                return NodeResult(
                    success=False,
                    error='数据库设计配置格式无效，需要包含 type+table 或 mainTable',
                )

            meta = main_table.get('meta', {})
            db_name = meta.get('dbName', db_config)
            database = node_database if node_database else meta.get('database', '')
            meta_schema = meta.get('schema', '')
            schema = node_schema if node_schema else meta_schema

            db_type = await self._resolve_db_type(
                db_name,
                meta.get('dbType', 'postgresql'),
                context,
            )

            logger.info(
                'FormDatabaseCreateNode - dbName=%s dbType=%s database=%s schema=%s',
                db_name,
                db_type,
                database,
                schema,
            )

            created_tables: List[str] = []
            skipped_tables: List[str] = []
            errors: List[str] = []
            sql_statements: List[str] = []
            comment_statements: List[str] = []

            if create_schema and schema and db_type in ('postgresql', 'sqlserver'):
                schema_sql = build_create_schema_sql(schema, db_type)
                if schema_sql:
                    sql_statements.append(schema_sql)

            for table in all_tables:
                table_name = table.get('tableName', '')
                if not table_name:
                    errors.append('表配置缺少 tableName')
                    continue

                try:
                    ddl_result = build_create_table_ddl(
                        table,
                        db_type=db_type,
                        if_exists=if_exists,
                        effective_schema=schema,
                    )
                    if ddl_result.skipped:
                        skipped_tables.append(table_name)
                        continue
                    if ddl_result.create_sql:
                        sql_statements.append(ddl_result.create_sql)
                        created_tables.append(table_name)
                        comment_statements.extend(ddl_result.comment_sqls)
                except Exception as exc:
                    error_msg = f'生成表 {table_name} 的SQL失败: {str(exc)}'
                    errors.append(error_msg)
                    logger.error(error_msg)

            if sql_statements:
                try:
                    from core.database_manager.service import AsyncDatabaseManagerService

                    full_sql = '\n\n'.join(sql_statements)
                    logger.info('FormDatabaseCreateNode - 执行 DDL，共 %d 段', len(sql_statements))

                    db_service = await AsyncDatabaseManagerService.create(db_name)
                    result = await db_service.execute_ddl(full_sql, database, schema)

                    if not result.get('success', False):
                        error_msg = result.get('message', '执行DDL失败')
                        errors.append(
                            f'[{db_name}/{db_type}] {error_msg}; SQL开头: {full_sql[:200]}...'
                        )
                        logger.error('DDL执行失败: %s', error_msg)
                    elif comment_statements and if_exists != 'skip':
                        try:
                            comment_sql = '\n'.join(comment_statements)
                            comment_result = await db_service.execute_ddl(
                                comment_sql, database, schema,
                            )
                            if not comment_result.get('success', False):
                                logger.warning(
                                    '字段注释执行失败: %s',
                                    comment_result.get('message', '未知错误'),
                                )
                        except Exception as comment_error:
                            logger.warning('执行字段注释时发生异常: %s', comment_error)
                except Exception as exc:
                    error_msg = f'执行DDL时发生异常: {str(exc)}'
                    errors.append(error_msg)
                    logger.exception(error_msg)

            all_tables_ready = len(errors) == 0 and (len(created_tables) > 0 or len(skipped_tables) > 0)

            creation_result = {
                'success': all_tables_ready,
                'created_tables': created_tables,
                'skipped_tables': skipped_tables,
                'errors': errors,
                'sql_statements': sql_statements,
                'total_tables': len(all_tables),
                'db_name': db_name,
                'db_type': db_type,
            }

            first_table_name = created_tables[0] if created_tables else (
                skipped_tables[0] if skipped_tables else ''
            )

            output_vars = {
                'creation_result': creation_result,
                'all_tables_ready': all_tables_ready,
                'created_count': len(created_tables),
                'error_count': len(errors),
                'schema_name': schema,
                'table_name': first_table_name,
                'db_name': db_name,
                'db_type': db_type,
            }

            if errors:
                return NodeResult(
                    success=False,
                    error=f'创建表时发生错误: {"; ".join(errors)}',
                    output=creation_result,
                    output_variables=output_vars,
                )

            return NodeResult(
                success=True,
                output=creation_result,
                output_variables=output_vars,
            )

        except Exception as exc:
            logger.exception('数据库表创建节点执行失败: %s', exc)
            return NodeResult(
                success=False,
                error=f'节点执行失败: {str(exc)}',
            )

    @classmethod
    def get_config_schema(cls) -> Dict[str, Any]:
        """获取节点配置 Schema"""
        return {
            'type': 'object',
            'properties': {
                'db_schema': {
                    'type': 'string',
                    'title': '数据库 Schema（可选）',
                    'description': 'PostgreSQL/SQL Server schema 名称（如 public、app），支持变量如 {{schema_name}}。如果配置则优先使用此值，否则使用设计节点的 schema',
                    'default': '',
                    'x-component': 'SmartInput',
                },
                'db_database': {
                    'type': 'string',
                    'title': '目标数据库（可选）',
                    'description': 'PostgreSQL/MySQL/SQL Server 目标库名，支持变量。如果配置则优先使用此值，否则使用设计节点的 database',
                    'default': '',
                    'x-component': 'SmartInput',
                },
                'database_design': {
                    'type': 'string',
                    'title': '数据库设计配置',
                    'description': '从上一节点获取的数据库设计配置，支持变量引用如 {{database_design}}',
                    'required': True,
                    'x-component': 'Textarea',
                    'x-component-props': {
                        'placeholder': '请使用变量 {{database_design}}',
                        'rows': 4,
                    },
                },
                'if_exists': {
                    'type': 'string',
                    'title': '表已存在时',
                    'description': '表已存在时的处理方式',
                    'default': 'skip',
                    'enum': ['skip', 'error', 'replace'],
                    'x-component': 'Select',
                    'x-component-props': {
                        'placeholder': '请选择处理方式',
                        'options': [
                            {'label': '跳过（推荐）', 'value': 'skip'},
                            {'label': '报错', 'value': 'error'},
                            {'label': '删除重建（危险）', 'value': 'replace'},
                        ],
                    },
                },
                'create_schema_if_not_exists': {
                    'type': 'boolean',
                    'title': '自动创建Schema',
                    'description': 'Schema不存在时自动创建（PostgreSQL/SQL Server）',
                    'default': True,
                    'x-component': 'Switch',
                },
            },
            'required': ['database_design'],
        }
